]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
[media] Rename media/dvb as media/pci
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 14 Jun 2012 19:35:57 +0000 (16:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:30:06 +0000 (23:30 -0300)
The remaining dvb drivers are pci, so rename them to match the
bus.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
248 files changed:
Documentation/DocBook/media/dvb/kdapi.xml
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/dvb/Kconfig [deleted file]
drivers/media/dvb/Makefile [deleted file]
drivers/media/dvb/b2c2/Kconfig [deleted file]
drivers/media/dvb/b2c2/Makefile [deleted file]
drivers/media/dvb/b2c2/flexcop-common.h [deleted file]
drivers/media/dvb/b2c2/flexcop-dma.c [deleted file]
drivers/media/dvb/b2c2/flexcop-eeprom.c [deleted file]
drivers/media/dvb/b2c2/flexcop-fe-tuner.c [deleted file]
drivers/media/dvb/b2c2/flexcop-hw-filter.c [deleted file]
drivers/media/dvb/b2c2/flexcop-i2c.c [deleted file]
drivers/media/dvb/b2c2/flexcop-misc.c [deleted file]
drivers/media/dvb/b2c2/flexcop-pci.c [deleted file]
drivers/media/dvb/b2c2/flexcop-reg.h [deleted file]
drivers/media/dvb/b2c2/flexcop-sram.c [deleted file]
drivers/media/dvb/b2c2/flexcop-usb.c [deleted file]
drivers/media/dvb/b2c2/flexcop-usb.h [deleted file]
drivers/media/dvb/b2c2/flexcop.c [deleted file]
drivers/media/dvb/b2c2/flexcop.h [deleted file]
drivers/media/dvb/b2c2/flexcop_ibi_value_be.h [deleted file]
drivers/media/dvb/b2c2/flexcop_ibi_value_le.h [deleted file]
drivers/media/dvb/bt8xx/Kconfig [deleted file]
drivers/media/dvb/bt8xx/Makefile [deleted file]
drivers/media/dvb/bt8xx/bt878.c [deleted file]
drivers/media/dvb/bt8xx/bt878.h [deleted file]
drivers/media/dvb/bt8xx/dst.c [deleted file]
drivers/media/dvb/bt8xx/dst_ca.c [deleted file]
drivers/media/dvb/bt8xx/dst_ca.h [deleted file]
drivers/media/dvb/bt8xx/dst_common.h [deleted file]
drivers/media/dvb/bt8xx/dst_priv.h [deleted file]
drivers/media/dvb/bt8xx/dvb-bt8xx.c [deleted file]
drivers/media/dvb/bt8xx/dvb-bt8xx.h [deleted file]
drivers/media/dvb/ddbridge/Kconfig [deleted file]
drivers/media/dvb/ddbridge/Makefile [deleted file]
drivers/media/dvb/ddbridge/ddbridge-core.c [deleted file]
drivers/media/dvb/ddbridge/ddbridge-regs.h [deleted file]
drivers/media/dvb/ddbridge/ddbridge.h [deleted file]
drivers/media/dvb/dm1105/Kconfig [deleted file]
drivers/media/dvb/dm1105/Makefile [deleted file]
drivers/media/dvb/dm1105/dm1105.c [deleted file]
drivers/media/dvb/mantis/Kconfig [deleted file]
drivers/media/dvb/mantis/Makefile [deleted file]
drivers/media/dvb/mantis/hopper_cards.c [deleted file]
drivers/media/dvb/mantis/hopper_vp3028.c [deleted file]
drivers/media/dvb/mantis/hopper_vp3028.h [deleted file]
drivers/media/dvb/mantis/mantis_ca.c [deleted file]
drivers/media/dvb/mantis/mantis_ca.h [deleted file]
drivers/media/dvb/mantis/mantis_cards.c [deleted file]
drivers/media/dvb/mantis/mantis_common.h [deleted file]
drivers/media/dvb/mantis/mantis_core.c [deleted file]
drivers/media/dvb/mantis/mantis_core.h [deleted file]
drivers/media/dvb/mantis/mantis_dma.c [deleted file]
drivers/media/dvb/mantis/mantis_dma.h [deleted file]
drivers/media/dvb/mantis/mantis_dvb.c [deleted file]
drivers/media/dvb/mantis/mantis_dvb.h [deleted file]
drivers/media/dvb/mantis/mantis_evm.c [deleted file]
drivers/media/dvb/mantis/mantis_hif.c [deleted file]
drivers/media/dvb/mantis/mantis_hif.h [deleted file]
drivers/media/dvb/mantis/mantis_i2c.c [deleted file]
drivers/media/dvb/mantis/mantis_i2c.h [deleted file]
drivers/media/dvb/mantis/mantis_input.c [deleted file]
drivers/media/dvb/mantis/mantis_ioc.c [deleted file]
drivers/media/dvb/mantis/mantis_ioc.h [deleted file]
drivers/media/dvb/mantis/mantis_link.h [deleted file]
drivers/media/dvb/mantis/mantis_pci.c [deleted file]
drivers/media/dvb/mantis/mantis_pci.h [deleted file]
drivers/media/dvb/mantis/mantis_pcmcia.c [deleted file]
drivers/media/dvb/mantis/mantis_reg.h [deleted file]
drivers/media/dvb/mantis/mantis_uart.c [deleted file]
drivers/media/dvb/mantis/mantis_uart.h [deleted file]
drivers/media/dvb/mantis/mantis_vp1033.c [deleted file]
drivers/media/dvb/mantis/mantis_vp1033.h [deleted file]
drivers/media/dvb/mantis/mantis_vp1034.c [deleted file]
drivers/media/dvb/mantis/mantis_vp1034.h [deleted file]
drivers/media/dvb/mantis/mantis_vp1041.c [deleted file]
drivers/media/dvb/mantis/mantis_vp1041.h [deleted file]
drivers/media/dvb/mantis/mantis_vp2033.c [deleted file]
drivers/media/dvb/mantis/mantis_vp2033.h [deleted file]
drivers/media/dvb/mantis/mantis_vp2040.c [deleted file]
drivers/media/dvb/mantis/mantis_vp2040.h [deleted file]
drivers/media/dvb/mantis/mantis_vp3028.c [deleted file]
drivers/media/dvb/mantis/mantis_vp3028.h [deleted file]
drivers/media/dvb/mantis/mantis_vp3030.c [deleted file]
drivers/media/dvb/mantis/mantis_vp3030.h [deleted file]
drivers/media/dvb/ngene/Kconfig [deleted file]
drivers/media/dvb/ngene/Makefile [deleted file]
drivers/media/dvb/ngene/ngene-cards.c [deleted file]
drivers/media/dvb/ngene/ngene-core.c [deleted file]
drivers/media/dvb/ngene/ngene-dvb.c [deleted file]
drivers/media/dvb/ngene/ngene-i2c.c [deleted file]
drivers/media/dvb/ngene/ngene.h [deleted file]
drivers/media/dvb/pluto2/Kconfig [deleted file]
drivers/media/dvb/pluto2/Makefile [deleted file]
drivers/media/dvb/pluto2/pluto2.c [deleted file]
drivers/media/dvb/pt1/Kconfig [deleted file]
drivers/media/dvb/pt1/Makefile [deleted file]
drivers/media/dvb/pt1/pt1.c [deleted file]
drivers/media/dvb/pt1/va1j5jf8007s.c [deleted file]
drivers/media/dvb/pt1/va1j5jf8007s.h [deleted file]
drivers/media/dvb/pt1/va1j5jf8007t.c [deleted file]
drivers/media/dvb/pt1/va1j5jf8007t.h [deleted file]
drivers/media/dvb/ttpci/Kconfig [deleted file]
drivers/media/dvb/ttpci/Makefile [deleted file]
drivers/media/dvb/ttpci/av7110.c [deleted file]
drivers/media/dvb/ttpci/av7110.h [deleted file]
drivers/media/dvb/ttpci/av7110_av.c [deleted file]
drivers/media/dvb/ttpci/av7110_av.h [deleted file]
drivers/media/dvb/ttpci/av7110_ca.c [deleted file]
drivers/media/dvb/ttpci/av7110_ca.h [deleted file]
drivers/media/dvb/ttpci/av7110_hw.c [deleted file]
drivers/media/dvb/ttpci/av7110_hw.h [deleted file]
drivers/media/dvb/ttpci/av7110_ipack.c [deleted file]
drivers/media/dvb/ttpci/av7110_ipack.h [deleted file]
drivers/media/dvb/ttpci/av7110_ir.c [deleted file]
drivers/media/dvb/ttpci/av7110_v4l.c [deleted file]
drivers/media/dvb/ttpci/budget-av.c [deleted file]
drivers/media/dvb/ttpci/budget-ci.c [deleted file]
drivers/media/dvb/ttpci/budget-core.c [deleted file]
drivers/media/dvb/ttpci/budget-patch.c [deleted file]
drivers/media/dvb/ttpci/budget.c [deleted file]
drivers/media/dvb/ttpci/budget.h [deleted file]
drivers/media/dvb/ttpci/ttpci-eeprom.c [deleted file]
drivers/media/dvb/ttpci/ttpci-eeprom.h [deleted file]
drivers/media/pci/Kconfig [new file with mode: 0644]
drivers/media/pci/Makefile [new file with mode: 0644]
drivers/media/pci/b2c2/Kconfig [new file with mode: 0644]
drivers/media/pci/b2c2/Makefile [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-common.h [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-dma.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-eeprom.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-fe-tuner.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-hw-filter.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-i2c.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-misc.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-pci.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-reg.h [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-sram.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-usb.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop-usb.h [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop.c [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop.h [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop_ibi_value_be.h [new file with mode: 0644]
drivers/media/pci/b2c2/flexcop_ibi_value_le.h [new file with mode: 0644]
drivers/media/pci/bt8xx/Kconfig [new file with mode: 0644]
drivers/media/pci/bt8xx/Makefile [new file with mode: 0644]
drivers/media/pci/bt8xx/bt878.c [new file with mode: 0644]
drivers/media/pci/bt8xx/bt878.h [new file with mode: 0644]
drivers/media/pci/bt8xx/dst.c [new file with mode: 0644]
drivers/media/pci/bt8xx/dst_ca.c [new file with mode: 0644]
drivers/media/pci/bt8xx/dst_ca.h [new file with mode: 0644]
drivers/media/pci/bt8xx/dst_common.h [new file with mode: 0644]
drivers/media/pci/bt8xx/dst_priv.h [new file with mode: 0644]
drivers/media/pci/bt8xx/dvb-bt8xx.c [new file with mode: 0644]
drivers/media/pci/bt8xx/dvb-bt8xx.h [new file with mode: 0644]
drivers/media/pci/ddbridge/Kconfig [new file with mode: 0644]
drivers/media/pci/ddbridge/Makefile [new file with mode: 0644]
drivers/media/pci/ddbridge/ddbridge-core.c [new file with mode: 0644]
drivers/media/pci/ddbridge/ddbridge-regs.h [new file with mode: 0644]
drivers/media/pci/ddbridge/ddbridge.h [new file with mode: 0644]
drivers/media/pci/dm1105/Kconfig [new file with mode: 0644]
drivers/media/pci/dm1105/Makefile [new file with mode: 0644]
drivers/media/pci/dm1105/dm1105.c [new file with mode: 0644]
drivers/media/pci/mantis/Kconfig [new file with mode: 0644]
drivers/media/pci/mantis/Makefile [new file with mode: 0644]
drivers/media/pci/mantis/hopper_cards.c [new file with mode: 0644]
drivers/media/pci/mantis/hopper_vp3028.c [new file with mode: 0644]
drivers/media/pci/mantis/hopper_vp3028.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_ca.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_ca.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_cards.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_common.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_core.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_core.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_dma.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_dma.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_dvb.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_dvb.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_evm.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_hif.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_hif.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_i2c.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_i2c.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_input.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_ioc.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_ioc.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_link.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_pci.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_pci.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_pcmcia.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_reg.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_uart.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_uart.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1033.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1033.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1034.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1034.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1041.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp1041.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp2033.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp2033.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp2040.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp2040.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp3028.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp3028.h [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp3030.c [new file with mode: 0644]
drivers/media/pci/mantis/mantis_vp3030.h [new file with mode: 0644]
drivers/media/pci/ngene/Kconfig [new file with mode: 0644]
drivers/media/pci/ngene/Makefile [new file with mode: 0644]
drivers/media/pci/ngene/ngene-cards.c [new file with mode: 0644]
drivers/media/pci/ngene/ngene-core.c [new file with mode: 0644]
drivers/media/pci/ngene/ngene-dvb.c [new file with mode: 0644]
drivers/media/pci/ngene/ngene-i2c.c [new file with mode: 0644]
drivers/media/pci/ngene/ngene.h [new file with mode: 0644]
drivers/media/pci/pluto2/Kconfig [new file with mode: 0644]
drivers/media/pci/pluto2/Makefile [new file with mode: 0644]
drivers/media/pci/pluto2/pluto2.c [new file with mode: 0644]
drivers/media/pci/pt1/Kconfig [new file with mode: 0644]
drivers/media/pci/pt1/Makefile [new file with mode: 0644]
drivers/media/pci/pt1/pt1.c [new file with mode: 0644]
drivers/media/pci/pt1/va1j5jf8007s.c [new file with mode: 0644]
drivers/media/pci/pt1/va1j5jf8007s.h [new file with mode: 0644]
drivers/media/pci/pt1/va1j5jf8007t.c [new file with mode: 0644]
drivers/media/pci/pt1/va1j5jf8007t.h [new file with mode: 0644]
drivers/media/pci/ttpci/Kconfig [new file with mode: 0644]
drivers/media/pci/ttpci/Makefile [new file with mode: 0644]
drivers/media/pci/ttpci/av7110.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110.h [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_av.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_av.h [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_ca.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_ca.h [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_hw.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_hw.h [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_ipack.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_ipack.h [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_ir.c [new file with mode: 0644]
drivers/media/pci/ttpci/av7110_v4l.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget-av.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget-ci.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget-core.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget-patch.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget.c [new file with mode: 0644]
drivers/media/pci/ttpci/budget.h [new file with mode: 0644]
drivers/media/pci/ttpci/ttpci-eeprom.c [new file with mode: 0644]
drivers/media/pci/ttpci/ttpci-eeprom.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/Makefile

index 6c67481eaa4b8f20292d5ab9d2cdcdc4398d9f3f..6c11ec52cbeef013839fc3bf8a27c0029c56427a 100644 (file)
@@ -2,7 +2,7 @@
 <para>The kernel demux API defines a driver-internal interface for registering low-level,
 hardware specific driver to a hardware independent demux layer. It is only of interest for
 DVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in
-<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.
+<emphasis role="tt">drivers/media/dvb-core</emphasis>.
 </para>
 <para>Maintainer note: This section must be reviewed. It is probably out of date.
 </para>
index 26da8b8721d56a3285402fe68ac0fa51b2c54e9d..81c8662a1a7c25d01f7a20afb0702ae4bc2b2f41 100644 (file)
@@ -162,7 +162,7 @@ source "drivers/media/radio/Kconfig"
 #
 
 source "drivers/media/dvb-core/Kconfig"
-source "drivers/media/dvb/Kconfig"
+source "drivers/media/pci/Kconfig"
 source "drivers/media/usb/Kconfig"
 
 comment "Supported FireWire (IEEE 1394) Adapters"
index 46a8dc3337b375fed6d196e7c7a82e34b31d30fd..90ec998a8e6ad1b27729fb1fec105744636ac54c 100644 (file)
@@ -11,5 +11,5 @@ endif
 obj-y += v4l2-core/ common/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB_CORE)  += dvb-core/ dvb/ dvb-frontends/ usb/
+obj-$(CONFIG_DVB_CORE)  += dvb-core/ pci/ dvb-frontends/ usb/
 obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
deleted file mode 100644 (file)
index e2565a4..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# DVB device configuration
-#
-
-menuconfig DVB_CAPTURE_DRIVERS
-       bool "DVB/ATSC adapters"
-       depends on DVB_CORE
-       default y
-       ---help---
-         Say Y to select Digital TV adapters
-
-if DVB_CAPTURE_DRIVERS && DVB_CORE
-
-comment "Supported SAA7146 based PCI Adapters"
-       depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/ttpci/Kconfig"
-
-comment "Supported FlexCopII (B2C2) Adapters"
-       depends on DVB_CORE && (PCI || USB) && I2C
-source "drivers/media/dvb/b2c2/Kconfig"
-
-comment "Supported BT878 Adapters"
-       depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/bt8xx/Kconfig"
-
-comment "Supported Pluto2 Adapters"
-       depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/pluto2/Kconfig"
-
-comment "Supported SDMC DM1105 Adapters"
-       depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/dm1105/Kconfig"
-
-comment "Supported Earthsoft PT1 Adapters"
-       depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/pt1/Kconfig"
-
-comment "Supported Mantis Adapters"
-       depends on DVB_CORE && PCI && I2C
-       source "drivers/media/dvb/mantis/Kconfig"
-
-comment "Supported nGene Adapters"
-       depends on DVB_CORE && PCI && I2C
-       source "drivers/media/dvb/ngene/Kconfig"
-
-comment "Supported ddbridge ('Octopus') Adapters"
-       depends on DVB_CORE && PCI && I2C
-       source "drivers/media/dvb/ddbridge/Kconfig"
-
-endif # DVB_CAPTURE_DRIVERS
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
deleted file mode 100644 (file)
index c5fa43a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for the kernel multimedia device drivers.
-#
-
-obj-y        :=        ttpci/          \
-               b2c2/           \
-               bt8xx/          \
-               pluto2/         \
-               dm1105/         \
-               pt1/            \
-               mantis/         \
-               ngene/          \
-               ddbridge/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
deleted file mode 100644 (file)
index 9e57814..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-config DVB_B2C2_FLEXCOP
-       tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
-       depends on DVB_CORE && I2C
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_MT312 if !DVB_FE_CUSTOMISE
-       select DVB_NXT200X if !DVB_FE_CUSTOMISE
-       select DVB_STV0297 if !DVB_FE_CUSTOMISE
-       select DVB_BCM3510 if !DVB_FE_CUSTOMISE
-       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-       select DVB_S5H1420 if !DVB_FE_CUSTOMISE
-       select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
-       select DVB_ISL6421 if !DVB_FE_CUSTOMISE
-       select DVB_CX24123 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
-       select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
-       help
-         Support for the digital TV receiver chip made by B2C2 Inc. included in
-         Technisats PCI cards and USB boxes.
-
-         Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_PCI
-       tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
-       depends on DVB_B2C2_FLEXCOP && PCI && I2C
-       help
-         Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
-
-         Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_USB
-       tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
-       depends on DVB_B2C2_FLEXCOP && USB && I2C
-       help
-         Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
-
-         Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_DEBUG
-       bool "Enable debug for the B2C2 FlexCop drivers"
-       depends on DVB_B2C2_FLEXCOP
-       help
-         Say Y if you want to enable the module option to control debug messages
-         of all B2C2 FlexCop drivers.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
deleted file mode 100644 (file)
index 7a1f5ce..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
-       flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
-
-ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
-b2c2-flexcop-objs += flexcop-dma.o
-endif
-
-b2c2-flexcop-pci-objs = flexcop-pci.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
-
-b2c2-flexcop-usb-objs = flexcop-usb.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
deleted file mode 100644 (file)
index 437912e..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-common.h - common header file for device-specific source files
- * see flexcop.c for copyright information
- */
-#ifndef __FLEXCOP_COMMON_H__
-#define __FLEXCOP_COMMON_H__
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-
-#include "flexcop-reg.h"
-
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
-
-#define FC_MAX_FEED 256
-
-#ifndef FC_LOG_PREFIX
-#warning please define a log prefix for your file, using a default one
-#define FC_LOG_PREFIX "b2c2-undef"
-#endif
-
-/* Steal from usb.h */
-#undef err
-#define err(format, arg...) \
-       printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) \
-       printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) \
-       printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
-
-struct flexcop_dma {
-       struct pci_dev *pdev;
-
-       u8 *cpu_addr0;
-       dma_addr_t dma_addr0;
-       u8 *cpu_addr1;
-       dma_addr_t dma_addr1;
-       u32 size; /* size of each address in bytes */
-};
-
-struct flexcop_i2c_adapter {
-       struct flexcop_device *fc;
-       struct i2c_adapter i2c_adap;
-
-       u8 no_base_addr;
-       flexcop_i2c_port_t port;
-};
-
-/* Control structure for data definitions that are common to
- * the B2C2-based PCI and USB devices.
- */
-struct flexcop_device {
-       /* general */
-       struct device *dev; /* for firmware_class */
-
-#define FC_STATE_DVB_INIT 0x01
-#define FC_STATE_I2C_INIT 0x02
-#define FC_STATE_FE_INIT  0x04
-       int init_state;
-
-       /* device information */
-       int has_32_hw_pid_filter;
-       flexcop_revision_t rev;
-       flexcop_device_type_t dev_type;
-       flexcop_bus_t bus_type;
-
-       /* dvb stuff */
-       struct dvb_adapter dvb_adapter;
-       struct dvb_frontend *fe;
-       struct dvb_net dvbnet;
-       struct dvb_demux demux;
-       struct dmxdev dmxdev;
-       struct dmx_frontend hw_frontend;
-       struct dmx_frontend mem_frontend;
-       int (*fe_sleep) (struct dvb_frontend *);
-
-       struct flexcop_i2c_adapter fc_i2c_adap[3];
-       struct mutex i2c_mutex;
-       struct module *owner;
-
-       /* options and status */
-       int extra_feedcount;
-       int feedcount;
-       int pid_filtering;
-       int fullts_streaming_state;
-
-       /* bus specific callbacks */
-       flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
-                       flexcop_ibi_register);
-       int (*write_ibi_reg) (struct flexcop_device *,
-                       flexcop_ibi_register, flexcop_ibi_value);
-       int (*i2c_request) (struct flexcop_i2c_adapter *,
-               flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
-       int (*stream_control) (struct flexcop_device *, int);
-       int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-       void *bus_specific;
-};
-
-/* exported prototypes */
-
-/* from flexcop.c */
-void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
-void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
-
-struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
-void flexcop_device_kfree(struct flexcop_device *);
-
-int flexcop_device_initialize(struct flexcop_device *);
-void flexcop_device_exit(struct flexcop_device *fc);
-void flexcop_reset_block_300(struct flexcop_device *fc);
-
-/* from flexcop-dma.c */
-int flexcop_dma_allocate(struct pci_dev *pdev,
-               struct flexcop_dma *dma, u32 size);
-void flexcop_dma_free(struct flexcop_dma *dma);
-
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_size_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
-               flexcop_dma_index_t dma_idx);
-int flexcop_dma_xfer_control(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
-               int onoff);
-int flexcop_dma_config_timer(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx, u8 cycles);
-
-/* from flexcop-eeprom.c */
-/* the PCI part uses this call to get the MAC address, the USB part has its own */
-int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
-
-/* from flexcop-i2c.c */
-/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
- * one. We have it in flexcop-i2c.c, because it is going via the actual
- * I2C-channel of the flexcop.
- */
-int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
-       u8 chipaddr, u8 addr, u8 *buf, u16 len);
-
-/* from flexcop-sram.c */
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
-       flexcop_sram_dest_target_t target);
-void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
-void flexcop_sram_ctrl(struct flexcop_device *fc,
-               int usb_wan, int sramdma, int maximumfill);
-
-/* global prototypes for the flexcop-chip */
-/* from flexcop-fe-tuner.c */
-int flexcop_frontend_init(struct flexcop_device *fc);
-void flexcop_frontend_exit(struct flexcop_device *fc);
-
-/* from flexcop-i2c.c */
-int flexcop_i2c_init(struct flexcop_device *fc);
-void flexcop_i2c_exit(struct flexcop_device *fc);
-
-/* from flexcop-sram.c */
-int flexcop_sram_init(struct flexcop_device *fc);
-
-/* from flexcop-misc.c */
-void flexcop_determine_revision(struct flexcop_device *fc);
-void flexcop_device_name(struct flexcop_device *fc,
-               const char *prefix, const char *suffix);
-void flexcop_dump_reg(struct flexcop_device *fc,
-               flexcop_ibi_register reg, int num);
-
-/* from flexcop-hw-filter.c */
-int flexcop_pid_feed_control(struct flexcop_device *fc,
-               struct dvb_demux_feed *dvbdmxfeed, int onoff);
-void flexcop_hw_filter_init(struct flexcop_device *fc);
-
-void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
-
-void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
-void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
deleted file mode 100644 (file)
index 2881e0d..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-int flexcop_dma_allocate(struct pci_dev *pdev,
-               struct flexcop_dma *dma, u32 size)
-{
-       u8 *tcpu;
-       dma_addr_t tdma = 0;
-
-       if (size % 2) {
-               err("dma buffersize has to be even.");
-               return -EINVAL;
-       }
-
-       if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) {
-               dma->pdev = pdev;
-               dma->cpu_addr0 = tcpu;
-               dma->dma_addr0 = tdma;
-               dma->cpu_addr1 = tcpu + size/2;
-               dma->dma_addr1 = tdma + size/2;
-               dma->size = size/2;
-               return 0;
-       }
-       return -ENOMEM;
-}
-EXPORT_SYMBOL(flexcop_dma_allocate);
-
-void flexcop_dma_free(struct flexcop_dma *dma)
-{
-       pci_free_consistent(dma->pdev, dma->size*2,
-                       dma->cpu_addr0, dma->dma_addr0);
-       memset(dma,0,sizeof(struct flexcop_dma));
-}
-EXPORT_SYMBOL(flexcop_dma_free);
-
-int flexcop_dma_config(struct flexcop_device *fc,
-               struct flexcop_dma *dma,
-               flexcop_dma_index_t dma_idx)
-{
-       flexcop_ibi_value v0x0,v0x4,v0xc;
-       v0x0.raw = v0x4.raw = v0xc.raw = 0;
-
-       v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
-       v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
-       v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
-
-       if ((dma_idx & FC_DMA_1) == dma_idx) {
-               fc->write_ibi_reg(fc,dma1_000,v0x0);
-               fc->write_ibi_reg(fc,dma1_004,v0x4);
-               fc->write_ibi_reg(fc,dma1_00c,v0xc);
-       } else if ((dma_idx & FC_DMA_2) == dma_idx) {
-               fc->write_ibi_reg(fc,dma2_010,v0x0);
-               fc->write_ibi_reg(fc,dma2_014,v0x4);
-               fc->write_ibi_reg(fc,dma2_01c,v0xc);
-       } else {
-               err("either DMA1 or DMA2 can be configured within one "
-                       "flexcop_dma_config call.");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config);
-
-/* start the DMA transfers, but not the DMA IRQs */
-int flexcop_dma_xfer_control(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx,
-               flexcop_dma_addr_index_t index,
-               int onoff)
-{
-       flexcop_ibi_value v0x0,v0xc;
-       flexcop_ibi_register r0x0,r0xc;
-
-       if ((dma_idx & FC_DMA_1) == dma_idx) {
-               r0x0 = dma1_000;
-               r0xc = dma1_00c;
-       } else if ((dma_idx & FC_DMA_2) == dma_idx) {
-               r0x0 = dma2_010;
-               r0xc = dma2_01c;
-       } else {
-               err("either transfer DMA1 or DMA2 can be started within one "
-                       "flexcop_dma_xfer_control call.");
-               return -EINVAL;
-       }
-
-       v0x0 = fc->read_ibi_reg(fc,r0x0);
-       v0xc = fc->read_ibi_reg(fc,r0xc);
-
-       deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
-       deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
-
-       if (index & FC_DMA_SUBADDR_0)
-               v0x0.dma_0x0.dma_0start = onoff;
-
-       if (index & FC_DMA_SUBADDR_1)
-               v0xc.dma_0xc.dma_1start = onoff;
-
-       fc->write_ibi_reg(fc,r0x0,v0x0);
-       fc->write_ibi_reg(fc,r0xc,v0xc);
-
-       deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
-       deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_xfer_control);
-
-static int flexcop_dma_remap(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx,
-               int onoff)
-{
-       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-       deb_info("%s\n",__func__);
-       v.dma_0xc.remap_enable = onoff;
-       fc->write_ibi_reg(fc,r,v);
-       return 0;
-}
-
-int flexcop_dma_control_size_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no,
-               int onoff)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
-
-       if (no & FC_DMA_1)
-               v.ctrl_208.DMA1_IRQ_Enable_sig = onoff;
-
-       if (no & FC_DMA_2)
-               v.ctrl_208.DMA2_IRQ_Enable_sig = onoff;
-
-       fc->write_ibi_reg(fc,ctrl_208,v);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_control_size_irq);
-
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no,
-               int onoff)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
-
-       if (no & FC_DMA_1)
-               v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
-
-       if (no & FC_DMA_2)
-               v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
-
-       fc->write_ibi_reg(fc,ctrl_208,v);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
-
-/* 1 cycles = 1.97 msec */
-int flexcop_dma_config_timer(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx, u8 cycles)
-{
-       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-
-       flexcop_dma_remap(fc,dma_idx,0);
-
-       deb_info("%s\n",__func__);
-       v.dma_0x4_write.dmatimer = cycles;
-       fc->write_ibi_reg(fc,r,v);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config_timer);
-
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c
deleted file mode 100644 (file)
index a25373a..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-#if 0
-/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
-static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
-       return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
-               u32 len, u8 *wbuf, u8 *rbuf, int retries)
-{
-int i;
-
-for (i = 0; i < retries; i++) {
-       if (eeprom_write(adapter, addr, wbuf, len) == len) {
-               if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/* These functions could be used to unlock SkyStar2 cards. */
-
-static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
-{
-       u8 rbuf[20];
-       u8 wbuf[20];
-
-       if (len != 16)
-               return 0;
-
-       memcpy(wbuf, key, len);
-       wbuf[16] = 0;
-       wbuf[17] = 0;
-       wbuf[18] = 0;
-       wbuf[19] = calc_lrc(wbuf, 19);
-       return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
-}
-
-static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
-{
-       u8 buf[20];
-
-       if (len != 16)
-               return 0;
-
-       if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
-               return 0;
-
-       memcpy(key, buf, len);
-       return 1;
-}
-
-static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
-       u8 tmp[8];
-
-       if (type != 0) {
-               tmp[0] = mac[0];
-               tmp[1] = mac[1];
-               tmp[2] = mac[2];
-               tmp[3] = mac[5];
-               tmp[4] = mac[6];
-               tmp[5] = mac[7];
-       } else {
-               tmp[0] = mac[0];
-               tmp[1] = mac[1];
-               tmp[2] = mac[2];
-               tmp[3] = mac[3];
-               tmp[4] = mac[4];
-               tmp[5] = mac[5];
-       }
-
-       tmp[6] = 0;
-       tmp[7] = calc_lrc(tmp, 7);
-
-       if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
-               return 1;
-       return 0;
-}
-
-static int flexcop_eeprom_read(struct flexcop_device *fc,
-               u16 addr, u8 *buf, u16 len)
-{
-       return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
-}
-
-#endif
-
-static u8 calc_lrc(u8 *buf, int len)
-{
-       int i;
-       u8 sum = 0;
-       for (i = 0; i < len; i++)
-               sum = sum ^ buf[i];
-       return sum;
-}
-
-static int flexcop_eeprom_request(struct flexcop_device *fc,
-       flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
-{
-       int i,ret = 0;
-       u8 chipaddr =  0x50 | ((addr >> 8) & 3);
-       for (i = 0; i < retries; i++) {
-               ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
-                       addr & 0xff, buf, len);
-               if (ret == 0)
-                       break;
-       }
-       return ret;
-}
-
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
-               u8 *buf, u16 len, int retries)
-{
-       int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
-       if (ret == 0)
-               if (calc_lrc(buf, len - 1) != buf[len - 1])
-                       ret = -EINVAL;
-       return ret;
-}
-
-/* JJ's comment about extended == 1: it is not presently used anywhere but was
- * added to the low-level functions for possible support of EUI64 */
-int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
-{
-       u8 buf[8];
-       int ret = 0;
-
-       if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
-               if (extended != 0) {
-                       err("TODO: extended (EUI64) MAC addresses aren't "
-                               "completely supported yet");
-                       ret = -EINVAL;
-               } else
-                       memcpy(fc->dvb_adapter.proposed_mac,buf,6);
-       }
-       return ret;
-}
-EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
deleted file mode 100644 (file)
index 850a6c6..0000000
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
- * see flexcop.c for copyright information
- */
-#include <media/tuner.h>
-#include "flexcop.h"
-#include "mt312.h"
-#include "stv0299.h"
-#include "s5h1420.h"
-#include "itd1000.h"
-#include "cx24113.h"
-#include "cx24123.h"
-#include "isl6421.h"
-#include "mt352.h"
-#include "bcm3510.h"
-#include "nxt200x.h"
-#include "dvb-pll.h"
-#include "lgdt330x.h"
-#include "tuner-simple.h"
-#include "stv0297.h"
-
-
-/* Can we use the specified front-end?  Remember that if we are compiled
- * into the kernel we can't call code that's in modules.  */
-#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
-       (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
-
-/* lnb control */
-#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
-static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct flexcop_device *fc = fe->dvb->priv;
-       flexcop_ibi_value v;
-       deb_tuner("polarity/voltage = %u\n", voltage);
-
-       v = fc->read_ibi_reg(fc, misc_204);
-       switch (voltage) {
-       case SEC_VOLTAGE_OFF:
-               v.misc_204.ACPI1_sig = 1;
-               break;
-       case SEC_VOLTAGE_13:
-               v.misc_204.ACPI1_sig = 0;
-               v.misc_204.LNB_L_H_sig = 0;
-               break;
-       case SEC_VOLTAGE_18:
-               v.misc_204.ACPI1_sig = 0;
-               v.misc_204.LNB_L_H_sig = 1;
-               break;
-       default:
-               err("unknown SEC_VOLTAGE value");
-               return -EINVAL;
-       }
-       return fc->write_ibi_reg(fc, misc_204, v);
-}
-#endif
-
-#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
-static int flexcop_sleep(struct dvb_frontend* fe)
-{
-       struct flexcop_device *fc = fe->dvb->priv;
-       if (fc->fe_sleep)
-               return fc->fe_sleep(fe);
-       return 0;
-}
-#endif
-
-/* SkyStar2 DVB-S rev 2.3 */
-#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
-static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
-       struct flexcop_device *fc = fe->dvb->priv;
-       flexcop_ibi_value v;
-       u16 ax;
-       v.raw = 0;
-       deb_tuner("tone = %u\n",tone);
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               ax = 0x01ff;
-               break;
-       case SEC_TONE_OFF:
-               ax = 0;
-               break;
-       default:
-               err("unknown SEC_TONE value");
-               return -EINVAL;
-       }
-
-       v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
-       v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
-       v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
-       return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
-}
-
-static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
-{
-       flexcop_set_tone(fe, SEC_TONE_ON);
-       udelay(data ? 500 : 1000);
-       flexcop_set_tone(fe, SEC_TONE_OFF);
-       udelay(data ? 1000 : 500);
-}
-
-static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
-{
-       int i, par = 1, d;
-       for (i = 7; i >= 0; i--) {
-               d = (data >> i) & 1;
-               par ^= d;
-               flexcop_diseqc_send_bit(fe, d);
-       }
-       flexcop_diseqc_send_bit(fe, par);
-}
-
-static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
-       int len, u8 *msg, unsigned long burst)
-{
-       int i;
-
-       flexcop_set_tone(fe, SEC_TONE_OFF);
-       mdelay(16);
-
-       for (i = 0; i < len; i++)
-               flexcop_diseqc_send_byte(fe,msg[i]);
-       mdelay(16);
-
-       if (burst != -1) {
-               if (burst)
-                       flexcop_diseqc_send_byte(fe, 0xff);
-               else {
-                       flexcop_set_tone(fe, SEC_TONE_ON);
-                       mdelay(12);
-                       udelay(500);
-                       flexcop_set_tone(fe, SEC_TONE_OFF);
-               }
-               msleep(20);
-       }
-       return 0;
-}
-
-static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
-       struct dvb_diseqc_master_cmd *cmd)
-{
-       return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
-}
-
-static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
-       fe_sec_mini_cmd_t minicmd)
-{
-       return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
-}
-
-static struct mt312_config skystar23_samsung_tbdu18132_config = {
-       .demod_address = 0x0e,
-};
-
-static int skystar2_rev23_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       struct dvb_frontend_ops *ops;
-
-       fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
-       if (!fc->fe)
-               return 0;
-
-       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
-                       DVB_PLL_SAMSUNG_TBDU18132))
-               return 0;
-
-       ops = &fc->fe->ops;
-       ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
-       ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
-       ops->set_tone               = flexcop_set_tone;
-       ops->set_voltage            = flexcop_set_voltage;
-       fc->fe_sleep                = ops->sleep;
-       ops->sleep                  = flexcop_sleep;
-       return 1;
-}
-#else
-#define skystar2_rev23_attach NULL
-#endif
-
-/* SkyStar2 DVB-S rev 2.6 */
-#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
-static int samsung_tbmu24112_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;
-}
-
-static u8 samsung_tbmu24112_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7D,
-       0x05, 0x35,
-       0x06, 0x02,
-       0x07, 0x00,
-       0x08, 0xC3,
-       0x0C, 0x00,
-       0x0D, 0x81,
-       0x0E, 0x23,
-       0x0F, 0x12,
-       0x10, 0x7E,
-       0x11, 0x84,
-       0x12, 0xB9,
-       0x13, 0x88,
-       0x14, 0x89,
-       0x15, 0xC9,
-       0x16, 0x00,
-       0x17, 0x5C,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1A, 0x00,
-       0x1C, 0x00,
-       0x1D, 0x00,
-       0x1E, 0x00,
-       0x1F, 0x3A,
-       0x20, 0x2E,
-       0x21, 0x80,
-       0x22, 0xFF,
-       0x23, 0xC1,
-       0x28, 0x00,
-       0x29, 0x1E,
-       0x2A, 0x14,
-       0x2B, 0x0F,
-       0x2C, 0x09,
-       0x2D, 0x05,
-       0x31, 0x1F,
-       0x32, 0x19,
-       0x33, 0xFE,
-       0x34, 0x93,
-       0xff, 0xff,
-};
-
-static struct stv0299_config samsung_tbmu24112_config = {
-       .demod_address = 0x68,
-       .inittab = samsung_tbmu24112_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_LK,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
-};
-
-static int skystar2_rev26_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
-       if (!fc->fe)
-               return 0;
-
-       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
-                       DVB_PLL_SAMSUNG_TBMU24112))
-               return 0;
-
-       fc->fe->ops.set_voltage = flexcop_set_voltage;
-       fc->fe_sleep = fc->fe->ops.sleep;
-       fc->fe->ops.sleep = flexcop_sleep;
-       return 1;
-
-}
-#else
-#define skystar2_rev26_attach NULL
-#endif
-
-/* SkyStar2 DVB-S rev 2.7 */
-#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
-static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
-       .demod_address = 0x53,
-       .invert = 1,
-       .repeated_start_workaround = 1,
-       .serial_mpeg = 1,
-};
-
-static struct itd1000_config skystar2_rev2_7_itd1000_config = {
-       .i2c_address = 0x61,
-};
-
-static int skystar2_rev27_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       flexcop_ibi_value r108;
-       struct i2c_adapter *i2c_tuner;
-
-       /* enable no_base_addr - no repeated start when reading */
-       fc->fc_i2c_adap[0].no_base_addr = 1;
-       fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
-                           i2c);
-       if (!fc->fe)
-               goto fail;
-
-       i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
-       if (!i2c_tuner)
-               goto fail;
-
-       fc->fe_sleep = fc->fe->ops.sleep;
-       fc->fe->ops.sleep = flexcop_sleep;
-
-       /* enable no_base_addr - no repeated start when reading */
-       fc->fc_i2c_adap[2].no_base_addr = 1;
-       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
-                       0x08, 1, 1)) {
-               err("ISL6421 could NOT be attached");
-               goto fail_isl;
-       }
-       info("ISL6421 successfully attached");
-
-       /* the ITD1000 requires a lower i2c clock - is it a problem ? */
-       r108.raw = 0x00000506;
-       fc->write_ibi_reg(fc, tw_sm_c_108, r108);
-       if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
-                       &skystar2_rev2_7_itd1000_config)) {
-               err("ITD1000 could NOT be attached");
-               /* Should i2c clock be restored? */
-               goto fail_isl;
-       }
-       info("ITD1000 successfully attached");
-
-       return 1;
-
-fail_isl:
-       fc->fc_i2c_adap[2].no_base_addr = 0;
-fail:
-       /* for the next devices we need it again */
-       fc->fc_i2c_adap[0].no_base_addr = 0;
-       return 0;
-}
-#else
-#define skystar2_rev27_attach NULL
-#endif
-
-/* SkyStar2 rev 2.8 */
-#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
-static struct cx24123_config skystar2_rev2_8_cx24123_config = {
-       .demod_address = 0x55,
-       .dont_use_pll = 1,
-       .agc_callback = cx24113_agc_callback,
-};
-
-static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
-       .i2c_addr = 0x54,
-       .xtal_khz = 10111,
-};
-
-static int skystar2_rev28_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       struct i2c_adapter *i2c_tuner;
-
-       fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
-                           i2c);
-       if (!fc->fe)
-               return 0;
-
-       i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
-       if (!i2c_tuner)
-               return 0;
-
-       if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
-                       i2c_tuner)) {
-               err("CX24113 could NOT be attached");
-               return 0;
-       }
-       info("CX24113 successfully attached");
-
-       fc->fc_i2c_adap[2].no_base_addr = 1;
-       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
-                       0x08, 0, 0)) {
-               err("ISL6421 could NOT be attached");
-               fc->fc_i2c_adap[2].no_base_addr = 0;
-               return 0;
-       }
-       info("ISL6421 successfully attached");
-       /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
-        * IR-receiver (PIC16F818) - but the card has no input for that ??? */
-       return 1;
-}
-#else
-#define skystar2_rev28_attach NULL
-#endif
-
-/* AirStar DVB-T */
-#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
-static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
-{
-       static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
-       static u8 mt352_reset[] = { 0x50, 0x80 };
-       static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
-       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-       return 0;
-}
-
-static struct mt352_config samsung_tdtc9251dh0_config = {
-       .demod_address = 0x0f,
-       .demod_init    = samsung_tdtc9251dh0_demod_init,
-};
-
-static int airstar_dvbt_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
-       if (!fc->fe)
-               return 0;
-
-       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
-                           DVB_PLL_SAMSUNG_TDTC9251DH0);
-}
-#else
-#define airstar_dvbt_attach NULL
-#endif
-
-/* AirStar ATSC 1st generation */
-#if FE_SUPPORTED(BCM3510)
-static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
-       const struct firmware **fw, char* name)
-{
-       struct flexcop_device *fc = fe->dvb->priv;
-       return request_firmware(fw, name, fc->dev);
-}
-
-static struct bcm3510_config air2pc_atsc_first_gen_config = {
-       .demod_address    = 0x0f,
-       .request_firmware = flexcop_fe_request_firmware,
-};
-
-static int airstar_atsc1_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
-       return fc->fe != NULL;
-}
-#else
-#define airstar_atsc1_attach NULL
-#endif
-
-/* AirStar ATSC 2nd generation */
-#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
-static struct nxt200x_config samsung_tbmv_config = {
-       .demod_address = 0x0a,
-};
-
-static int airstar_atsc2_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
-       if (!fc->fe)
-               return 0;
-
-       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
-                           DVB_PLL_SAMSUNG_TBMV);
-}
-#else
-#define airstar_atsc2_attach NULL
-#endif
-
-/* AirStar ATSC 3rd generation */
-#if FE_SUPPORTED(LGDT330X)
-static struct lgdt330x_config air2pc_atsc_hd5000_config = {
-       .demod_address       = 0x59,
-       .demod_chip          = LGDT3303,
-       .serial_mpeg         = 0x04,
-       .clock_polarity_flip = 1,
-};
-
-static int airstar_atsc3_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
-       if (!fc->fe)
-               return 0;
-
-       return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
-                           TUNER_LG_TDVS_H06XF);
-}
-#else
-#define airstar_atsc3_attach NULL
-#endif
-
-/* CableStar2 DVB-C */
-#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
-static u8 alps_tdee4_stv0297_inittab[] = {
-       0x80, 0x01,
-       0x80, 0x00,
-       0x81, 0x01,
-       0x81, 0x00,
-       0x00, 0x48,
-       0x01, 0x58,
-       0x03, 0x00,
-       0x04, 0x00,
-       0x07, 0x00,
-       0x08, 0x00,
-       0x30, 0xff,
-       0x31, 0x9d,
-       0x32, 0xff,
-       0x33, 0x00,
-       0x34, 0x29,
-       0x35, 0x55,
-       0x36, 0x80,
-       0x37, 0x6e,
-       0x38, 0x9c,
-       0x40, 0x1a,
-       0x41, 0xfe,
-       0x42, 0x33,
-       0x43, 0x00,
-       0x44, 0xff,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x49, 0x04,
-       0x4a, 0x51,
-       0x4b, 0xf8,
-       0x52, 0x30,
-       0x53, 0x06,
-       0x59, 0x06,
-       0x5a, 0x5e,
-       0x5b, 0x04,
-       0x61, 0x49,
-       0x62, 0x0a,
-       0x70, 0xff,
-       0x71, 0x04,
-       0x72, 0x00,
-       0x73, 0x00,
-       0x74, 0x0c,
-       0x80, 0x20,
-       0x81, 0x00,
-       0x82, 0x30,
-       0x83, 0x00,
-       0x84, 0x04,
-       0x85, 0x22,
-       0x86, 0x08,
-       0x87, 0x1b,
-       0x88, 0x00,
-       0x89, 0x00,
-       0x90, 0x00,
-       0x91, 0x04,
-       0xa0, 0x86,
-       0xa1, 0x00,
-       0xa2, 0x00,
-       0xb0, 0x91,
-       0xb1, 0x0b,
-       0xc0, 0x5b,
-       0xc1, 0x10,
-       0xc2, 0x12,
-       0xd0, 0x02,
-       0xd1, 0x00,
-       0xd2, 0x00,
-       0xd3, 0x00,
-       0xd4, 0x02,
-       0xd5, 0x00,
-       0xde, 0x00,
-       0xdf, 0x01,
-       0xff, 0xff,
-};
-
-static struct stv0297_config alps_tdee4_stv0297_config = {
-       .demod_address = 0x1c,
-       .inittab = alps_tdee4_stv0297_inittab,
-};
-
-static int cablestar2_attach(struct flexcop_device *fc,
-       struct i2c_adapter *i2c)
-{
-       fc->fc_i2c_adap[0].no_base_addr = 1;
-       fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
-       if (!fc->fe)
-               goto fail;
-
-       /* This tuner doesn't use the stv0297's I2C gate, but instead the
-        * tuner is connected to a different flexcop I2C adapter.  */
-       if (fc->fe->ops.i2c_gate_ctrl)
-               fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
-       fc->fe->ops.i2c_gate_ctrl = NULL;
-
-       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
-                       &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
-               goto fail;
-
-       return 1;
-
-fail:
-       /* Reset for next frontend to try */
-       fc->fc_i2c_adap[0].no_base_addr = 0;
-       return 0;
-}
-#else
-#define cablestar2_attach NULL
-#endif
-
-static struct {
-       flexcop_device_type_t type;
-       int (*attach)(struct flexcop_device *, struct i2c_adapter *);
-} flexcop_frontends[] = {
-       { FC_SKY_REV27, skystar2_rev27_attach },
-       { FC_SKY_REV28, skystar2_rev28_attach },
-       { FC_SKY_REV26, skystar2_rev26_attach },
-       { FC_AIR_DVBT, airstar_dvbt_attach },
-       { FC_AIR_ATSC2, airstar_atsc2_attach },
-       { FC_AIR_ATSC3, airstar_atsc3_attach },
-       { FC_AIR_ATSC1, airstar_atsc1_attach },
-       { FC_CABLE, cablestar2_attach },
-       { FC_SKY_REV23, skystar2_rev23_attach },
-};
-
-/* try to figure out the frontend */
-int flexcop_frontend_init(struct flexcop_device *fc)
-{
-       int i;
-       for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
-               if (!flexcop_frontends[i].attach)
-                       continue;
-               /* type needs to be set before, because of some workarounds
-                * done based on the probed card type */
-               fc->dev_type = flexcop_frontends[i].type;
-               if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
-                       goto fe_found;
-               /* Clean up partially attached frontend */
-               if (fc->fe) {
-                       dvb_frontend_detach(fc->fe);
-                       fc->fe = NULL;
-               }
-       }
-       fc->dev_type = FC_UNK;
-       err("no frontend driver found for this B2C2/FlexCop adapter");
-       return -ENODEV;
-
-fe_found:
-       info("found '%s' .", fc->fe->ops.info.name);
-       if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
-               err("frontend registration failed!");
-               dvb_frontend_detach(fc->fe);
-               fc->fe = NULL;
-               return -EINVAL;
-       }
-       fc->init_state |= FC_STATE_FE_INIT;
-       return 0;
-}
-
-void flexcop_frontend_exit(struct flexcop_device *fc)
-{
-       if (fc->init_state & FC_STATE_FE_INIT) {
-               dvb_unregister_frontend(fc->fe);
-               dvb_frontend_detach(fc->fe);
-       }
-       fc->init_state &= ~FC_STATE_FE_INIT;
-}
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
deleted file mode 100644 (file)
index 77e4547..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-hw-filter.c - pid and mac address filtering and control functions
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
-{
-       flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
-       deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
-}
-
-void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
-{
-       flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
-}
-
-static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
-{
-       flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
-}
-
-void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
-{
-       flexcop_ibi_value v418, v41c;
-       v41c = fc->read_ibi_reg(fc, mac_address_41c);
-
-       v418.mac_address_418.MAC1 = mac[0];
-       v418.mac_address_418.MAC2 = mac[1];
-       v418.mac_address_418.MAC3 = mac[2];
-       v418.mac_address_418.MAC6 = mac[3];
-       v41c.mac_address_41c.MAC7 = mac[4];
-       v41c.mac_address_41c.MAC8 = mac[5];
-
-       fc->write_ibi_reg(fc, mac_address_418, v418);
-       fc->write_ibi_reg(fc, mac_address_41c, v41c);
-}
-
-void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
-{
-       flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
-}
-
-static void flexcop_pid_group_filter(struct flexcop_device *fc,
-               u16 pid, u16 mask)
-{
-       /* index_reg_310.extra_index_reg need to 0 or 7 to work */
-       flexcop_ibi_value v30c;
-       v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
-       v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
-       fc->write_ibi_reg(fc, pid_filter_30c, v30c);
-}
-
-static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
-{
-       flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
-}
-
-/* this fancy define reduces the code size of the quite similar PID controlling of
- * the first 6 PIDs
- */
-
-#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
-       flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
-v208 = fc->read_ibi_reg(fc, ctrl_208); \
-vpid.vregname.field = onoff ? pid : 0x1fff; \
-vpid.vregname.trans_field = transval; \
-v208.ctrl_208.enablefield = onoff; \
-fc->write_ibi_reg(fc, vregname, vpid); \
-fc->write_ibi_reg(fc, ctrl_208, v208);
-
-static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
-                       Stream1_trans, 0);
-}
-
-static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
-                       Stream2_trans, 0);
-}
-
-static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
-}
-
-static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
-}
-
-static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
-}
-
-static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
-               u16 pid, int onoff)
-{
-       pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
-}
-
-static void flexcop_pid_control(struct flexcop_device *fc,
-               int index, u16 pid, int onoff)
-{
-       if (pid == 0x2000)
-               return;
-
-       deb_ts("setting pid: %5d %04x at index %d '%s'\n",
-                       pid, pid, index, onoff ? "on" : "off");
-
-       /* We could use bit magic here to reduce source code size.
-        * I decided against it, but to use the real register names */
-       switch (index) {
-       case 0:
-               flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
-               break;
-       case 1:
-               flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
-               break;
-       case 2:
-               flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
-               break;
-       case 3:
-               flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
-               break;
-       case 4:
-               flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
-               break;
-       case 5:
-               flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
-               break;
-       default:
-               if (fc->has_32_hw_pid_filter && index < 38) {
-                       flexcop_ibi_value vpid, vid;
-
-                       /* set the index */
-                       vid = fc->read_ibi_reg(fc, index_reg_310);
-                       vid.index_reg_310.index_reg = index - 6;
-                       fc->write_ibi_reg(fc, index_reg_310, vid);
-
-                       vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
-                       vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
-                       vpid.pid_n_reg_314.PID_enable_bit = onoff;
-                       fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
-               }
-               break;
-       }
-}
-
-static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
-{
-       if (fc->fullts_streaming_state != onoff) {
-               deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
-               flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
-               flexcop_pid_group_filter_ctrl(fc, onoff);
-               fc->fullts_streaming_state = onoff;
-       }
-       return 0;
-}
-
-int flexcop_pid_feed_control(struct flexcop_device *fc,
-               struct dvb_demux_feed *dvbdmxfeed, int onoff)
-{
-       int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
-
-       fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
-       if (dvbdmxfeed->index >= max_pid_filter)
-               fc->extra_feedcount += onoff ? 1 : -1;
-
-       /* toggle complete-TS-streaming when:
-        * - pid_filtering is not enabled and it is the first or last feed requested
-        * - pid_filtering is enabled,
-        *   - but the number of requested feeds is exceeded
-        *   - or the requested pid is 0x2000 */
-
-       if (!fc->pid_filtering && fc->feedcount == onoff)
-               flexcop_toggle_fullts_streaming(fc, onoff);
-
-       if (fc->pid_filtering) {
-               flexcop_pid_control \
-                       (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
-
-               if (fc->extra_feedcount > 0)
-                       flexcop_toggle_fullts_streaming(fc, 1);
-               else if (dvbdmxfeed->pid == 0x2000)
-                       flexcop_toggle_fullts_streaming(fc, onoff);
-               else
-                       flexcop_toggle_fullts_streaming(fc, 0);
-       }
-
-       /* if it was the first or last feed request change the stream-status */
-       if (fc->feedcount == onoff) {
-               flexcop_rcv_data_ctrl(fc, onoff);
-               if (fc->stream_control) /* device specific stream control */
-                       fc->stream_control(fc, onoff);
-
-               /* feeding stopped -> reset the flexcop filter*/
-               if (onoff == 0) {
-                       flexcop_reset_block_300(fc);
-                       flexcop_hw_filter_init(fc);
-               }
-       }
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_pid_feed_control);
-
-void flexcop_hw_filter_init(struct flexcop_device *fc)
-{
-       int i;
-       flexcop_ibi_value v;
-       for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
-               flexcop_pid_control(fc, i, 0x1fff, 0);
-
-       flexcop_pid_group_filter(fc, 0, 0x1fe0);
-       flexcop_pid_group_filter_ctrl(fc, 0);
-
-       v = fc->read_ibi_reg(fc, pid_filter_308);
-       v.pid_filter_308.EMM_filter_4 = 1;
-       v.pid_filter_308.EMM_filter_6 = 0;
-       fc->write_ibi_reg(fc, pid_filter_308, v);
-
-       flexcop_null_filter_ctrl(fc, 1);
-}
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
deleted file mode 100644 (file)
index 965d5eb..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-#define FC_MAX_I2C_RETRIES 100000
-
-static int flexcop_i2c_operation(struct flexcop_device *fc,
-               flexcop_ibi_value *r100)
-{
-       int i;
-       flexcop_ibi_value r;
-
-       r100->tw_sm_c_100.working_start = 1;
-       deb_i2c("r100 before: %08x\n",r100->raw);
-
-       fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
-       fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
-
-       for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
-               r = fc->read_ibi_reg(fc, tw_sm_c_100);
-
-               if (!r.tw_sm_c_100.no_base_addr_ack_error) {
-                       if (r.tw_sm_c_100.st_done) {
-                               *r100 = r;
-                               deb_i2c("i2c success\n");
-                               return 0;
-                       }
-               } else {
-                       deb_i2c("suffering from an i2c ack_error\n");
-                       return -EREMOTEIO;
-               }
-       }
-       deb_i2c("tried %d times i2c operation, "
-                       "never finished or too many ack errors.\n", i);
-       return -EREMOTEIO;
-}
-
-static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
-               flexcop_ibi_value r100, u8 *buf)
-{
-       flexcop_ibi_value r104;
-       int len = r100.tw_sm_c_100.total_bytes,
-               /* remember total_bytes is buflen-1 */
-               ret;
-
-       /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
-        * correctly:
-        *
-        * the ITD1000 is behind an i2c-gate which closes automatically
-        * after an i2c-transaction the STV0297 needs 2 consecutive reads
-        * one with no_base_addr = 0 and one with 1
-        *
-        * those two work-arounds are conflictin: we check for the card
-        * type, it is set when probing the ITD1000 */
-       if (i2c->fc->dev_type == FC_SKY_REV27)
-               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
-
-       ret = flexcop_i2c_operation(i2c->fc, &r100);
-       if (ret != 0) {
-               deb_i2c("Retrying operation\n");
-               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
-               ret = flexcop_i2c_operation(i2c->fc, &r100);
-       }
-       if (ret != 0) {
-               deb_i2c("read failed. %d\n", ret);
-               return ret;
-       }
-
-       buf[0] = r100.tw_sm_c_100.data1_reg;
-
-       if (len > 0) {
-               r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
-               deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
-
-               /* there is at least one more byte, otherwise we wouldn't be here */
-               buf[1] = r104.tw_sm_c_104.data2_reg;
-               if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
-               if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
-       }
-       return 0;
-}
-
-static int flexcop_i2c_write4(struct flexcop_device *fc,
-               flexcop_ibi_value r100, u8 *buf)
-{
-       flexcop_ibi_value r104;
-       int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
-       r104.raw = 0;
-
-       /* there is at least one byte, otherwise we wouldn't be here */
-       r100.tw_sm_c_100.data1_reg = buf[0];
-       r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
-       r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
-       r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
-
-       deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
-
-       /* write the additional i2c data before doing the actual i2c operation */
-       fc->write_ibi_reg(fc, tw_sm_c_104, r104);
-       return flexcop_i2c_operation(fc, &r100);
-}
-
-int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
-               flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
-{
-       int ret;
-
-#ifdef DUMP_I2C_MESSAGES
-       int i;
-#endif
-
-       u16 bytes_to_transfer;
-       flexcop_ibi_value r100;
-
-       deb_i2c("op = %d\n",op);
-       r100.raw = 0;
-       r100.tw_sm_c_100.chipaddr = chipaddr;
-       r100.tw_sm_c_100.twoWS_rw = op;
-       r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
-
-#ifdef DUMP_I2C_MESSAGES
-       printk(KERN_DEBUG "%d ", i2c->port);
-       if (op == FC_READ)
-               printk("rd(");
-       else
-               printk("wr(");
-       printk("%02x): %02x ", chipaddr, addr);
-#endif
-
-       /* in that case addr is the only value ->
-        * we write it twice as baseaddr and val0
-        * BBTI is doing it like that for ISL6421 at least */
-       if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
-               buf = &addr;
-               len = 1;
-       }
-
-       while (len != 0) {
-               bytes_to_transfer = len > 4 ? 4 : len;
-
-               r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
-               r100.tw_sm_c_100.baseaddr = addr;
-
-               if (op == FC_READ)
-                       ret = flexcop_i2c_read4(i2c, r100, buf);
-               else
-                       ret = flexcop_i2c_write4(i2c->fc, r100, buf);
-
-#ifdef DUMP_I2C_MESSAGES
-               for (i = 0; i < bytes_to_transfer; i++)
-                       printk("%02x ", buf[i]);
-#endif
-
-               if (ret < 0)
-                       return ret;
-
-               buf  += bytes_to_transfer;
-               addr += bytes_to_transfer;
-               len  -= bytes_to_transfer;
-       }
-
-#ifdef DUMP_I2C_MESSAGES
-       printk("\n");
-#endif
-
-       return 0;
-}
-/* exported for PCI i2c */
-EXPORT_SYMBOL(flexcop_i2c_request);
-
-/* master xfer callback for demodulator */
-static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msgs[], int num)
-{
-       struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
-       int i, ret = 0;
-
-       /* Some drivers use 1 byte or 0 byte reads as probes, which this
-        * driver doesn't support.  These probes will always fail, so this
-        * hack makes them always succeed.  If one knew how, it would of
-        * course be better to actually do the read.  */
-       if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
-               return 1;
-
-       if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
-               return -ERESTARTSYS;
-
-       for (i = 0; i < num; i++) {
-               /* reading */
-               if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
-                       ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
-                                       msgs[i].buf[0], msgs[i+1].buf,
-                                       msgs[i+1].len);
-                       i++; /* skip the following message */
-               } else /* writing */
-                       ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
-                                       msgs[i].buf[0], &msgs[i].buf[1],
-                                       msgs[i].len - 1);
-               if (ret < 0) {
-                       deb_i2c("i2c master_xfer failed");
-                       break;
-               }
-       }
-
-       mutex_unlock(&i2c->fc->i2c_mutex);
-
-       if (ret == 0)
-               ret = num;
-       return ret;
-}
-
-static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm flexcop_algo = {
-       .master_xfer    = flexcop_master_xfer,
-       .functionality  = flexcop_i2c_func,
-};
-
-int flexcop_i2c_init(struct flexcop_device *fc)
-{
-       int ret;
-       mutex_init(&fc->i2c_mutex);
-
-       fc->fc_i2c_adap[0].fc = fc;
-       fc->fc_i2c_adap[1].fc = fc;
-       fc->fc_i2c_adap[2].fc = fc;
-       fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
-       fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
-       fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
-
-       strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
-                       sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
-       strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
-                       sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
-       strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
-                       sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
-
-       i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
-       i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
-       i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
-
-       fc->fc_i2c_adap[0].i2c_adap.algo =
-               fc->fc_i2c_adap[1].i2c_adap.algo =
-               fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
-       fc->fc_i2c_adap[0].i2c_adap.algo_data =
-               fc->fc_i2c_adap[1].i2c_adap.algo_data =
-               fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
-       fc->fc_i2c_adap[0].i2c_adap.dev.parent =
-               fc->fc_i2c_adap[1].i2c_adap.dev.parent =
-               fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
-
-       ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-       if (ret < 0)
-               return ret;
-
-       ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
-       if (ret < 0)
-               goto adap_1_failed;
-
-       ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
-       if (ret < 0)
-               goto adap_2_failed;
-
-       fc->init_state |= FC_STATE_I2C_INIT;
-       return 0;
-
-adap_2_failed:
-       i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
-adap_1_failed:
-       i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-       return ret;
-}
-
-void flexcop_i2c_exit(struct flexcop_device *fc)
-{
-       if (fc->init_state & FC_STATE_I2C_INIT) {
-               i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
-               i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
-               i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-       }
-       fc->init_state &= ~FC_STATE_I2C_INIT;
-}
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
deleted file mode 100644 (file)
index f06f3a9..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-misc.c - miscellaneous functions
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-void flexcop_determine_revision(struct flexcop_device *fc)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
-
-       switch (v.misc_204.Rev_N_sig_revision_hi) {
-       case 0x2:
-               deb_info("found a FlexCopII.\n");
-               fc->rev = FLEXCOP_II;
-               break;
-       case 0x3:
-               deb_info("found a FlexCopIIb.\n");
-               fc->rev = FLEXCOP_IIB;
-               break;
-       case 0x0:
-               deb_info("found a FlexCopIII.\n");
-               fc->rev = FLEXCOP_III;
-               break;
-       default:
-               err("unknown FlexCop Revision: %x. Please report this to "
-                               "linux-dvb@linuxtv.org.",
-                               v.misc_204.Rev_N_sig_revision_hi);
-               break;
-       }
-
-       if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
-               deb_info("this FlexCop has "
-                               "the additional 32 hardware pid filter.\n");
-       else
-               deb_info("this FlexCop has "
-                               "the 6 basic main hardware pid filter.\n");
-       /* bus parts have to decide if hw pid filtering is used or not. */
-}
-
-static const char *flexcop_revision_names[] = {
-       "Unknown chip",
-       "FlexCopII",
-       "FlexCopIIb",
-       "FlexCopIII",
-};
-
-static const char *flexcop_device_names[] = {
-       [FC_UNK]        = "Unknown device",
-       [FC_CABLE]      = "Cable2PC/CableStar 2 DVB-C",
-       [FC_AIR_DVBT]   = "Air2PC/AirStar 2 DVB-T",
-       [FC_AIR_ATSC1]  = "Air2PC/AirStar 2 ATSC 1st generation",
-       [FC_AIR_ATSC2]  = "Air2PC/AirStar 2 ATSC 2nd generation",
-       [FC_AIR_ATSC3]  = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
-       [FC_SKY_REV23]  = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
-       [FC_SKY_REV26]  = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
-       [FC_SKY_REV27]  = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
-       [FC_SKY_REV28]  = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
-};
-
-static const char *flexcop_bus_names[] = {
-       "USB",
-       "PCI",
-};
-
-void flexcop_device_name(struct flexcop_device *fc,
-               const char *prefix, const char *suffix)
-{
-       info("%s '%s' at the '%s' bus controlled by a '%s' %s",
-                       prefix, flexcop_device_names[fc->dev_type],
-                       flexcop_bus_names[fc->bus_type],
-                       flexcop_revision_names[fc->rev], suffix);
-}
-
-void flexcop_dump_reg(struct flexcop_device *fc,
-               flexcop_ibi_register reg, int num)
-{
-       flexcop_ibi_value v;
-       int i;
-       for (i = 0; i < num; i++) {
-               v = fc->read_ibi_reg(fc, reg+4*i);
-               deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
-       }
-       deb_rdump("\n");
-}
-EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
deleted file mode 100644 (file)
index 44f8fb5..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-pci.c - covers the PCI part including DMA transfers
- * see flexcop.c for copyright information
- */
-
-#define FC_LOG_PREFIX "flexcop-pci"
-#include "flexcop-common.h"
-
-static int enable_pid_filtering = 1;
-module_param(enable_pid_filtering, int, 0444);
-MODULE_PARM_DESC(enable_pid_filtering,
-       "enable hardware pid filtering: supported values: 0 (fullts), 1");
-
-static int irq_chk_intv = 100;
-module_param(irq_chk_intv, int, 0644);
-MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
-
-#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
-#define dprintk(level,args...) \
-       do { if ((debug & level)) printk(args); } while (0)
-#define DEBSTATUS ""
-#else
-#define dprintk(level,args...)
-#define DEBSTATUS " (debugging is not enabled)"
-#endif
-
-#define deb_info(args...) dprintk(0x01, args)
-#define deb_reg(args...) dprintk(0x02, args)
-#define deb_ts(args...) dprintk(0x04, args)
-#define deb_irq(args...) dprintk(0x08, args)
-#define deb_chk(args...) dprintk(0x10, args)
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,
-       "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
-       DEBSTATUS);
-
-#define DRIVER_VERSION "0.1"
-#define DRIVER_NAME "flexcop-pci"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
-
-struct flexcop_pci {
-       struct pci_dev *pdev;
-
-#define FC_PCI_INIT     0x01
-#define FC_PCI_DMA_INIT 0x02
-       int init_state;
-
-       void __iomem *io_mem;
-       u32 irq;
-       /* buffersize (at least for DMA1, need to be % 188 == 0,
-        * this logic is required */
-#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
-#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
-       struct flexcop_dma dma[2];
-
-       int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
-       u32 last_dma1_cur_pos;
-       /* position of the pointer last time the timer/packet irq occurred */
-       int count;
-       int count_prev;
-       int stream_problem;
-
-       spinlock_t irq_lock;
-       unsigned long last_irq;
-
-       struct delayed_work irq_check_work;
-       struct flexcop_device *fc_dev;
-};
-
-static int lastwreg, lastwval, lastrreg, lastrval;
-
-static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
-               flexcop_ibi_register r)
-{
-       struct flexcop_pci *fc_pci = fc->bus_specific;
-       flexcop_ibi_value v;
-       v.raw = readl(fc_pci->io_mem + r);
-
-       if (lastrreg != r || lastrval != v.raw) {
-               lastrreg = r; lastrval = v.raw;
-               deb_reg("new rd: %3x: %08x\n", r, v.raw);
-       }
-
-       return v;
-}
-
-static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
-               flexcop_ibi_register r, flexcop_ibi_value v)
-{
-       struct flexcop_pci *fc_pci = fc->bus_specific;
-
-       if (lastwreg != r || lastwval != v.raw) {
-               lastwreg = r; lastwval = v.raw;
-               deb_reg("new wr: %3x: %08x\n", r, v.raw);
-       }
-
-       writel(v.raw, fc_pci->io_mem + r);
-       return 0;
-}
-
-static void flexcop_pci_irq_check_work(struct work_struct *work)
-{
-       struct flexcop_pci *fc_pci =
-               container_of(work, struct flexcop_pci, irq_check_work.work);
-       struct flexcop_device *fc = fc_pci->fc_dev;
-
-       if (fc->feedcount) {
-
-               if (fc_pci->count == fc_pci->count_prev) {
-                       deb_chk("no IRQ since the last check\n");
-                       if (fc_pci->stream_problem++ == 3) {
-                               struct dvb_demux_feed *feed;
-                               deb_info("flexcop-pci: stream problem, resetting pid filter\n");
-
-                               spin_lock_irq(&fc->demux.lock);
-                               list_for_each_entry(feed, &fc->demux.feed_list,
-                                               list_head) {
-                                       flexcop_pid_feed_control(fc, feed, 0);
-                               }
-
-                               list_for_each_entry(feed, &fc->demux.feed_list,
-                                               list_head) {
-                                       flexcop_pid_feed_control(fc, feed, 1);
-                               }
-                               spin_unlock_irq(&fc->demux.lock);
-
-                               fc_pci->stream_problem = 0;
-                       }
-               } else {
-                       fc_pci->stream_problem = 0;
-                       fc_pci->count_prev = fc_pci->count;
-               }
-       }
-
-       schedule_delayed_work(&fc_pci->irq_check_work,
-                       msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-}
-
-/* When PID filtering is turned on, we use the timer IRQ, because small amounts
- * of data need to be passed to the user space instantly as well. When PID
- * filtering is turned off, we use the page-change-IRQ */
-static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
-{
-       struct flexcop_pci *fc_pci = dev_id;
-       struct flexcop_device *fc = fc_pci->fc_dev;
-       unsigned long flags;
-       flexcop_ibi_value v;
-       irqreturn_t ret = IRQ_HANDLED;
-
-       spin_lock_irqsave(&fc_pci->irq_lock, flags);
-       v = fc->read_ibi_reg(fc, irq_20c);
-
-       /* errors */
-       if (v.irq_20c.Data_receiver_error)
-               deb_chk("data receiver error\n");
-       if (v.irq_20c.Continuity_error_flag)
-               deb_chk("Contunuity error flag is set\n");
-       if (v.irq_20c.LLC_SNAP_FLAG_set)
-               deb_chk("LLC_SNAP_FLAG_set is set\n");
-       if (v.irq_20c.Transport_Error)
-               deb_chk("Transport error\n");
-
-       if ((fc_pci->count % 1000) == 0)
-               deb_chk("%d valid irq took place so far\n", fc_pci->count);
-
-       if (v.irq_20c.DMA1_IRQ_Status == 1) {
-               if (fc_pci->active_dma1_addr == 0)
-                       flexcop_pass_dmx_packets(fc_pci->fc_dev,
-                                       fc_pci->dma[0].cpu_addr0,
-                                       fc_pci->dma[0].size / 188);
-               else
-                       flexcop_pass_dmx_packets(fc_pci->fc_dev,
-                                       fc_pci->dma[0].cpu_addr1,
-                                       fc_pci->dma[0].size / 188);
-
-               deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
-               fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
-               /* for the timer IRQ we only can use buffer dmx feeding, because we don't have
-                * complete TS packets when reading from the DMA memory */
-       } else if (v.irq_20c.DMA1_Timer_Status == 1) {
-               dma_addr_t cur_addr =
-                       fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
-               u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
-
-               deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
-                       "last_cur_pos: %08x ",
-                               jiffies_to_usecs(jiffies - fc_pci->last_irq),
-                               v.raw, (unsigned long long)cur_addr, cur_pos,
-                               fc_pci->last_dma1_cur_pos);
-               fc_pci->last_irq = jiffies;
-
-               /* buffer end was reached, restarted from the beginning
-                * pass the data from last_cur_pos to the buffer end to the demux
-                */
-               if (cur_pos < fc_pci->last_dma1_cur_pos) {
-                       deb_irq(" end was reached: passing %d bytes ",
-                               (fc_pci->dma[0].size*2 - 1) -
-                               fc_pci->last_dma1_cur_pos);
-                       flexcop_pass_dmx_data(fc_pci->fc_dev,
-                               fc_pci->dma[0].cpu_addr0 +
-                                       fc_pci->last_dma1_cur_pos,
-                               (fc_pci->dma[0].size*2) -
-                                       fc_pci->last_dma1_cur_pos);
-                       fc_pci->last_dma1_cur_pos = 0;
-               }
-
-               if (cur_pos > fc_pci->last_dma1_cur_pos) {
-                       deb_irq(" passing %d bytes ",
-                               cur_pos - fc_pci->last_dma1_cur_pos);
-                       flexcop_pass_dmx_data(fc_pci->fc_dev,
-                               fc_pci->dma[0].cpu_addr0 +
-                                       fc_pci->last_dma1_cur_pos,
-                               cur_pos - fc_pci->last_dma1_cur_pos);
-               }
-               deb_irq("\n");
-
-               fc_pci->last_dma1_cur_pos = cur_pos;
-               fc_pci->count++;
-       } else {
-               deb_irq("isr for flexcop called, "
-                       "apparently without reason (%08x)\n", v.raw);
-               ret = IRQ_NONE;
-       }
-
-       spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
-       return ret;
-}
-
-static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
-{
-       struct flexcop_pci *fc_pci = fc->bus_specific;
-       if (onoff) {
-               flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
-               flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
-               flexcop_dma_config_timer(fc, FC_DMA_1, 0);
-               flexcop_dma_xfer_control(fc, FC_DMA_1,
-                               FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
-               deb_irq("DMA xfer enabled\n");
-
-               fc_pci->last_dma1_cur_pos = 0;
-               flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
-               deb_irq("IRQ enabled\n");
-               fc_pci->count_prev = fc_pci->count;
-       } else {
-               flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
-               deb_irq("IRQ disabled\n");
-
-               flexcop_dma_xfer_control(fc, FC_DMA_1,
-                        FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
-               deb_irq("DMA xfer disabled\n");
-       }
-       return 0;
-}
-
-static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
-{
-       int ret;
-       ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
-                       FC_DEFAULT_DMA1_BUFSIZE);
-       if (ret != 0)
-               return ret;
-
-       ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
-                       FC_DEFAULT_DMA2_BUFSIZE);
-       if (ret != 0) {
-               flexcop_dma_free(&fc_pci->dma[0]);
-               return ret;
-       }
-
-       flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
-                       FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
-       flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
-                       FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
-       fc_pci->init_state |= FC_PCI_DMA_INIT;
-       return ret;
-}
-
-static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
-{
-       if (fc_pci->init_state & FC_PCI_DMA_INIT) {
-               flexcop_dma_free(&fc_pci->dma[0]);
-               flexcop_dma_free(&fc_pci->dma[1]);
-       }
-       fc_pci->init_state &= ~FC_PCI_DMA_INIT;
-}
-
-static int flexcop_pci_init(struct flexcop_pci *fc_pci)
-{
-       int ret;
-
-       info("card revision %x", fc_pci->pdev->revision);
-
-       if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
-               return ret;
-       pci_set_master(fc_pci->pdev);
-
-       if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
-               goto err_pci_disable_device;
-
-       fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);
-
-       if (!fc_pci->io_mem) {
-               err("cannot map io memory\n");
-               ret = -EIO;
-               goto err_pci_release_regions;
-       }
-
-       pci_set_drvdata(fc_pci->pdev, fc_pci);
-       spin_lock_init(&fc_pci->irq_lock);
-       if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
-                                       IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
-               goto err_pci_iounmap;
-
-       fc_pci->init_state |= FC_PCI_INIT;
-       return ret;
-
-err_pci_iounmap:
-       pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
-       pci_set_drvdata(fc_pci->pdev, NULL);
-err_pci_release_regions:
-       pci_release_regions(fc_pci->pdev);
-err_pci_disable_device:
-       pci_disable_device(fc_pci->pdev);
-       return ret;
-}
-
-static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
-{
-       if (fc_pci->init_state & FC_PCI_INIT) {
-               free_irq(fc_pci->pdev->irq, fc_pci);
-               pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
-               pci_set_drvdata(fc_pci->pdev, NULL);
-               pci_release_regions(fc_pci->pdev);
-               pci_disable_device(fc_pci->pdev);
-       }
-       fc_pci->init_state &= ~FC_PCI_INIT;
-}
-
-static int flexcop_pci_probe(struct pci_dev *pdev,
-               const struct pci_device_id *ent)
-{
-       struct flexcop_device *fc;
-       struct flexcop_pci *fc_pci;
-       int ret = -ENOMEM;
-
-       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) {
-               err("out of memory\n");
-               return -ENOMEM;
-       }
-
-       /* general flexcop init */
-       fc_pci = fc->bus_specific;
-       fc_pci->fc_dev = fc;
-
-       fc->read_ibi_reg = flexcop_pci_read_ibi_reg;
-       fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
-       fc->i2c_request = flexcop_i2c_request;
-       fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
-       fc->stream_control = flexcop_pci_stream_control;
-
-       if (enable_pid_filtering)
-               info("will use the HW PID filter.");
-       else
-               info("will pass the complete TS to the demuxer.");
-
-       fc->pid_filtering = enable_pid_filtering;
-       fc->bus_type = FC_PCI;
-       fc->dev = &pdev->dev;
-       fc->owner = THIS_MODULE;
-
-       /* bus specific part */
-       fc_pci->pdev = pdev;
-       if ((ret = flexcop_pci_init(fc_pci)) != 0)
-               goto err_kfree;
-
-       /* init flexcop */
-       if ((ret = flexcop_device_initialize(fc)) != 0)
-               goto err_pci_exit;
-
-       /* init dma */
-       if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
-               goto err_fc_exit;
-
-       INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
-
-       if (irq_chk_intv > 0)
-               schedule_delayed_work(&fc_pci->irq_check_work,
-                               msecs_to_jiffies(irq_chk_intv < 100 ?
-                                       100 :
-                                       irq_chk_intv));
-       return ret;
-
-err_fc_exit:
-       flexcop_device_exit(fc);
-err_pci_exit:
-       flexcop_pci_exit(fc_pci);
-err_kfree:
-       flexcop_device_kfree(fc);
-       return ret;
-}
-
-/* in theory every _exit function should be called exactly two times,
- * here and in the bail-out-part of the _init-function
- */
-static void flexcop_pci_remove(struct pci_dev *pdev)
-{
-       struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
-
-       if (irq_chk_intv > 0)
-               cancel_delayed_work(&fc_pci->irq_check_work);
-
-       flexcop_pci_dma_exit(fc_pci);
-       flexcop_device_exit(fc_pci->fc_dev);
-       flexcop_pci_exit(fc_pci);
-       flexcop_device_kfree(fc_pci->fc_dev);
-}
-
-static struct pci_device_id flexcop_pci_tbl[] = {
-       { PCI_DEVICE(0x13d0, 0x2103) },
-       { },
-};
-
-MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
-
-static struct pci_driver flexcop_pci_driver = {
-       .name     = "b2c2_flexcop_pci",
-       .id_table = flexcop_pci_tbl,
-       .probe    = flexcop_pci_probe,
-       .remove   = flexcop_pci_remove,
-};
-
-static int __init flexcop_pci_module_init(void)
-{
-       return pci_register_driver(&flexcop_pci_driver);
-}
-
-static void __exit flexcop_pci_module_exit(void)
-{
-       pci_unregister_driver(&flexcop_pci_driver);
-}
-
-module_init(flexcop_pci_module_init);
-module_exit(flexcop_pci_module_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_NAME);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
deleted file mode 100644 (file)
index dc4528d..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
- * see flexcop.c for copyright information
- */
-#ifndef __FLEXCOP_REG_H__
-#define __FLEXCOP_REG_H__
-
-typedef enum {
-       FLEXCOP_UNK = 0,
-       FLEXCOP_II,
-       FLEXCOP_IIB,
-       FLEXCOP_III,
-} flexcop_revision_t;
-
-typedef enum {
-       FC_UNK = 0,
-       FC_CABLE,
-       FC_AIR_DVBT,
-       FC_AIR_ATSC1,
-       FC_AIR_ATSC2,
-       FC_AIR_ATSC3,
-       FC_SKY_REV23,
-       FC_SKY_REV26,
-       FC_SKY_REV27,
-       FC_SKY_REV28,
-} flexcop_device_type_t;
-
-typedef enum {
-       FC_USB = 0,
-       FC_PCI,
-} flexcop_bus_t;
-
-/* FlexCop IBI Registers */
-#if defined(__LITTLE_ENDIAN)
-#include "flexcop_ibi_value_le.h"
-#else
-#if defined(__BIG_ENDIAN)
-#include "flexcop_ibi_value_be.h"
-#else
-#error no endian defined
-#endif
-#endif
-
-#define fc_data_Tag_ID_DVB  0x3e
-#define fc_data_Tag_ID_ATSC 0x3f
-#define fc_data_Tag_ID_IDSB 0x8b
-
-#define fc_key_code_default 0x1
-#define fc_key_code_even    0x2
-#define fc_key_code_odd     0x3
-
-extern flexcop_ibi_value ibi_zero;
-
-typedef enum {
-       FC_I2C_PORT_DEMOD  = 1,
-       FC_I2C_PORT_EEPROM = 2,
-       FC_I2C_PORT_TUNER  = 3,
-} flexcop_i2c_port_t;
-
-typedef enum {
-       FC_WRITE = 0,
-       FC_READ  = 1,
-} flexcop_access_op_t;
-
-typedef enum {
-       FC_SRAM_DEST_NET   = 1,
-       FC_SRAM_DEST_CAI   = 2,
-       FC_SRAM_DEST_CAO   = 4,
-       FC_SRAM_DEST_MEDIA = 8
-} flexcop_sram_dest_t;
-
-typedef enum {
-       FC_SRAM_DEST_TARGET_WAN_USB = 0,
-       FC_SRAM_DEST_TARGET_DMA1    = 1,
-       FC_SRAM_DEST_TARGET_DMA2    = 2,
-       FC_SRAM_DEST_TARGET_FC3_CA  = 3
-} flexcop_sram_dest_target_t;
-
-typedef enum {
-       FC_SRAM_2_32KB  = 0, /*  64KB */
-       FC_SRAM_1_32KB  = 1, /*  32KB - default fow FCII */
-       FC_SRAM_1_128KB = 2, /* 128KB */
-       FC_SRAM_1_48KB  = 3, /*  48KB - default for FCIII */
-} flexcop_sram_type_t;
-
-typedef enum {
-       FC_WAN_SPEED_4MBITS  = 0,
-       FC_WAN_SPEED_8MBITS  = 1,
-       FC_WAN_SPEED_12MBITS = 2,
-       FC_WAN_SPEED_16MBITS = 3,
-} flexcop_wan_speed_t;
-
-typedef enum {
-       FC_DMA_1 = 1,
-       FC_DMA_2 = 2,
-} flexcop_dma_index_t;
-
-typedef enum {
-       FC_DMA_SUBADDR_0 = 1,
-       FC_DMA_SUBADDR_1 = 2,
-} flexcop_dma_addr_index_t;
-
-/* names of the particular registers */
-typedef enum {
-       dma1_000            = 0x000,
-       dma1_004            = 0x004,
-       dma1_008            = 0x008,
-       dma1_00c            = 0x00c,
-       dma2_010            = 0x010,
-       dma2_014            = 0x014,
-       dma2_018            = 0x018,
-       dma2_01c            = 0x01c,
-
-       tw_sm_c_100         = 0x100,
-       tw_sm_c_104         = 0x104,
-       tw_sm_c_108         = 0x108,
-       tw_sm_c_10c         = 0x10c,
-       tw_sm_c_110         = 0x110,
-
-       lnb_switch_freq_200 = 0x200,
-       misc_204            = 0x204,
-       ctrl_208            = 0x208,
-       irq_20c             = 0x20c,
-       sw_reset_210        = 0x210,
-       misc_214            = 0x214,
-       mbox_v8_to_host_218 = 0x218,
-       mbox_host_to_v8_21c = 0x21c,
-
-       pid_filter_300      = 0x300,
-       pid_filter_304      = 0x304,
-       pid_filter_308      = 0x308,
-       pid_filter_30c      = 0x30c,
-       index_reg_310       = 0x310,
-       pid_n_reg_314       = 0x314,
-       mac_low_reg_318     = 0x318,
-       mac_high_reg_31c    = 0x31c,
-
-       data_tag_400        = 0x400,
-       card_id_408         = 0x408,
-       card_id_40c         = 0x40c,
-       mac_address_418     = 0x418,
-       mac_address_41c     = 0x41c,
-
-       ci_600              = 0x600,
-       pi_604              = 0x604,
-       pi_608              = 0x608,
-       dvb_reg_60c         = 0x60c,
-
-       sram_ctrl_reg_700   = 0x700,
-       net_buf_reg_704     = 0x704,
-       cai_buf_reg_708     = 0x708,
-       cao_buf_reg_70c     = 0x70c,
-       media_buf_reg_710   = 0x710,
-       sram_dest_reg_714   = 0x714,
-       net_buf_reg_718     = 0x718,
-       wan_ctrl_reg_71c    = 0x71c,
-} flexcop_ibi_register;
-
-#define flexcop_set_ibi_value(reg,attr,val) { \
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
-       v.reg.attr = val; \
-       fc->write_ibi_reg(fc,reg,v); \
-}
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c
deleted file mode 100644 (file)
index f2199e4..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-sram.c - functions for controlling the SRAM
- * see flexcop.c for copyright information
- */
-#include "flexcop.h"
-
-static void flexcop_sram_set_chip(struct flexcop_device *fc,
-               flexcop_sram_type_t type)
-{
-       flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
-}
-
-int flexcop_sram_init(struct flexcop_device *fc)
-{
-       switch (fc->rev) {
-       case FLEXCOP_II:
-       case FLEXCOP_IIB:
-               flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
-               break;
-       case FLEXCOP_III:
-               flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
-                flexcop_sram_dest_target_t target)
-{
-       flexcop_ibi_value v;
-       v = fc->read_ibi_reg(fc, sram_dest_reg_714);
-
-       if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
-               err("SRAM destination target to available on FlexCopII(b)\n");
-               return -EINVAL;
-       }
-       deb_sram("sram dest: %x target: %x\n", dest, target);
-
-       if (dest & FC_SRAM_DEST_NET)
-               v.sram_dest_reg_714.NET_Dest = target;
-       if (dest & FC_SRAM_DEST_CAI)
-               v.sram_dest_reg_714.CAI_Dest = target;
-       if (dest & FC_SRAM_DEST_CAO)
-               v.sram_dest_reg_714.CAO_Dest = target;
-       if (dest & FC_SRAM_DEST_MEDIA)
-               v.sram_dest_reg_714.MEDIA_Dest = target;
-
-       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
-       udelay(1000); /* TODO delay really necessary */
-
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_sram_set_dest);
-
-void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
-{
-       flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
-}
-EXPORT_SYMBOL(flexcop_wan_set_speed);
-
-void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
-       v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
-       v.sram_dest_reg_714.ctrl_sramdma = sramdma;
-       v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
-       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
-}
-EXPORT_SYMBOL(flexcop_sram_ctrl);
-
-#if 0
-static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
-       int i, retries;
-       u32 command;
-
-       for (i = 0; i < len; i++) {
-               command = bank | addr | 0x04000000 | (*buf << 0x10);
-
-               retries = 2;
-
-               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-                       mdelay(1);
-                       retries--;
-               };
-
-               if (retries == 0)
-                       printk("%s: SRAM timeout\n", __func__);
-
-               write_reg_dw(adapter, 0x700, command);
-
-               buf++;
-               addr++;
-       }
-}
-
-static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
-       int i, retries;
-       u32 command, value;
-
-       for (i = 0; i < len; i++) {
-               command = bank | addr | 0x04008000;
-
-               retries = 10000;
-
-               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-                       mdelay(1);
-                       retries--;
-               };
-
-               if (retries == 0)
-                       printk("%s: SRAM timeout\n", __func__);
-
-               write_reg_dw(adapter, 0x700, command);
-
-               retries = 10000;
-
-               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-                       mdelay(1);
-                       retries--;
-               };
-
-               if (retries == 0)
-                       printk("%s: SRAM timeout\n", __func__);
-
-               value = read_reg_dw(adapter, 0x700) >> 0x10;
-
-               *buf = (value & 0xff);
-
-               addr++;
-               buf++;
-       }
-}
-
-static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
-       u32 bank;
-
-       bank = 0;
-
-       if (adapter->dw_sram_type == 0x20000) {
-               bank = (addr & 0x18000) << 0x0d;
-       }
-
-       if (adapter->dw_sram_type == 0x00000) {
-               if ((addr >> 0x0f) == 0)
-                       bank = 0x20000000;
-               else
-                       bank = 0x10000000;
-       }
-       flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
-       u32 bank;
-       bank = 0;
-
-       if (adapter->dw_sram_type == 0x20000) {
-               bank = (addr & 0x18000) << 0x0d;
-       }
-
-       if (adapter->dw_sram_type == 0x00000) {
-               if ((addr >> 0x0f) == 0)
-                       bank = 0x20000000;
-               else
-                       bank = 0x10000000;
-       }
-       flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
-       u32 length;
-       while (len != 0) {
-               length = len;
-               /* check if the address range belongs to the same
-                * 32K memory chip. If not, the data is read
-                * from one chip at a time */
-               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
-                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
-               }
-
-               sram_read_chunk(adapter, addr, buf, length);
-               addr = addr + length;
-               buf = buf + length;
-               len = len - length;
-       }
-}
-
-static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
-       u32 length;
-       while (len != 0) {
-               length = len;
-
-               /* check if the address range belongs to the same
-                * 32K memory chip. If not, the data is
-                * written to one chip at a time */
-               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
-                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
-               }
-
-               sram_write_chunk(adapter, addr, buf, length);
-               addr = addr + length;
-               buf = buf + length;
-               len = len - length;
-       }
-}
-
-static void sram_set_size(struct adapter *adapter, u32 mask)
-{
-       write_reg_dw(adapter, 0x71c,
-                       (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
-}
-
-static void sram_init(struct adapter *adapter)
-{
-       u32 tmp;
-       tmp = read_reg_dw(adapter, 0x71c);
-       write_reg_dw(adapter, 0x71c, 1);
-
-       if (read_reg_dw(adapter, 0x71c) != 0) {
-               write_reg_dw(adapter, 0x71c, tmp);
-               adapter->dw_sram_type = tmp & 0x30000;
-               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-       } else {
-               adapter->dw_sram_type = 0x10000;
-               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-       }
-}
-
-static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
-{
-       u8 tmp1, tmp2;
-       dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
-
-       sram_set_size(adapter, mask);
-       sram_init(adapter);
-
-       tmp2 = 0xa5;
-       tmp1 = 0x4f;
-
-       sram_write(adapter, addr, &tmp2, 1);
-       sram_write(adapter, addr + 4, &tmp1, 1);
-
-       tmp2 = 0;
-       mdelay(20);
-
-       sram_read(adapter, addr, &tmp2, 1);
-       sram_read(adapter, addr, &tmp2, 1);
-
-       dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
-
-       if (tmp2 != 0xa5)
-               return 0;
-
-       tmp2 = 0x5a;
-       tmp1 = 0xf4;
-
-       sram_write(adapter, addr, &tmp2, 1);
-       sram_write(adapter, addr + 4, &tmp1, 1);
-
-       tmp2 = 0;
-       mdelay(20);
-
-       sram_read(adapter, addr, &tmp2, 1);
-       sram_read(adapter, addr, &tmp2, 1);
-
-       dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
-
-       if (tmp2 != 0x5a)
-               return 0;
-       return 1;
-}
-
-static u32 sram_length(struct adapter *adapter)
-{
-       if (adapter->dw_sram_type == 0x10000)
-               return 32768; /* 32K */
-       if (adapter->dw_sram_type == 0x00000)
-               return 65536; /* 64K */
-       if (adapter->dw_sram_type == 0x20000)
-               return 131072; /* 128K */
-       return 32768; /* 32K */
-}
-
-/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
-   - for 128K there are 4x32K chips at bank 0,1,2,3.
-   - for  64K there are 2x32K chips at bank 1,2.
-   - for  32K there is one 32K chip at bank 0.
-
-   FlexCop works only with one bank at a time. The bank is selected
-   by bits 28-29 of the 0x700 register.
-
-   bank 0 covers addresses 0x00000-0x07fff
-   bank 1 covers addresses 0x08000-0x0ffff
-   bank 2 covers addresses 0x10000-0x17fff
-   bank 3 covers addresses 0x18000-0x1ffff */
-
-static int flexcop_sram_detect(struct flexcop_device *fc)
-{
-       flexcop_ibi_value r208, r71c_0, vr71c_1;
-       r208 = fc->read_ibi_reg(fc, ctrl_208);
-       fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
-
-       r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
-       write_reg_dw(adapter, 0x71c, 1);
-       tmp3 = read_reg_dw(adapter, 0x71c);
-       dprintk("%s: tmp3 = %x\n", __func__, tmp3);
-       write_reg_dw(adapter, 0x71c, tmp2);
-
-       // check for internal SRAM ???
-       tmp3--;
-       if (tmp3 != 0) {
-               sram_set_size(adapter, 0x10000);
-               sram_init(adapter);
-               write_reg_dw(adapter, 0x208, tmp);
-               dprintk("%s: sram size = 32K\n", __func__);
-               return 32;
-       }
-
-       if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
-               sram_set_size(adapter, 0x20000);
-               sram_init(adapter);
-               write_reg_dw(adapter, 0x208, tmp);
-               dprintk("%s: sram size = 128K\n", __func__);
-               return 128;
-       }
-
-       if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
-               sram_set_size(adapter, 0x00000);
-               sram_init(adapter);
-               write_reg_dw(adapter, 0x208, tmp);
-               dprintk("%s: sram size = 64K\n", __func__);
-               return 64;
-       }
-
-       if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
-               sram_set_size(adapter, 0x10000);
-               sram_init(adapter);
-               write_reg_dw(adapter, 0x208, tmp);
-               dprintk("%s: sram size = 32K\n", __func__);
-               return 32;
-       }
-
-       sram_set_size(adapter, 0x10000);
-       sram_init(adapter);
-       write_reg_dw(adapter, 0x208, tmp);
-       dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
-       return 0;
-}
-
-static void sll_detect_sram_size(struct adapter *adapter)
-{
-       sram_detect_for_flex2(adapter);
-}
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
deleted file mode 100644 (file)
index 8b6275f..0000000
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-usb.c - covers the USB part
- * see flexcop.c for copyright information
- */
-#define FC_LOG_PREFIX "flexcop_usb"
-#include "flexcop-usb.h"
-#include "flexcop-common.h"
-
-/* Version information */
-#define DRIVER_VERSION "0.1"
-#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
-
-/* debug */
-#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
-#define dprintk(level,args...) \
-       do { if ((debug & level)) printk(args); } while (0)
-
-#define debug_dump(b, l, method) do {\
-       int i; \
-       for (i = 0; i < l; i++) \
-               method("%02x ", b[i]); \
-       method("\n"); \
-} while (0)
-
-#define DEBSTATUS ""
-#else
-#define dprintk(level, args...)
-#define debug_dump(b, l, method)
-#define DEBSTATUS " (debugging is not enabled)"
-#endif
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
-               "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
-#undef DEBSTATUS
-
-#define deb_info(args...) dprintk(0x01, args)
-#define deb_ts(args...) dprintk(0x02, args)
-#define deb_ctrl(args...) dprintk(0x04, args)
-#define deb_i2c(args...) dprintk(0x08, args)
-#define deb_v8(args...) dprintk(0x10, args)
-
-/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
- * in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
- *                  in general: 0000 0HHH 000L LL00
- * IBI ADDRESS FORMAT:                    RHHH BLLL
- *
- * where R is the read(1)/write(0) bit, B is the busy bit
- * and HHH and LLL are the two sets of three bits from the PCI address.
- */
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
-       (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
-       (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
-
-/*
- * DKT 020228
- * - forget about this VENDOR_BUFFER_SIZE, read and write register
- *   deal with DWORD or 4 bytes, that should be should from now on
- * - from now on, we don't support anything older than firm 1.00
- *   I eliminated the write register as a 2 trip of writing hi word and lo word
- *   and force this to write only 4 bytes at a time.
- *   NOTE: this should work with all the firmware from 1.00 and newer
- */
-static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read)
-{
-       struct flexcop_usb *fc_usb = fc->bus_specific;
-       u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
-       u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
-       u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
-               (read ? 0x80 : 0);
-
-       int len = usb_control_msg(fc_usb->udev,
-                       read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
-                       request,
-                       request_type, /* 0xc0 read or 0x40 write */
-                       wAddress,
-                       0,
-                       val,
-                       sizeof(u32),
-                       B2C2_WAIT_FOR_OPERATION_RDW * HZ);
-
-       if (len != sizeof(u32)) {
-               err("error while %s dword from %d (%d).", read ? "reading" :
-                               "writing", wAddress, wRegOffsPCI);
-               return -EIO;
-       }
-       return 0;
-}
-/*
- * DKT 010817 - add support for V8 memory read/write and flash update
- */
-static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
-               flexcop_usb_request_t req, u8 page, u16 wAddress,
-               u8 *pbBuffer, u32 buflen)
-{
-       u8 request_type = USB_TYPE_VENDOR;
-       u16 wIndex;
-       int nWaitTime, pipe, len;
-       wIndex = page << 8;
-
-       switch (req) {
-       case B2C2_USB_READ_V8_MEM:
-               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
-               request_type |= USB_DIR_IN;
-               pipe = B2C2_USB_CTRL_PIPE_IN;
-               break;
-       case B2C2_USB_WRITE_V8_MEM:
-               wIndex |= pbBuffer[0];
-               request_type |= USB_DIR_OUT;
-               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-               pipe = B2C2_USB_CTRL_PIPE_OUT;
-               break;
-       case B2C2_USB_FLASH_BLOCK:
-               request_type |= USB_DIR_OUT;
-               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-               pipe = B2C2_USB_CTRL_PIPE_OUT;
-               break;
-       default:
-               deb_info("unsupported request for v8_mem_req %x.\n", req);
-               return -EINVAL;
-       }
-       deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
-                       wAddress, wIndex, buflen);
-
-       len = usb_control_msg(fc_usb->udev, pipe,
-                       req,
-                       request_type,
-                       wAddress,
-                       wIndex,
-                       pbBuffer,
-                       buflen,
-                       nWaitTime * HZ);
-
-       debug_dump(pbBuffer, len, deb_v8);
-       return len == buflen ? 0 : -EIO;
-}
-
-#define bytes_left_to_read_on_page(paddr,buflen) \
-       ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
-        ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
-
-static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
-               flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
-               u32 addr, int extended, u8 *buf, u32 len)
-{
-       int i,ret = 0;
-       u16 wMax;
-       u32 pagechunk = 0;
-
-       switch(req) {
-       case B2C2_USB_READ_V8_MEM:
-               wMax = USB_MEM_READ_MAX;
-               break;
-       case B2C2_USB_WRITE_V8_MEM:
-               wMax = USB_MEM_WRITE_MAX;
-               break;
-       case B2C2_USB_FLASH_BLOCK:
-               wMax = USB_FLASH_MAX;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
-       for (i = 0; i < len;) {
-               pagechunk =
-                       wMax < bytes_left_to_read_on_page(addr, len) ?
-                               wMax :
-                               bytes_left_to_read_on_page(addr, len);
-               deb_info("%x\n",
-                       (addr & V8_MEMORY_PAGE_MASK) |
-                               (V8_MEMORY_EXTENDED*extended));
-
-               ret = flexcop_usb_v8_memory_req(fc_usb, req,
-                       page_start + (addr / V8_MEMORY_PAGE_SIZE),
-                       (addr & V8_MEMORY_PAGE_MASK) |
-                               (V8_MEMORY_EXTENDED*extended),
-                       &buf[i], pagechunk);
-
-               if (ret < 0)
-                       return ret;
-               addr += pagechunk;
-               len -= pagechunk;
-       }
-       return 0;
-}
-
-static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
-{
-       return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
-               V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
-               fc->dvb_adapter.proposed_mac, 6);
-}
-
-#if 0
-static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
-               flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
-               u16 buflen, u8 *pvBuffer)
-{
-       u16 wValue;
-       u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-       int nWaitTime = 2,
-           pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
-       wValue = (func << 8) | extra;
-
-       len = usb_control_msg(fc_usb->udev,pipe,
-                       B2C2_USB_UTILITY,
-                       request_type,
-                       wValue,
-                       wIndex,
-                       pvBuffer,
-                       buflen,
-                       nWaitTime * HZ);
-       return len == buflen ? 0 : -EIO;
-}
-#endif
-
-/* usb i2c stuff */
-static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
-               flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
-               u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
-{
-       struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
-       u16 wValue, wIndex;
-       int nWaitTime,pipe,len;
-       u8 request_type = USB_TYPE_VENDOR;
-
-       switch (func) {
-       case USB_FUNC_I2C_WRITE:
-       case USB_FUNC_I2C_MULTIWRITE:
-       case USB_FUNC_I2C_REPEATWRITE:
-               /* DKT 020208 - add this to support special case of DiSEqC */
-       case USB_FUNC_I2C_CHECKWRITE:
-               pipe = B2C2_USB_CTRL_PIPE_OUT;
-               nWaitTime = 2;
-               request_type |= USB_DIR_OUT;
-               break;
-       case USB_FUNC_I2C_READ:
-       case USB_FUNC_I2C_REPEATREAD:
-               pipe = B2C2_USB_CTRL_PIPE_IN;
-               nWaitTime = 2;
-               request_type |= USB_DIR_IN;
-               break;
-       default:
-               deb_info("unsupported function for i2c_req %x\n", func);
-               return -EINVAL;
-       }
-       wValue = (func << 8) | (i2c->port << 4);
-       wIndex = (chipaddr << 8 ) | addr;
-
-       deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
-                       func, request_type, req,
-                       wValue & 0xff, wValue >> 8,
-                       wIndex & 0xff, wIndex >> 8);
-
-       len = usb_control_msg(fc_usb->udev,pipe,
-                       req,
-                       request_type,
-                       wValue,
-                       wIndex,
-                       buf,
-                       buflen,
-                       nWaitTime * HZ);
-       return len == buflen ? 0 : -EREMOTEIO;
-}
-
-/* actual bus specific access functions,
-   make sure prototype are/will be equal to pci */
-static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
-       flexcop_ibi_register reg)
-{
-       flexcop_ibi_value val;
-       val.raw = 0;
-       flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
-       return val;
-}
-
-static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
-               flexcop_ibi_register reg, flexcop_ibi_value val)
-{
-       return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
-}
-
-static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
-               flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
-{
-       if (op == FC_READ)
-               return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
-                               USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
-       else
-               return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
-                               USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
-}
-
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
-       u8 *buffer, int buffer_length)
-{
-       u8 *b;
-       int l;
-
-       deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
-               fc_usb->tmp_buffer_length, buffer_length);
-
-       if (fc_usb->tmp_buffer_length > 0) {
-               memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
-                               buffer_length);
-               fc_usb->tmp_buffer_length += buffer_length;
-               b = fc_usb->tmp_buffer;
-               l = fc_usb->tmp_buffer_length;
-       } else {
-               b=buffer;
-               l=buffer_length;
-       }
-
-       while (l >= 190) {
-               if (*b == 0xff) {
-                       switch (*(b+1) & 0x03) {
-                       case 0x01: /* media packet */
-                               if (*(b+2) == 0x47)
-                                       flexcop_pass_dmx_packets(
-                                                       fc_usb->fc_dev, b+2, 1);
-                               else
-                                       deb_ts("not ts packet %*ph\n", 4, b+2);
-                               b += 190;
-                               l -= 190;
-                               break;
-                       default:
-                               deb_ts("wrong packet type\n");
-                               l = 0;
-                               break;
-                       }
-               } else {
-                       deb_ts("wrong header\n");
-                       l = 0;
-               }
-       }
-
-       if (l>0)
-               memcpy(fc_usb->tmp_buffer, b, l);
-       fc_usb->tmp_buffer_length = l;
-}
-
-static void flexcop_usb_urb_complete(struct urb *urb)
-{
-       struct flexcop_usb *fc_usb = urb->context;
-       int i;
-
-       if (urb->actual_length > 0)
-               deb_ts("urb completed, bufsize: %d actlen; %d\n",
-                       urb->transfer_buffer_length, urb->actual_length);
-
-       for (i = 0; i < urb->number_of_packets; i++) {
-               if (urb->iso_frame_desc[i].status < 0) {
-                       err("iso frame descriptor %d has an error: %d\n", i,
-                               urb->iso_frame_desc[i].status);
-               } else
-                       if (urb->iso_frame_desc[i].actual_length > 0) {
-                               deb_ts("passed %d bytes to the demux\n",
-                                       urb->iso_frame_desc[i].actual_length);
-
-                               flexcop_usb_process_frame(fc_usb,
-                                       urb->transfer_buffer +
-                                               urb->iso_frame_desc[i].offset,
-                                       urb->iso_frame_desc[i].actual_length);
-                       }
-               urb->iso_frame_desc[i].status = 0;
-               urb->iso_frame_desc[i].actual_length = 0;
-       }
-       usb_submit_urb(urb,GFP_ATOMIC);
-}
-
-static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff)
-{
-       /* submit/kill iso packets */
-       return 0;
-}
-
-static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
-{
-       int i;
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
-               if (fc_usb->iso_urb[i] != NULL) {
-                       deb_ts("unlinking/killing urb no. %d\n",i);
-                       usb_kill_urb(fc_usb->iso_urb[i]);
-                       usb_free_urb(fc_usb->iso_urb[i]);
-               }
-
-       if (fc_usb->iso_buffer != NULL)
-               pci_free_consistent(NULL,
-                       fc_usb->buffer_size, fc_usb->iso_buffer,
-                       fc_usb->dma_addr);
-}
-
-static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
-{
-       u16 frame_size = le16_to_cpu(
-               fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
-       int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
-               frame_size, i, j, ret;
-       int buffer_offset = 0;
-
-       deb_ts("creating %d iso-urbs with %d frames "
-                       "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
-                       B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
-
-       fc_usb->iso_buffer = pci_alloc_consistent(NULL,
-                       bufsize, &fc_usb->dma_addr);
-       if (fc_usb->iso_buffer == NULL)
-               return -ENOMEM;
-
-       memset(fc_usb->iso_buffer, 0, bufsize);
-       fc_usb->buffer_size = bufsize;
-
-       /* creating iso urbs */
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
-               fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
-                       GFP_ATOMIC);
-               if (fc_usb->iso_urb[i] == NULL) {
-                       ret = -ENOMEM;
-                       goto urb_error;
-               }
-       }
-
-       /* initialising and submitting iso urbs */
-       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
-               int frame_offset = 0;
-               struct urb *urb = fc_usb->iso_urb[i];
-               deb_ts("initializing and submitting urb no. %d "
-                       "(buf_offset: %d).\n", i, buffer_offset);
-
-               urb->dev = fc_usb->udev;
-               urb->context = fc_usb;
-               urb->complete = flexcop_usb_urb_complete;
-               urb->pipe = B2C2_USB_DATA_PIPE;
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->interval = 1;
-               urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
-               urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
-               urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset;
-
-               buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
-               for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
-                       deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
-                                       i, j, frame_offset);
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = frame_size;
-                       frame_offset += frame_size;
-               }
-
-               if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
-                       err("submitting urb %d failed with %d.", i, ret);
-                       goto urb_error;
-               }
-               deb_ts("submitted urb no. %d.\n",i);
-       }
-
-       /* SRAM */
-       flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
-                       FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
-                       FC_SRAM_DEST_TARGET_WAN_USB);
-       flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
-       flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
-       return 0;
-
-urb_error:
-       flexcop_usb_transfer_exit(fc_usb);
-       return ret;
-}
-
-static int flexcop_usb_init(struct flexcop_usb *fc_usb)
-{
-       /* use the alternate setting with the larges buffer */
-       usb_set_interface(fc_usb->udev,0,1);
-       switch (fc_usb->udev->speed) {
-       case USB_SPEED_LOW:
-               err("cannot handle USB speed because it is too slow.");
-               return -ENODEV;
-               break;
-       case USB_SPEED_FULL:
-               info("running at FULL speed.");
-               break;
-       case USB_SPEED_HIGH:
-               info("running at HIGH speed.");
-               break;
-       case USB_SPEED_UNKNOWN: /* fall through */
-       default:
-               err("cannot handle USB speed because it is unknown.");
-               return -ENODEV;
-       }
-       usb_set_intfdata(fc_usb->uintf, fc_usb);
-       return 0;
-}
-
-static void flexcop_usb_exit(struct flexcop_usb *fc_usb)
-{
-       usb_set_intfdata(fc_usb->uintf, NULL);
-}
-
-static int flexcop_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct flexcop_usb *fc_usb = NULL;
-       struct flexcop_device *fc = NULL;
-       int ret;
-
-       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
-               err("out of memory\n");
-               return -ENOMEM;
-       }
-
-       /* general flexcop init */
-       fc_usb = fc->bus_specific;
-       fc_usb->fc_dev = fc;
-
-       fc->read_ibi_reg  = flexcop_usb_read_ibi_reg;
-       fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
-       fc->i2c_request = flexcop_usb_i2c_request;
-       fc->get_mac_addr = flexcop_usb_get_mac_addr;
-
-       fc->stream_control = flexcop_usb_stream_control;
-
-       fc->pid_filtering = 1;
-       fc->bus_type = FC_USB;
-
-       fc->dev = &udev->dev;
-       fc->owner = THIS_MODULE;
-
-       /* bus specific part */
-       fc_usb->udev = udev;
-       fc_usb->uintf = intf;
-       if ((ret = flexcop_usb_init(fc_usb)) != 0)
-               goto err_kfree;
-
-       /* init flexcop */
-       if ((ret = flexcop_device_initialize(fc)) != 0)
-               goto err_usb_exit;
-
-       /* xfer init */
-       if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
-               goto err_fc_exit;
-
-       info("%s successfully initialized and connected.", DRIVER_NAME);
-       return 0;
-
-err_fc_exit:
-       flexcop_device_exit(fc);
-err_usb_exit:
-       flexcop_usb_exit(fc_usb);
-err_kfree:
-       flexcop_device_kfree(fc);
-       return ret;
-}
-
-static void flexcop_usb_disconnect(struct usb_interface *intf)
-{
-       struct flexcop_usb *fc_usb = usb_get_intfdata(intf);
-       flexcop_usb_transfer_exit(fc_usb);
-       flexcop_device_exit(fc_usb->fc_dev);
-       flexcop_usb_exit(fc_usb);
-       flexcop_device_kfree(fc_usb->fc_dev);
-       info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
-}
-
-static struct usb_device_id flexcop_usb_table [] = {
-       { USB_DEVICE(0x0af7, 0x0101) },
-       { }
-};
-MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver flexcop_usb_driver = {
-       .name           = "b2c2_flexcop_usb",
-       .probe          = flexcop_usb_probe,
-       .disconnect = flexcop_usb_disconnect,
-       .id_table       = flexcop_usb_table,
-};
-
-module_usb_driver(flexcop_usb_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_NAME);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h
deleted file mode 100644 (file)
index 92529a9..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop-usb.h - header file for the USB part
- * see flexcop.c for copyright information
- */
-#ifndef __FLEXCOP_USB_H_INCLUDED__
-#define __FLEXCOP_USB_H_INCLUDED__
-
-#include <linux/usb.h>
-
-/* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO 4
-#define B2C2_USB_NUM_ISO_URB 4
-
-#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
-#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
-#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
-
-struct flexcop_usb {
-       struct usb_device *udev;
-       struct usb_interface *uintf;
-
-       u8 *iso_buffer;
-       int buffer_size;
-       dma_addr_t dma_addr;
-
-       struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
-       struct flexcop_device *fc_dev;
-
-       u8 tmp_buffer[1023+190];
-       int tmp_buffer_length;
-};
-
-#if 0
-/* request types TODO What is its use?*/
-typedef enum {
-
-} flexcop_usb_request_type_t;
-#endif
-
-/* request */
-typedef enum {
-       B2C2_USB_WRITE_V8_MEM = 0x04,
-       B2C2_USB_READ_V8_MEM  = 0x05,
-       B2C2_USB_READ_REG     = 0x08,
-       B2C2_USB_WRITE_REG    = 0x0A,
-       B2C2_USB_WRITEREGHI   = 0x0B,
-       B2C2_USB_FLASH_BLOCK  = 0x10,
-       B2C2_USB_I2C_REQUEST  = 0x11,
-       B2C2_USB_UTILITY      = 0x12,
-} flexcop_usb_request_t;
-
-/* function definition for I2C_REQUEST */
-typedef enum {
-       USB_FUNC_I2C_WRITE       = 0x01,
-       USB_FUNC_I2C_MULTIWRITE  = 0x02,
-       USB_FUNC_I2C_READ        = 0x03,
-       USB_FUNC_I2C_REPEATWRITE = 0x04,
-       USB_FUNC_GET_DESCRIPTOR  = 0x05,
-       USB_FUNC_I2C_REPEATREAD  = 0x06,
-       /* DKT 020208 - add this to support special case of DiSEqC */
-       USB_FUNC_I2C_CHECKWRITE  = 0x07,
-       USB_FUNC_I2C_CHECKRESULT = 0x08,
-} flexcop_usb_i2c_function_t;
-
-/* function definition for UTILITY request 0x12
- * DKT 020304 - new utility function */
-typedef enum {
-       UTILITY_SET_FILTER          = 0x01,
-       UTILITY_DATA_ENABLE         = 0x02,
-       UTILITY_FLEX_MULTIWRITE     = 0x03,
-       UTILITY_SET_BUFFER_SIZE     = 0x04,
-       UTILITY_FLEX_OPERATOR       = 0x05,
-       UTILITY_FLEX_RESET300_START = 0x06,
-       UTILITY_FLEX_RESET300_STOP  = 0x07,
-       UTILITY_FLEX_RESET300       = 0x08,
-       UTILITY_SET_ISO_SIZE        = 0x09,
-       UTILITY_DATA_RESET          = 0x0A,
-       UTILITY_GET_DATA_STATUS     = 0x10,
-       UTILITY_GET_V8_REG          = 0x11,
-       /* DKT 020326 - add function for v1.14 */
-       UTILITY_SRAM_WRITE          = 0x12,
-       UTILITY_SRAM_READ           = 0x13,
-       UTILITY_SRAM_TESTFILL       = 0x14,
-       UTILITY_SRAM_TESTSET        = 0x15,
-       UTILITY_SRAM_TESTVERIFY     = 0x16,
-} flexcop_usb_utility_function_t;
-
-#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
-#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
-
-#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
-
-typedef enum {
-       V8_MEMORY_PAGE_DVB_CI = 0x20,
-       V8_MEMORY_PAGE_DVB_DS = 0x40,
-       V8_MEMORY_PAGE_MULTI2 = 0x60,
-       V8_MEMORY_PAGE_FLASH  = 0x80
-} flexcop_usb_mem_page_t;
-
-#define V8_MEMORY_EXTENDED (1 << 15)
-#define USB_MEM_READ_MAX   32
-#define USB_MEM_WRITE_MAX   1
-#define USB_FLASH_MAX       8
-#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
-#define V8_MEMORY_PAGE_MASK 0x7FFF
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
deleted file mode 100644 (file)
index b1e8c99..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop.c - main module part
- * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
- * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
- *
- * Acknowledgements:
- *   John Jurrius from BBTI, Inc. for extensive support
- *                    with code examples and data books
- *   Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
- *
- * Contributions to the skystar2-driver have been done by
- *   Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
- *   Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
- *   Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
- *   Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
- *               filtering)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * 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 Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "flexcop.h"
-
-#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
-
-#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
-#define DEBSTATUS ""
-#else
-#define DEBSTATUS " (debugging is not enabled)"
-#endif
-
-int b2c2_flexcop_debug;
-module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
-MODULE_PARM_DESC(debug,
-               "set debug level (1=info,2=tuner,4=i2c,8=ts,"
-               "16=sram,32=reg (|-able))."
-               DEBSTATUS);
-#undef DEBSTATUS
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* global zero for ibi values */
-flexcop_ibi_value ibi_zero;
-
-static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
-       return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
-}
-
-static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
-       return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
-}
-
-static int flexcop_dvb_init(struct flexcop_device *fc)
-{
-       int ret = dvb_register_adapter(&fc->dvb_adapter,
-                       "FlexCop Digital TV device", fc->owner,
-                       fc->dev, adapter_nr);
-       if (ret < 0) {
-               err("error registering DVB adapter");
-               return ret;
-       }
-       fc->dvb_adapter.priv = fc;
-
-       fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
-                       | DMX_MEMORY_BASED_FILTERING);
-       fc->demux.priv = fc;
-       fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
-       fc->demux.start_feed = flexcop_dvb_start_feed;
-       fc->demux.stop_feed = flexcop_dvb_stop_feed;
-       fc->demux.write_to_decoder = NULL;
-
-       ret = dvb_dmx_init(&fc->demux);
-       if (ret < 0) {
-               err("dvb_dmx failed: error %d", ret);
-               goto err_dmx;
-       }
-
-       fc->hw_frontend.source = DMX_FRONTEND_0;
-
-       fc->dmxdev.filternum = fc->demux.feednum;
-       fc->dmxdev.demux = &fc->demux.dmx;
-       fc->dmxdev.capabilities = 0;
-       ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter);
-       if (ret < 0) {
-               err("dvb_dmxdev_init failed: error %d", ret);
-               goto err_dmx_dev;
-       }
-
-       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
-       if (ret < 0) {
-               err("adding hw_frontend to dmx failed: error %d", ret);
-               goto err_dmx_add_hw_frontend;
-       }
-
-       fc->mem_frontend.source = DMX_MEMORY_FE;
-       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
-       if (ret < 0) {
-               err("adding mem_frontend to dmx failed: error %d", ret);
-               goto err_dmx_add_mem_frontend;
-       }
-
-       ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
-       if (ret < 0) {
-               err("connect frontend failed: error %d", ret);
-               goto err_connect_frontend;
-       }
-
-       ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
-       if (ret < 0) {
-               err("dvb_net_init failed: error %d", ret);
-               goto err_net;
-       }
-
-       fc->init_state |= FC_STATE_DVB_INIT;
-       return 0;
-
-err_net:
-       fc->demux.dmx.disconnect_frontend(&fc->demux.dmx);
-err_connect_frontend:
-       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
-err_dmx_add_mem_frontend:
-       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
-err_dmx_add_hw_frontend:
-       dvb_dmxdev_release(&fc->dmxdev);
-err_dmx_dev:
-       dvb_dmx_release(&fc->demux);
-err_dmx:
-       dvb_unregister_adapter(&fc->dvb_adapter);
-       return ret;
-}
-
-static void flexcop_dvb_exit(struct flexcop_device *fc)
-{
-       if (fc->init_state & FC_STATE_DVB_INIT) {
-               dvb_net_release(&fc->dvbnet);
-
-               fc->demux.dmx.close(&fc->demux.dmx);
-               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
-                       &fc->mem_frontend);
-               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
-                       &fc->hw_frontend);
-               dvb_dmxdev_release(&fc->dmxdev);
-               dvb_dmx_release(&fc->demux);
-               dvb_unregister_adapter(&fc->dvb_adapter);
-               deb_info("deinitialized dvb stuff\n");
-       }
-       fc->init_state &= ~FC_STATE_DVB_INIT;
-}
-
-/* these methods are necessary to achieve the long-term-goal of hiding the
- * struct flexcop_device from the bus-parts */
-void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
-{
-       dvb_dmx_swfilter(&fc->demux, buf, len);
-}
-EXPORT_SYMBOL(flexcop_pass_dmx_data);
-
-void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
-{
-       dvb_dmx_swfilter_packets(&fc->demux, buf, no);
-}
-EXPORT_SYMBOL(flexcop_pass_dmx_packets);
-
-static void flexcop_reset(struct flexcop_device *fc)
-{
-       flexcop_ibi_value v210, v204;
-
-       /* reset the flexcop itself */
-       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
-
-       v210.raw = 0;
-       v210.sw_reset_210.reset_block_000 = 1;
-       v210.sw_reset_210.reset_block_100 = 1;
-       v210.sw_reset_210.reset_block_200 = 1;
-       v210.sw_reset_210.reset_block_300 = 1;
-       v210.sw_reset_210.reset_block_400 = 1;
-       v210.sw_reset_210.reset_block_500 = 1;
-       v210.sw_reset_210.reset_block_600 = 1;
-       v210.sw_reset_210.reset_block_700 = 1;
-       v210.sw_reset_210.Block_reset_enable = 0xb2;
-       v210.sw_reset_210.Special_controls = 0xc259;
-       fc->write_ibi_reg(fc,sw_reset_210,v210);
-       msleep(1);
-
-       /* reset the periphical devices */
-
-       v204 = fc->read_ibi_reg(fc,misc_204);
-       v204.misc_204.Per_reset_sig = 0;
-       fc->write_ibi_reg(fc,misc_204,v204);
-       msleep(1);
-       v204.misc_204.Per_reset_sig = 1;
-       fc->write_ibi_reg(fc,misc_204,v204);
-}
-
-void flexcop_reset_block_300(struct flexcop_device *fc)
-{
-       flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
-                         v210 = fc->read_ibi_reg(fc, sw_reset_210);
-
-       deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
-       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
-
-       v210.sw_reset_210.reset_block_300 = 1;
-       v210.sw_reset_210.Block_reset_enable = 0xb2;
-
-       fc->write_ibi_reg(fc,sw_reset_210,v210);
-       fc->write_ibi_reg(fc,ctrl_208,v208_save);
-}
-
-struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
-{
-       void *bus;
-       struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
-                               GFP_KERNEL);
-       if (!fc) {
-               err("no memory");
-               return NULL;
-       }
-
-       bus = kzalloc(bus_specific_len, GFP_KERNEL);
-       if (!bus) {
-               err("no memory");
-               kfree(fc);
-               return NULL;
-       }
-
-       fc->bus_specific = bus;
-
-       return fc;
-}
-EXPORT_SYMBOL(flexcop_device_kmalloc);
-
-void flexcop_device_kfree(struct flexcop_device *fc)
-{
-       kfree(fc->bus_specific);
-       kfree(fc);
-}
-EXPORT_SYMBOL(flexcop_device_kfree);
-
-int flexcop_device_initialize(struct flexcop_device *fc)
-{
-       int ret;
-       ibi_zero.raw = 0;
-
-       flexcop_reset(fc);
-       flexcop_determine_revision(fc);
-       flexcop_sram_init(fc);
-       flexcop_hw_filter_init(fc);
-       flexcop_smc_ctrl(fc, 0);
-
-       ret = flexcop_dvb_init(fc);
-       if (ret)
-               goto error;
-
-       /* i2c has to be done before doing EEProm stuff -
-        * because the EEProm is accessed via i2c */
-       ret = flexcop_i2c_init(fc);
-       if (ret)
-               goto error;
-
-       /* do the MAC address reading after initializing the dvb_adapter */
-       if (fc->get_mac_addr(fc, 0) == 0) {
-               u8 *b = fc->dvb_adapter.proposed_mac;
-               info("MAC address = %pM", b);
-               flexcop_set_mac_filter(fc,b);
-               flexcop_mac_filter_ctrl(fc,1);
-       } else
-               warn("reading of MAC address failed.\n");
-
-       ret = flexcop_frontend_init(fc);
-       if (ret)
-               goto error;
-
-       flexcop_device_name(fc,"initialization of","complete");
-       return 0;
-
-error:
-       flexcop_device_exit(fc);
-       return ret;
-}
-EXPORT_SYMBOL(flexcop_device_initialize);
-
-void flexcop_device_exit(struct flexcop_device *fc)
-{
-       flexcop_frontend_exit(fc);
-       flexcop_i2c_exit(fc);
-       flexcop_dvb_exit(fc);
-}
-EXPORT_SYMBOL(flexcop_device_exit);
-
-static int flexcop_module_init(void)
-{
-       info(DRIVER_NAME " loaded successfully");
-       return 0;
-}
-
-static void flexcop_module_cleanup(void)
-{
-       info(DRIVER_NAME " unloaded successfully");
-}
-
-module_init(flexcop_module_init);
-module_exit(flexcop_module_cleanup);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_NAME);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
deleted file mode 100644 (file)
index 897b10c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * flexcop.h - private header file for all flexcop-chip-source files
- * see flexcop.c for copyright information
- */
-#ifndef __FLEXCOP_H__
-#define __FLEXCOP_H___
-
-#define FC_LOG_PREFIX "b2c2-flexcop"
-#include "flexcop-common.h"
-
-extern int b2c2_flexcop_debug;
-
-/* debug */
-#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
-#define dprintk(level,args...) \
-       do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
-#else
-#define dprintk(level,args...)
-#endif
-
-#define deb_info(args...) dprintk(0x01, args)
-#define deb_tuner(args...) dprintk(0x02, args)
-#define deb_i2c(args...) dprintk(0x04, args)
-#define deb_ts(args...) dprintk(0x08, args)
-#define deb_sram(args...) dprintk(0x10, args)
-#define deb_rdump(args...) dprintk(0x20, args)
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
deleted file mode 100644 (file)
index 8f64bdb..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * register descriptions
- * see flexcop.c for copyright information
- */
-/* This file is automatically generated, do not edit things here. */
-#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
-#define __FLEXCOP_IBI_VALUE_INCLUDED__
-
-typedef union {
-       u32 raw;
-
-       struct {
-               u32 dma_address0                   :30;
-               u32 dma_0No_update                 : 1;
-               u32 dma_0start                     : 1;
-       } dma_0x0;
-
-       struct {
-               u32 dma_addr_size                  :24;
-               u32 DMA_maxpackets                 : 8;
-       } dma_0x4_remap;
-
-       struct {
-               u32 dma_addr_size                  :24;
-               u32 unused                         : 1;
-               u32 dma1timer                      : 7;
-       } dma_0x4_read;
-
-       struct {
-               u32 dma_addr_size                  :24;
-               u32 dmatimer                       : 7;
-               u32 unused                         : 1;
-       } dma_0x4_write;
-
-       struct {
-               u32 dma_cur_addr                   :30;
-               u32 unused                         : 2;
-       } dma_0x8;
-
-       struct {
-               u32 dma_address1                   :30;
-               u32 remap_enable                   : 1;
-               u32 dma_1start                     : 1;
-       } dma_0xc;
-
-       struct {
-               u32 st_done                        : 1;
-               u32 no_base_addr_ack_error         : 1;
-               u32 twoWS_port_reg                 : 2;
-               u32 total_bytes                    : 2;
-               u32 twoWS_rw                       : 1;
-               u32 working_start                  : 1;
-               u32 data1_reg                      : 8;
-               u32 baseaddr                       : 8;
-               u32 reserved1                      : 1;
-               u32 chipaddr                       : 7;
-       } tw_sm_c_100;
-
-       struct {
-               u32 unused                         : 6;
-               u32 force_stop                     : 1;
-               u32 exlicit_stops                  : 1;
-               u32 data4_reg                      : 8;
-               u32 data3_reg                      : 8;
-               u32 data2_reg                      : 8;
-       } tw_sm_c_104;
-
-       struct {
-               u32 reserved2                      :19;
-               u32 tlo1                           : 5;
-               u32 reserved1                      : 2;
-               u32 thi1                           : 6;
-       } tw_sm_c_108;
-
-       struct {
-               u32 reserved2                      :19;
-               u32 tlo1                           : 5;
-               u32 reserved1                      : 2;
-               u32 thi1                           : 6;
-       } tw_sm_c_10c;
-
-       struct {
-               u32 reserved2                      :19;
-               u32 tlo1                           : 5;
-               u32 reserved1                      : 2;
-               u32 thi1                           : 6;
-       } tw_sm_c_110;
-
-       struct {
-               u32 LNB_CTLPrescaler_sig           : 2;
-               u32 LNB_CTLLowCount_sig            :15;
-               u32 LNB_CTLHighCount_sig           :15;
-       } lnb_switch_freq_200;
-
-       struct {
-               u32 Rev_N_sig_reserved2            : 1;
-               u32 Rev_N_sig_caps                 : 1;
-               u32 Rev_N_sig_reserved1            : 2;
-               u32 Rev_N_sig_revision_hi          : 4;
-               u32 reserved                       :20;
-               u32 Per_reset_sig                  : 1;
-               u32 LNB_L_H_sig                    : 1;
-               u32 ACPI3_sig                      : 1;
-               u32 ACPI1_sig                      : 1;
-       } misc_204;
-
-       struct {
-               u32 unused                         : 9;
-               u32 Mailbox_from_V8_Enable_sig     : 1;
-               u32 DMA2_Size_IRQ_Enable_sig       : 1;
-               u32 DMA1_Size_IRQ_Enable_sig       : 1;
-               u32 DMA2_Timer_Enable_sig          : 1;
-               u32 DMA2_IRQ_Enable_sig            : 1;
-               u32 DMA1_Timer_Enable_sig          : 1;
-               u32 DMA1_IRQ_Enable_sig            : 1;
-               u32 Rcv_Data_sig                   : 1;
-               u32 MAC_filter_Mode_sig            : 1;
-               u32 Multi2_Enable_sig              : 1;
-               u32 Per_CA_Enable_sig              : 1;
-               u32 SMC_Enable_sig                 : 1;
-               u32 CA_Enable_sig                  : 1;
-               u32 WAN_CA_Enable_sig              : 1;
-               u32 WAN_Enable_sig                 : 1;
-               u32 Mask_filter_sig                : 1;
-               u32 Null_filter_sig                : 1;
-               u32 ECM_filter_sig                 : 1;
-               u32 EMM_filter_sig                 : 1;
-               u32 PMT_filter_sig                 : 1;
-               u32 PCR_filter_sig                 : 1;
-               u32 Stream2_filter_sig             : 1;
-               u32 Stream1_filter_sig             : 1;
-       } ctrl_208;
-
-       struct {
-               u32 reserved                       :21;
-               u32 Transport_Error                : 1;
-               u32 LLC_SNAP_FLAG_set              : 1;
-               u32 Continuity_error_flag          : 1;
-               u32 Data_receiver_error            : 1;
-               u32 Mailbox_from_V8_Status_sig     : 1;
-               u32 DMA2_Size_IRQ_Status           : 1;
-               u32 DMA1_Size_IRQ_Status           : 1;
-               u32 DMA2_Timer_Status              : 1;
-               u32 DMA2_IRQ_Status                : 1;
-               u32 DMA1_Timer_Status              : 1;
-               u32 DMA1_IRQ_Status                : 1;
-       } irq_20c;
-
-       struct {
-               u32 Special_controls               :16;
-               u32 Block_reset_enable             : 8;
-               u32 reset_block_700                : 1;
-               u32 reset_block_600                : 1;
-               u32 reset_block_500                : 1;
-               u32 reset_block_400                : 1;
-               u32 reset_block_300                : 1;
-               u32 reset_block_200                : 1;
-               u32 reset_block_100                : 1;
-               u32 reset_block_000                : 1;
-       } sw_reset_210;
-
-       struct {
-               u32 unused2                        :20;
-               u32 polarity_PS_ERR_sig            : 1;
-               u32 polarity_PS_SYNC_sig           : 1;
-               u32 polarity_PS_VALID_sig          : 1;
-               u32 polarity_PS_CLK_sig            : 1;
-               u32 unused1                        : 3;
-               u32 s2p_sel_sig                    : 1;
-               u32 section_pkg_enable_sig         : 1;
-               u32 halt_V8_sig                    : 1;
-               u32 v2WS_oe_sig                    : 1;
-               u32 vuart_oe_sig                   : 1;
-       } misc_214;
-
-       struct {
-               u32 Mailbox_from_V8                :32;
-       } mbox_v8_to_host_218;
-
-       struct {
-               u32 sysramaccess_busmuster         : 1;
-               u32 sysramaccess_write             : 1;
-               u32 unused                         : 7;
-               u32 sysramaccess_addr              :15;
-               u32 sysramaccess_data              : 8;
-       } mbox_host_to_v8_21c;
-
-       struct {
-               u32 debug_fifo_problem             : 1;
-               u32 debug_flag_write_status00      : 1;
-               u32 Stream2_trans                  : 1;
-               u32 Stream2_PID                    :13;
-               u32 debug_flag_pid_saved           : 1;
-               u32 MAC_Multicast_filter           : 1;
-               u32 Stream1_trans                  : 1;
-               u32 Stream1_PID                    :13;
-       } pid_filter_300;
-
-       struct {
-               u32 reserved                       : 2;
-               u32 PMT_trans                      : 1;
-               u32 PMT_PID                        :13;
-               u32 debug_overrun2                 : 1;
-               u32 debug_overrun3                 : 1;
-               u32 PCR_trans                      : 1;
-               u32 PCR_PID                        :13;
-       } pid_filter_304;
-
-       struct {
-               u32 reserved                       : 2;
-               u32 ECM_trans                      : 1;
-               u32 ECM_PID                        :13;
-               u32 EMM_filter_6                   : 1;
-               u32 EMM_filter_4                   : 1;
-               u32 EMM_trans                      : 1;
-               u32 EMM_PID                        :13;
-       } pid_filter_308;
-
-       struct {
-               u32 unused2                        : 3;
-               u32 Group_mask                     :13;
-               u32 unused1                        : 2;
-               u32 Group_trans                    : 1;
-               u32 Group_PID                      :13;
-       } pid_filter_30c_ext_ind_0_7;
-
-       struct {
-               u32 unused                         :15;
-               u32 net_master_read                :17;
-       } pid_filter_30c_ext_ind_1;
-
-       struct {
-               u32 unused                         :15;
-               u32 net_master_write               :17;
-       } pid_filter_30c_ext_ind_2;
-
-       struct {
-               u32 unused                         :15;
-               u32 next_net_master_write          :17;
-       } pid_filter_30c_ext_ind_3;
-
-       struct {
-               u32 reserved2                      : 5;
-               u32 stack_read                     :10;
-               u32 reserved1                      : 6;
-               u32 state_write                    :10;
-               u32 unused1                        : 1;
-       } pid_filter_30c_ext_ind_4;
-
-       struct {
-               u32 unused                         :22;
-               u32 stack_cnt                      :10;
-       } pid_filter_30c_ext_ind_5;
-
-       struct {
-               u32 unused                         : 4;
-               u32 data_size_reg                  :12;
-               u32 write_status4                  : 2;
-               u32 write_status1                  : 2;
-               u32 pid_fsm_save_reg300            : 2;
-               u32 pid_fsm_save_reg4              : 2;
-               u32 pid_fsm_save_reg3              : 2;
-               u32 pid_fsm_save_reg2              : 2;
-               u32 pid_fsm_save_reg1              : 2;
-               u32 pid_fsm_save_reg0              : 2;
-       } pid_filter_30c_ext_ind_6;
-
-       struct {
-               u32 unused                         :22;
-               u32 pass_alltables                 : 1;
-               u32 AB_select                      : 1;
-               u32 extra_index_reg                : 3;
-               u32 index_reg                      : 5;
-       } index_reg_310;
-
-       struct {
-               u32 reserved                       :17;
-               u32 PID_enable_bit                 : 1;
-               u32 PID_trans                      : 1;
-               u32 PID                            :13;
-       } pid_n_reg_314;
-
-       struct {
-               u32 reserved                       : 6;
-               u32 HighAB_bit                     : 1;
-               u32 Enable_bit                     : 1;
-               u32 A6_byte                        : 8;
-               u32 A5_byte                        : 8;
-               u32 A4_byte                        : 8;
-       } mac_low_reg_318;
-
-       struct {
-               u32 reserved                       : 8;
-               u32 A3_byte                        : 8;
-               u32 A2_byte                        : 8;
-               u32 A1_byte                        : 8;
-       } mac_high_reg_31c;
-
-       struct {
-               u32 data_Tag_ID                    :16;
-               u32 reserved                       :16;
-       } data_tag_400;
-
-       struct {
-               u32 Card_IDbyte3                   : 8;
-               u32 Card_IDbyte4                   : 8;
-               u32 Card_IDbyte5                   : 8;
-               u32 Card_IDbyte6                   : 8;
-       } card_id_408;
-
-       struct {
-               u32 Card_IDbyte1                   : 8;
-               u32 Card_IDbyte2                   : 8;
-       } card_id_40c;
-
-       struct {
-               u32 MAC6                           : 8;
-               u32 MAC3                           : 8;
-               u32 MAC2                           : 8;
-               u32 MAC1                           : 8;
-       } mac_address_418;
-
-       struct {
-               u32 reserved                       :16;
-               u32 MAC8                           : 8;
-               u32 MAC7                           : 8;
-       } mac_address_41c;
-
-       struct {
-               u32 reserved                       :21;
-               u32 txbuffempty                    : 1;
-               u32 ReceiveByteFrameError          : 1;
-               u32 ReceiveDataReady               : 1;
-               u32 transmitter_data_byte          : 8;
-       } ci_600;
-
-       struct {
-               u32 pi_component_reg               : 3;
-               u32 pi_rw                          : 1;
-               u32 pi_ha                          :20;
-               u32 pi_d                           : 8;
-       } pi_604;
-
-       struct {
-               u32 pi_busy_n                      : 1;
-               u32 pi_wait_n                      : 1;
-               u32 pi_timeout_status              : 1;
-               u32 pi_CiMax_IRQ_n                 : 1;
-               u32 config_cclk                    : 1;
-               u32 config_cs_n                    : 1;
-               u32 config_wr_n                    : 1;
-               u32 config_Prog_n                  : 1;
-               u32 config_Init_stat               : 1;
-               u32 config_Done_stat               : 1;
-               u32 pcmcia_b_mod_pwr_n             : 1;
-               u32 pcmcia_a_mod_pwr_n             : 1;
-               u32 reserved                       : 3;
-               u32 Timer_addr                     : 5;
-               u32 unused                         : 1;
-               u32 timer_data                     : 7;
-               u32 Timer_Load_req                 : 1;
-               u32 Timer_Read_req                 : 1;
-               u32 oncecycle_read                 : 1;
-               u32 serialReset                    : 1;
-       } pi_608;
-
-       struct {
-               u32 reserved                       : 6;
-               u32 rw_flag                        : 1;
-               u32 dvb_en                         : 1;
-               u32 key_array_row                  : 5;
-               u32 key_array_col                  : 3;
-               u32 key_code                       : 2;
-               u32 key_enable                     : 1;
-               u32 PID                            :13;
-       } dvb_reg_60c;
-
-       struct {
-               u32 start_sram_ibi                 : 1;
-               u32 reserved2                      : 1;
-               u32 ce_pin_reg                     : 1;
-               u32 oe_pin_reg                     : 1;
-               u32 reserved1                      : 3;
-               u32 sc_xfer_bit                    : 1;
-               u32 sram_data                      : 8;
-               u32 sram_rw                        : 1;
-               u32 sram_addr                      :15;
-       } sram_ctrl_reg_700;
-
-       struct {
-               u32 net_addr_write                 :16;
-               u32 net_addr_read                  :16;
-       } net_buf_reg_704;
-
-       struct {
-               u32 cai_cnt                        : 4;
-               u32 reserved2                      : 6;
-               u32 cai_write                      :11;
-               u32 reserved1                      : 5;
-               u32 cai_read                       :11;
-       } cai_buf_reg_708;
-
-       struct {
-               u32 cao_cnt                        : 4;
-               u32 reserved2                      : 6;
-               u32 cap_write                      :11;
-               u32 reserved1                      : 5;
-               u32 cao_read                       :11;
-       } cao_buf_reg_70c;
-
-       struct {
-               u32 media_cnt                      : 4;
-               u32 reserved2                      : 6;
-               u32 media_write                    :11;
-               u32 reserved1                      : 5;
-               u32 media_read                     :11;
-       } media_buf_reg_710;
-
-       struct {
-               u32 reserved                       :17;
-               u32 ctrl_maximumfill               : 1;
-               u32 ctrl_sramdma                   : 1;
-               u32 ctrl_usb_wan                   : 1;
-               u32 cao_ovflow_error               : 1;
-               u32 cai_ovflow_error               : 1;
-               u32 media_ovflow_error             : 1;
-               u32 net_ovflow_error               : 1;
-               u32 MEDIA_Dest                     : 2;
-               u32 CAO_Dest                       : 2;
-               u32 CAI_Dest                       : 2;
-               u32 NET_Dest                       : 2;
-       } sram_dest_reg_714;
-
-       struct {
-               u32 reserved3                      :11;
-               u32 net_addr_write                 : 1;
-               u32 reserved2                      : 3;
-               u32 net_addr_read                  : 1;
-               u32 reserved1                      : 4;
-               u32 net_cnt                        :12;
-       } net_buf_reg_718;
-
-       struct {
-               u32 reserved3                      : 4;
-               u32 wan_pkt_frame                  : 4;
-               u32 reserved2                      : 4;
-               u32 sram_memmap                    : 2;
-               u32 sram_chip                      : 2;
-               u32 wan_wait_state                 : 8;
-               u32 reserved1                      : 6;
-               u32 wan_speed_sig                  : 2;
-       } wan_ctrl_reg_71c;
-} flexcop_ibi_value;
-
-#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
deleted file mode 100644 (file)
index c75830d..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- * register descriptions
- * see flexcop.c for copyright information
- */
-/* This file is automatically generated, do not edit things here. */
-#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
-#define __FLEXCOP_IBI_VALUE_INCLUDED__
-
-typedef union {
-       u32 raw;
-
-       struct {
-               u32 dma_0start                     : 1;
-               u32 dma_0No_update                 : 1;
-               u32 dma_address0                   :30;
-       } dma_0x0;
-
-       struct {
-               u32 DMA_maxpackets                 : 8;
-               u32 dma_addr_size                  :24;
-       } dma_0x4_remap;
-
-       struct {
-               u32 dma1timer                      : 7;
-               u32 unused                         : 1;
-               u32 dma_addr_size                  :24;
-       } dma_0x4_read;
-
-       struct {
-               u32 unused                         : 1;
-               u32 dmatimer                       : 7;
-               u32 dma_addr_size                  :24;
-       } dma_0x4_write;
-
-       struct {
-               u32 unused                         : 2;
-               u32 dma_cur_addr                   :30;
-       } dma_0x8;
-
-       struct {
-               u32 dma_1start                     : 1;
-               u32 remap_enable                   : 1;
-               u32 dma_address1                   :30;
-       } dma_0xc;
-
-       struct {
-               u32 chipaddr                       : 7;
-               u32 reserved1                      : 1;
-               u32 baseaddr                       : 8;
-               u32 data1_reg                      : 8;
-               u32 working_start                  : 1;
-               u32 twoWS_rw                       : 1;
-               u32 total_bytes                    : 2;
-               u32 twoWS_port_reg                 : 2;
-               u32 no_base_addr_ack_error         : 1;
-               u32 st_done                        : 1;
-       } tw_sm_c_100;
-
-       struct {
-               u32 data2_reg                      : 8;
-               u32 data3_reg                      : 8;
-               u32 data4_reg                      : 8;
-               u32 exlicit_stops                  : 1;
-               u32 force_stop                     : 1;
-               u32 unused                         : 6;
-       } tw_sm_c_104;
-
-       struct {
-               u32 thi1                           : 6;
-               u32 reserved1                      : 2;
-               u32 tlo1                           : 5;
-               u32 reserved2                      :19;
-       } tw_sm_c_108;
-
-       struct {
-               u32 thi1                           : 6;
-               u32 reserved1                      : 2;
-               u32 tlo1                           : 5;
-               u32 reserved2                      :19;
-       } tw_sm_c_10c;
-
-       struct {
-               u32 thi1                           : 6;
-               u32 reserved1                      : 2;
-               u32 tlo1                           : 5;
-               u32 reserved2                      :19;
-       } tw_sm_c_110;
-
-       struct {
-               u32 LNB_CTLHighCount_sig           :15;
-               u32 LNB_CTLLowCount_sig            :15;
-               u32 LNB_CTLPrescaler_sig           : 2;
-       } lnb_switch_freq_200;
-
-       struct {
-               u32 ACPI1_sig                      : 1;
-               u32 ACPI3_sig                      : 1;
-               u32 LNB_L_H_sig                    : 1;
-               u32 Per_reset_sig                  : 1;
-               u32 reserved                       :20;
-               u32 Rev_N_sig_revision_hi          : 4;
-               u32 Rev_N_sig_reserved1            : 2;
-               u32 Rev_N_sig_caps                 : 1;
-               u32 Rev_N_sig_reserved2            : 1;
-       } misc_204;
-
-       struct {
-               u32 Stream1_filter_sig             : 1;
-               u32 Stream2_filter_sig             : 1;
-               u32 PCR_filter_sig                 : 1;
-               u32 PMT_filter_sig                 : 1;
-               u32 EMM_filter_sig                 : 1;
-               u32 ECM_filter_sig                 : 1;
-               u32 Null_filter_sig                : 1;
-               u32 Mask_filter_sig                : 1;
-               u32 WAN_Enable_sig                 : 1;
-               u32 WAN_CA_Enable_sig              : 1;
-               u32 CA_Enable_sig                  : 1;
-               u32 SMC_Enable_sig                 : 1;
-               u32 Per_CA_Enable_sig              : 1;
-               u32 Multi2_Enable_sig              : 1;
-               u32 MAC_filter_Mode_sig            : 1;
-               u32 Rcv_Data_sig                   : 1;
-               u32 DMA1_IRQ_Enable_sig            : 1;
-               u32 DMA1_Timer_Enable_sig          : 1;
-               u32 DMA2_IRQ_Enable_sig            : 1;
-               u32 DMA2_Timer_Enable_sig          : 1;
-               u32 DMA1_Size_IRQ_Enable_sig       : 1;
-               u32 DMA2_Size_IRQ_Enable_sig       : 1;
-               u32 Mailbox_from_V8_Enable_sig     : 1;
-               u32 unused                         : 9;
-       } ctrl_208;
-
-       struct {
-               u32 DMA1_IRQ_Status                : 1;
-               u32 DMA1_Timer_Status              : 1;
-               u32 DMA2_IRQ_Status                : 1;
-               u32 DMA2_Timer_Status              : 1;
-               u32 DMA1_Size_IRQ_Status           : 1;
-               u32 DMA2_Size_IRQ_Status           : 1;
-               u32 Mailbox_from_V8_Status_sig     : 1;
-               u32 Data_receiver_error            : 1;
-               u32 Continuity_error_flag          : 1;
-               u32 LLC_SNAP_FLAG_set              : 1;
-               u32 Transport_Error                : 1;
-               u32 reserved                       :21;
-       } irq_20c;
-
-       struct {
-               u32 reset_block_000                : 1;
-               u32 reset_block_100                : 1;
-               u32 reset_block_200                : 1;
-               u32 reset_block_300                : 1;
-               u32 reset_block_400                : 1;
-               u32 reset_block_500                : 1;
-               u32 reset_block_600                : 1;
-               u32 reset_block_700                : 1;
-               u32 Block_reset_enable             : 8;
-               u32 Special_controls               :16;
-       } sw_reset_210;
-
-       struct {
-               u32 vuart_oe_sig                   : 1;
-               u32 v2WS_oe_sig                    : 1;
-               u32 halt_V8_sig                    : 1;
-               u32 section_pkg_enable_sig         : 1;
-               u32 s2p_sel_sig                    : 1;
-               u32 unused1                        : 3;
-               u32 polarity_PS_CLK_sig            : 1;
-               u32 polarity_PS_VALID_sig          : 1;
-               u32 polarity_PS_SYNC_sig           : 1;
-               u32 polarity_PS_ERR_sig            : 1;
-               u32 unused2                        :20;
-       } misc_214;
-
-       struct {
-               u32 Mailbox_from_V8                :32;
-       } mbox_v8_to_host_218;
-
-       struct {
-               u32 sysramaccess_data              : 8;
-               u32 sysramaccess_addr              :15;
-               u32 unused                         : 7;
-               u32 sysramaccess_write             : 1;
-               u32 sysramaccess_busmuster         : 1;
-       } mbox_host_to_v8_21c;
-
-       struct {
-               u32 Stream1_PID                    :13;
-               u32 Stream1_trans                  : 1;
-               u32 MAC_Multicast_filter           : 1;
-               u32 debug_flag_pid_saved           : 1;
-               u32 Stream2_PID                    :13;
-               u32 Stream2_trans                  : 1;
-               u32 debug_flag_write_status00      : 1;
-               u32 debug_fifo_problem             : 1;
-       } pid_filter_300;
-
-       struct {
-               u32 PCR_PID                        :13;
-               u32 PCR_trans                      : 1;
-               u32 debug_overrun3                 : 1;
-               u32 debug_overrun2                 : 1;
-               u32 PMT_PID                        :13;
-               u32 PMT_trans                      : 1;
-               u32 reserved                       : 2;
-       } pid_filter_304;
-
-       struct {
-               u32 EMM_PID                        :13;
-               u32 EMM_trans                      : 1;
-               u32 EMM_filter_4                   : 1;
-               u32 EMM_filter_6                   : 1;
-               u32 ECM_PID                        :13;
-               u32 ECM_trans                      : 1;
-               u32 reserved                       : 2;
-       } pid_filter_308;
-
-       struct {
-               u32 Group_PID                      :13;
-               u32 Group_trans                    : 1;
-               u32 unused1                        : 2;
-               u32 Group_mask                     :13;
-               u32 unused2                        : 3;
-       } pid_filter_30c_ext_ind_0_7;
-
-       struct {
-               u32 net_master_read                :17;
-               u32 unused                         :15;
-       } pid_filter_30c_ext_ind_1;
-
-       struct {
-               u32 net_master_write               :17;
-               u32 unused                         :15;
-       } pid_filter_30c_ext_ind_2;
-
-       struct {
-               u32 next_net_master_write          :17;
-               u32 unused                         :15;
-       } pid_filter_30c_ext_ind_3;
-
-       struct {
-               u32 unused1                        : 1;
-               u32 state_write                    :10;
-               u32 reserved1                      : 6;
-               u32 stack_read                     :10;
-               u32 reserved2                      : 5;
-       } pid_filter_30c_ext_ind_4;
-
-       struct {
-               u32 stack_cnt                      :10;
-               u32 unused                         :22;
-       } pid_filter_30c_ext_ind_5;
-
-       struct {
-               u32 pid_fsm_save_reg0              : 2;
-               u32 pid_fsm_save_reg1              : 2;
-               u32 pid_fsm_save_reg2              : 2;
-               u32 pid_fsm_save_reg3              : 2;
-               u32 pid_fsm_save_reg4              : 2;
-               u32 pid_fsm_save_reg300            : 2;
-               u32 write_status1                  : 2;
-               u32 write_status4                  : 2;
-               u32 data_size_reg                  :12;
-               u32 unused                         : 4;
-       } pid_filter_30c_ext_ind_6;
-
-       struct {
-               u32 index_reg                      : 5;
-               u32 extra_index_reg                : 3;
-               u32 AB_select                      : 1;
-               u32 pass_alltables                 : 1;
-               u32 unused                         :22;
-       } index_reg_310;
-
-       struct {
-               u32 PID                            :13;
-               u32 PID_trans                      : 1;
-               u32 PID_enable_bit                 : 1;
-               u32 reserved                       :17;
-       } pid_n_reg_314;
-
-       struct {
-               u32 A4_byte                        : 8;
-               u32 A5_byte                        : 8;
-               u32 A6_byte                        : 8;
-               u32 Enable_bit                     : 1;
-               u32 HighAB_bit                     : 1;
-               u32 reserved                       : 6;
-       } mac_low_reg_318;
-
-       struct {
-               u32 A1_byte                        : 8;
-               u32 A2_byte                        : 8;
-               u32 A3_byte                        : 8;
-               u32 reserved                       : 8;
-       } mac_high_reg_31c;
-
-       struct {
-               u32 reserved                       :16;
-               u32 data_Tag_ID                    :16;
-       } data_tag_400;
-
-       struct {
-               u32 Card_IDbyte6                   : 8;
-               u32 Card_IDbyte5                   : 8;
-               u32 Card_IDbyte4                   : 8;
-               u32 Card_IDbyte3                   : 8;
-       } card_id_408;
-
-       struct {
-               u32 Card_IDbyte2                   : 8;
-               u32 Card_IDbyte1                   : 8;
-       } card_id_40c;
-
-       struct {
-               u32 MAC1                           : 8;
-               u32 MAC2                           : 8;
-               u32 MAC3                           : 8;
-               u32 MAC6                           : 8;
-       } mac_address_418;
-
-       struct {
-               u32 MAC7                           : 8;
-               u32 MAC8                           : 8;
-               u32 reserved                       :16;
-       } mac_address_41c;
-
-       struct {
-               u32 transmitter_data_byte          : 8;
-               u32 ReceiveDataReady               : 1;
-               u32 ReceiveByteFrameError          : 1;
-               u32 txbuffempty                    : 1;
-               u32 reserved                       :21;
-       } ci_600;
-
-       struct {
-               u32 pi_d                           : 8;
-               u32 pi_ha                          :20;
-               u32 pi_rw                          : 1;
-               u32 pi_component_reg               : 3;
-       } pi_604;
-
-       struct {
-               u32 serialReset                    : 1;
-               u32 oncecycle_read                 : 1;
-               u32 Timer_Read_req                 : 1;
-               u32 Timer_Load_req                 : 1;
-               u32 timer_data                     : 7;
-               u32 unused                         : 1;
-               u32 Timer_addr                     : 5;
-               u32 reserved                       : 3;
-               u32 pcmcia_a_mod_pwr_n             : 1;
-               u32 pcmcia_b_mod_pwr_n             : 1;
-               u32 config_Done_stat               : 1;
-               u32 config_Init_stat               : 1;
-               u32 config_Prog_n                  : 1;
-               u32 config_wr_n                    : 1;
-               u32 config_cs_n                    : 1;
-               u32 config_cclk                    : 1;
-               u32 pi_CiMax_IRQ_n                 : 1;
-               u32 pi_timeout_status              : 1;
-               u32 pi_wait_n                      : 1;
-               u32 pi_busy_n                      : 1;
-       } pi_608;
-
-       struct {
-               u32 PID                            :13;
-               u32 key_enable                     : 1;
-               u32 key_code                       : 2;
-               u32 key_array_col                  : 3;
-               u32 key_array_row                  : 5;
-               u32 dvb_en                         : 1;
-               u32 rw_flag                        : 1;
-               u32 reserved                       : 6;
-       } dvb_reg_60c;
-
-       struct {
-               u32 sram_addr                      :15;
-               u32 sram_rw                        : 1;
-               u32 sram_data                      : 8;
-               u32 sc_xfer_bit                    : 1;
-               u32 reserved1                      : 3;
-               u32 oe_pin_reg                     : 1;
-               u32 ce_pin_reg                     : 1;
-               u32 reserved2                      : 1;
-               u32 start_sram_ibi                 : 1;
-       } sram_ctrl_reg_700;
-
-       struct {
-               u32 net_addr_read                  :16;
-               u32 net_addr_write                 :16;
-       } net_buf_reg_704;
-
-       struct {
-               u32 cai_read                       :11;
-               u32 reserved1                      : 5;
-               u32 cai_write                      :11;
-               u32 reserved2                      : 6;
-               u32 cai_cnt                        : 4;
-       } cai_buf_reg_708;
-
-       struct {
-               u32 cao_read                       :11;
-               u32 reserved1                      : 5;
-               u32 cap_write                      :11;
-               u32 reserved2                      : 6;
-               u32 cao_cnt                        : 4;
-       } cao_buf_reg_70c;
-
-       struct {
-               u32 media_read                     :11;
-               u32 reserved1                      : 5;
-               u32 media_write                    :11;
-               u32 reserved2                      : 6;
-               u32 media_cnt                      : 4;
-       } media_buf_reg_710;
-
-       struct {
-               u32 NET_Dest                       : 2;
-               u32 CAI_Dest                       : 2;
-               u32 CAO_Dest                       : 2;
-               u32 MEDIA_Dest                     : 2;
-               u32 net_ovflow_error               : 1;
-               u32 media_ovflow_error             : 1;
-               u32 cai_ovflow_error               : 1;
-               u32 cao_ovflow_error               : 1;
-               u32 ctrl_usb_wan                   : 1;
-               u32 ctrl_sramdma                   : 1;
-               u32 ctrl_maximumfill               : 1;
-               u32 reserved                       :17;
-       } sram_dest_reg_714;
-
-       struct {
-               u32 net_cnt                        :12;
-               u32 reserved1                      : 4;
-               u32 net_addr_read                  : 1;
-               u32 reserved2                      : 3;
-               u32 net_addr_write                 : 1;
-               u32 reserved3                      :11;
-       } net_buf_reg_718;
-
-       struct {
-               u32 wan_speed_sig                  : 2;
-               u32 reserved1                      : 6;
-               u32 wan_wait_state                 : 8;
-               u32 sram_chip                      : 2;
-               u32 sram_memmap                    : 2;
-               u32 reserved2                      : 4;
-               u32 wan_pkt_frame                  : 4;
-               u32 reserved3                      : 4;
-       } wan_ctrl_reg_71c;
-} flexcop_ibi_value;
-
-#endif
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
deleted file mode 100644 (file)
index 8668e63..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-config DVB_BT8XX
-       tristate "BT8xx based PCI cards"
-       depends on DVB_CORE && PCI && I2C && VIDEO_BT848
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_SP887X if !DVB_FE_CUSTOMISE
-       select DVB_NXT6000 if !DVB_FE_CUSTOMISE
-       select DVB_CX24110 if !DVB_FE_CUSTOMISE
-       select DVB_OR51211 if !DVB_FE_CUSTOMISE
-       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
-       help
-         Support for PCI cards based on the Bt8xx PCI bridge. Examples are
-         the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
-         the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
-         some AVerMedia cards.
-
-         Since these cards have no MPEG decoder onboard, they transmit
-         only compressed MPEG data over the PCI bus, so you need
-         an external software decoder to watch TV on your computer.
-
-         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
deleted file mode 100644 (file)
index 36591ae..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/video/bt8xx
-ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
deleted file mode 100644 (file)
index b34fa95..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
- *
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
- *
- * large parts based on the bttv driver
- * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@metzlerbros.de)
- *                        & Marcus Metzler (mocm@metzlerbros.de)
- * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <linux/ioport.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/kmod.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "bt878.h"
-#include "dst_priv.h"
-
-
-/**************************************/
-/* Miscellaneous utility  definitions */
-/**************************************/
-
-static unsigned int bt878_verbose = 1;
-static unsigned int bt878_debug;
-
-module_param_named(verbose, bt878_verbose, int, 0444);
-MODULE_PARM_DESC(verbose,
-                "verbose startup messages, default is 1 (yes)");
-module_param_named(debug, bt878_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
-
-int bt878_num;
-struct bt878 bt878[BT878_MAX];
-
-EXPORT_SYMBOL(bt878_num);
-EXPORT_SYMBOL(bt878);
-
-#define btwrite(dat,adr)    bmtwrite((dat), (bt->bt878_mem+(adr)))
-#define btread(adr)         bmtread(bt->bt878_mem+(adr))
-
-#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
-#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
-#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-
-#if defined(dprintk)
-#undef dprintk
-#endif
-#define dprintk(fmt, arg...) \
-       do { \
-               if (bt878_debug) \
-                       printk(KERN_DEBUG fmt, ##arg); \
-       } while (0)
-
-static void bt878_mem_free(struct bt878 *bt)
-{
-       if (bt->buf_cpu) {
-               pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
-                                   bt->buf_dma);
-               bt->buf_cpu = NULL;
-       }
-
-       if (bt->risc_cpu) {
-               pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
-                                   bt->risc_dma);
-               bt->risc_cpu = NULL;
-       }
-}
-
-static int bt878_mem_alloc(struct bt878 *bt)
-{
-       if (!bt->buf_cpu) {
-               bt->buf_size = 128 * 1024;
-
-               bt->buf_cpu =
-                   pci_alloc_consistent(bt->dev, bt->buf_size,
-                                        &bt->buf_dma);
-
-               if (!bt->buf_cpu)
-                       return -ENOMEM;
-
-               memset(bt->buf_cpu, 0, bt->buf_size);
-       }
-
-       if (!bt->risc_cpu) {
-               bt->risc_size = PAGE_SIZE;
-               bt->risc_cpu =
-                   pci_alloc_consistent(bt->dev, bt->risc_size,
-                                        &bt->risc_dma);
-
-               if (!bt->risc_cpu) {
-                       bt878_mem_free(bt);
-                       return -ENOMEM;
-               }
-
-               memset(bt->risc_cpu, 0, bt->risc_size);
-       }
-
-       return 0;
-}
-
-/* RISC instructions */
-#define RISC_WRITE             (0x01 << 28)
-#define RISC_JUMP              (0x07 << 28)
-#define RISC_SYNC              (0x08 << 28)
-
-/* RISC bits */
-#define RISC_WR_SOL            (1 << 27)
-#define RISC_WR_EOL            (1 << 26)
-#define RISC_IRQ               (1 << 24)
-#define RISC_STATUS(status)    ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
-#define RISC_SYNC_RESYNC       (1 << 15)
-#define RISC_SYNC_FM1          0x06
-#define RISC_SYNC_VRO          0x0C
-
-#define RISC_FLUSH()           bt->risc_pos = 0
-#define RISC_INSTR(instr)      bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
-
-static int bt878_make_risc(struct bt878 *bt)
-{
-       bt->block_bytes = bt->buf_size >> 4;
-       bt->block_count = 1 << 4;
-       bt->line_bytes = bt->block_bytes;
-       bt->line_count = bt->block_count;
-
-       while (bt->line_bytes > 4095) {
-               bt->line_bytes >>= 1;
-               bt->line_count <<= 1;
-       }
-
-       if (bt->line_count > 255) {
-               printk(KERN_ERR "bt878: buffer size error!\n");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-
-static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
-{
-       u32 buf_pos = 0;
-       u32 line;
-
-       RISC_FLUSH();
-       RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
-       RISC_INSTR(0);
-
-       dprintk("bt878: risc len lines %u, bytes per line %u\n",
-                       bt->line_count, bt->line_bytes);
-       for (line = 0; line < bt->line_count; line++) {
-               // At the beginning of every block we issue an IRQ with previous (finished) block number set
-               if (!(buf_pos % bt->block_bytes))
-                       RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
-                                  RISC_IRQ |
-                                  RISC_STATUS(((buf_pos /
-                                                bt->block_bytes) +
-                                               (bt->block_count -
-                                                1)) %
-                                              bt->block_count) | bt->
-                                  line_bytes);
-               else
-                       RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
-                                  bt->line_bytes);
-               RISC_INSTR(bt->buf_dma + buf_pos);
-               buf_pos += bt->line_bytes;
-       }
-
-       RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
-       RISC_INSTR(0);
-
-       RISC_INSTR(RISC_JUMP);
-       RISC_INSTR(bt->risc_dma);
-
-       btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
-}
-
-/*****************************/
-/* Start/Stop grabbing funcs */
-/*****************************/
-
-void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
-               u32 irq_err_ignore)
-{
-       u32 int_mask;
-
-       dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
-       /* complete the writing of the risc dma program now we have
-        * the card specifics
-        */
-       bt878_risc_program(bt, op_sync_orin);
-       controlreg &= ~0x1f;
-       controlreg |= 0x1b;
-
-       btwrite(bt->risc_dma, BT878_ARISC_START);
-
-       /* original int mask had :
-        *    6    2    8    4    0
-        * 1111 1111 1000 0000 0000
-        * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
-        * Hacked for DST to:
-        * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
-        */
-       int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
-               BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
-               BT878_AFBUS | BT878_ARISCI;
-
-
-       /* ignore pesky bits */
-       int_mask &= ~irq_err_ignore;
-
-       btwrite(int_mask, BT878_AINT_MASK);
-       btwrite(controlreg, BT878_AGPIO_DMA_CTL);
-}
-
-void bt878_stop(struct bt878 *bt)
-{
-       u32 stat;
-       int i = 0;
-
-       dprintk("bt878 debug: bt878_stop\n");
-
-       btwrite(0, BT878_AINT_MASK);
-       btand(~0x13, BT878_AGPIO_DMA_CTL);
-
-       do {
-               stat = btread(BT878_AINT_STAT);
-               if (!(stat & BT878_ARISC_EN))
-                       break;
-               i++;
-       } while (i < 500);
-
-       dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
-               bt->nr, i, stat);
-}
-
-EXPORT_SYMBOL(bt878_start);
-EXPORT_SYMBOL(bt878_stop);
-
-/*****************************/
-/* Interrupt service routine */
-/*****************************/
-
-static irqreturn_t bt878_irq(int irq, void *dev_id)
-{
-       u32 stat, astat, mask;
-       int count;
-       struct bt878 *bt;
-
-       bt = (struct bt878 *) dev_id;
-
-       count = 0;
-       while (1) {
-               stat = btread(BT878_AINT_STAT);
-               mask = btread(BT878_AINT_MASK);
-               if (!(astat = (stat & mask)))
-                       return IRQ_NONE;        /* this interrupt is not for me */
-/*             dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
-               btwrite(astat, BT878_AINT_STAT);        /* try to clear interrupt condition */
-
-
-               if (astat & (BT878_ASCERR | BT878_AOCERR)) {
-                       if (bt878_verbose) {
-                               printk(KERN_INFO
-                                      "bt878(%d): irq%s%s risc_pc=%08x\n",
-                                      bt->nr,
-                                      (astat & BT878_ASCERR) ? " SCERR" :
-                                      "",
-                                      (astat & BT878_AOCERR) ? " OCERR" :
-                                      "", btread(BT878_ARISC_PC));
-                       }
-               }
-               if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
-                       if (bt878_verbose) {
-                               printk(KERN_INFO
-                                    "bt878(%d): irq%s%s%s risc_pc=%08x\n",
-                                    bt->nr,
-                                    (astat & BT878_APABORT) ? " PABORT" :
-                                    "",
-                                    (astat & BT878_ARIPERR) ? " RIPERR" :
-                                    "",
-                                    (astat & BT878_APPERR) ? " PPERR" :
-                                    "", btread(BT878_ARISC_PC));
-                       }
-               }
-               if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
-                       if (bt878_verbose) {
-                               printk(KERN_INFO
-                                    "bt878(%d): irq%s%s%s risc_pc=%08x\n",
-                                    bt->nr,
-                                    (astat & BT878_AFDSR) ? " FDSR" : "",
-                                    (astat & BT878_AFTRGT) ? " FTRGT" :
-                                    "",
-                                    (astat & BT878_AFBUS) ? " FBUS" : "",
-                                    btread(BT878_ARISC_PC));
-                       }
-               }
-               if (astat & BT878_ARISCI) {
-                       bt->finished_block = (stat & BT878_ARISCS) >> 28;
-                       tasklet_schedule(&bt->tasklet);
-                       break;
-               }
-               count++;
-               if (count > 20) {
-                       btwrite(0, BT878_AINT_MASK);
-                       printk(KERN_ERR
-                              "bt878(%d): IRQ lockup, cleared int mask\n",
-                              bt->nr);
-                       break;
-               }
-       }
-       return IRQ_HANDLED;
-}
-
-int
-bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
-{
-       int retval;
-
-       retval = 0;
-       if (mutex_lock_interruptible(&bt->gpio_lock))
-               return -ERESTARTSYS;
-       /* special gpio signal */
-       switch (cmd) {
-           case DST_IG_ENABLE:
-               // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
-               retval = bttv_gpio_enable(bt->bttv_nr,
-                               mp->enb.mask,
-                               mp->enb.enable);
-               break;
-           case DST_IG_WRITE:
-               // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
-               retval = bttv_write_gpio(bt->bttv_nr,
-                               mp->outp.mask,
-                               mp->outp.highvals);
-
-               break;
-           case DST_IG_READ:
-               /* read */
-               retval =  bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
-               // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
-               break;
-           case DST_IG_TS:
-               /* Set packet size */
-               bt->TS_Size = mp->psize;
-               break;
-
-           default:
-               retval = -EINVAL;
-               break;
-       }
-       mutex_unlock(&bt->gpio_lock);
-       return retval;
-}
-
-EXPORT_SYMBOL(bt878_device_control);
-
-#define BROOKTREE_878_DEVICE(vend, dev, name) \
-       { \
-               .vendor = PCI_VENDOR_ID_BROOKTREE, \
-               .device = PCI_DEVICE_ID_BROOKTREE_878, \
-               .subvendor = (vend), .subdevice = (dev), \
-               .driver_data = (unsigned long) name \
-       }
-
-static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
-       BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"),
-       BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"),
-       BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"),
-       BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"),
-       BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"),
-       BROOKTREE_878_DEVICE(0x270f, 0xfc00,
-                               "ChainTech digitop DST-1000 DVB-S"),
-       BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"),
-       BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"),
-       BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"),
-       BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"),
-       BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"),
-       BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"),
-       { }
-};
-
-MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
-
-static const char * __devinit card_name(const struct pci_device_id *id)
-{
-       return id->driver_data ? (const char *)id->driver_data : "Unknown";
-}
-
-/***********************/
-/* PCI device handling */
-/***********************/
-
-static int __devinit bt878_probe(struct pci_dev *dev,
-                                const struct pci_device_id *pci_id)
-{
-       int result = 0;
-       unsigned char lat;
-       struct bt878 *bt;
-#if defined(__powerpc__)
-       unsigned int cmd;
-#endif
-       unsigned int cardid;
-
-       printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
-              bt878_num);
-       if (bt878_num >= BT878_MAX) {
-               printk(KERN_ERR "bt878: Too many devices inserted\n");
-               result = -ENOMEM;
-               goto fail0;
-       }
-       if (pci_enable_device(dev))
-               return -EIO;
-
-       cardid = dev->subsystem_device << 16;
-       cardid |= dev->subsystem_vendor;
-
-       printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n",
-                               __func__, cardid, card_name(pci_id));
-
-       bt = &bt878[bt878_num];
-       bt->dev = dev;
-       bt->nr = bt878_num;
-       bt->shutdown = 0;
-
-       bt->id = dev->device;
-       bt->irq = dev->irq;
-       bt->bt878_adr = pci_resource_start(dev, 0);
-       if (!request_mem_region(pci_resource_start(dev, 0),
-                               pci_resource_len(dev, 0), "bt878")) {
-               result = -EBUSY;
-               goto fail0;
-       }
-
-       bt->revision = dev->revision;
-       pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-
-
-       printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
-              bt878_num, bt->id, bt->revision, dev->bus->number,
-              PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       printk("irq: %d, latency: %d, memory: 0x%lx\n",
-              bt->irq, lat, bt->bt878_adr);
-
-
-#if defined(__powerpc__)
-       /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
-       /* response on cards with no firmware is not enabled by OF */
-       pci_read_config_dword(dev, PCI_COMMAND, &cmd);
-       cmd = (cmd | PCI_COMMAND_MEMORY);
-       pci_write_config_dword(dev, PCI_COMMAND, cmd);
-#endif
-
-#ifdef __sparc__
-       bt->bt878_mem = (unsigned char *) bt->bt878_adr;
-#else
-       bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
-#endif
-
-       /* clear interrupt mask */
-       btwrite(0, BT848_INT_MASK);
-
-       result = request_irq(bt->irq, bt878_irq,
-                            IRQF_SHARED | IRQF_DISABLED, "bt878",
-                            (void *) bt);
-       if (result == -EINVAL) {
-               printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
-                      bt878_num);
-               goto fail1;
-       }
-       if (result == -EBUSY) {
-               printk(KERN_ERR
-                      "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
-                      bt878_num, bt->irq);
-               goto fail1;
-       }
-       if (result < 0)
-               goto fail1;
-
-       pci_set_master(dev);
-       pci_set_drvdata(dev, bt);
-
-       if ((result = bt878_mem_alloc(bt))) {
-               printk(KERN_ERR "bt878: failed to allocate memory!\n");
-               goto fail2;
-       }
-
-       bt878_make_risc(bt);
-       btwrite(0, BT878_AINT_MASK);
-       bt878_num++;
-
-       return 0;
-
-      fail2:
-       free_irq(bt->irq, bt);
-      fail1:
-       release_mem_region(pci_resource_start(bt->dev, 0),
-                          pci_resource_len(bt->dev, 0));
-      fail0:
-       pci_disable_device(dev);
-       return result;
-}
-
-static void __devexit bt878_remove(struct pci_dev *pci_dev)
-{
-       u8 command;
-       struct bt878 *bt = pci_get_drvdata(pci_dev);
-
-       if (bt878_verbose)
-               printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
-
-       /* turn off all capturing, DMA and IRQs */
-       btand(~0x13, BT878_AGPIO_DMA_CTL);
-
-       /* first disable interrupts before unmapping the memory! */
-       btwrite(0, BT878_AINT_MASK);
-       btwrite(~0U, BT878_AINT_STAT);
-
-       /* disable PCI bus-mastering */
-       pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
-       /* Should this be &=~ ?? */
-       command &= ~PCI_COMMAND_MASTER;
-       pci_write_config_byte(bt->dev, PCI_COMMAND, command);
-
-       free_irq(bt->irq, bt);
-       printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
-       if (bt->bt878_mem)
-               iounmap(bt->bt878_mem);
-
-       release_mem_region(pci_resource_start(bt->dev, 0),
-                          pci_resource_len(bt->dev, 0));
-       /* wake up any waiting processes
-          because shutdown flag is set, no new processes (in this queue)
-          are expected
-        */
-       bt->shutdown = 1;
-       bt878_mem_free(bt);
-
-       pci_set_drvdata(pci_dev, NULL);
-       pci_disable_device(pci_dev);
-       return;
-}
-
-static struct pci_driver bt878_pci_driver = {
-      .name    = "bt878",
-      .id_table = bt878_pci_tbl,
-      .probe   = bt878_probe,
-      .remove  = __devexit_p(bt878_remove),
-};
-
-/*******************************/
-/* Module management functions */
-/*******************************/
-
-static int __init bt878_init_module(void)
-{
-       bt878_num = 0;
-
-       printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
-              (BT878_VERSION_CODE >> 16) & 0xff,
-              (BT878_VERSION_CODE >> 8) & 0xff,
-              BT878_VERSION_CODE & 0xff);
-
-       return pci_register_driver(&bt878_pci_driver);
-}
-
-static void __exit bt878_cleanup_module(void)
-{
-       pci_unregister_driver(&bt878_pci_driver);
-}
-
-module_init(bt878_init_module);
-module_exit(bt878_cleanup_module);
-
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
deleted file mode 100644 (file)
index d19b592..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-    bt878.h - Bt878 audio module (register offsets)
-
-    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
-
-    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 _BT878_H_
-#define _BT878_H_
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-
-#include "bt848.h"
-#include "bttv.h"
-
-#define BT878_VERSION_CODE 0x000000
-
-#define BT878_AINT_STAT                0x100
-#define BT878_ARISCS           (0xf<<28)
-#define BT878_ARISC_EN         (1<<27)
-#define BT878_ASCERR           (1<<19)
-#define BT878_AOCERR           (1<<18)
-#define BT878_APABORT          (1<<17)
-#define BT878_ARIPERR          (1<<16)
-#define BT878_APPERR           (1<<15)
-#define BT878_AFDSR            (1<<14)
-#define BT878_AFTRGT           (1<<13)
-#define BT878_AFBUS            (1<<12)
-#define BT878_ARISCI           (1<<11)
-#define BT878_AOFLOW           (1<<3)
-
-#define BT878_AINT_MASK                0x104
-
-#define BT878_AGPIO_DMA_CTL    0x10c
-#define BT878_A_GAIN           (0xf<<28)
-#define BT878_A_G2X            (1<<27)
-#define BT878_A_PWRDN          (1<<26)
-#define BT878_A_SEL            (3<<24)
-#define BT878_DA_SCE           (1<<23)
-#define BT878_DA_LRI           (1<<22)
-#define BT878_DA_MLB           (1<<21)
-#define BT878_DA_LRD           (0x1f<<16)
-#define BT878_DA_DPM           (1<<15)
-#define BT878_DA_SBR           (1<<14)
-#define BT878_DA_ES2           (1<<13)
-#define BT878_DA_LMT           (1<<12)
-#define BT878_DA_SDR           (0xf<<8)
-#define BT878_DA_IOM           (3<<6)
-#define BT878_DA_APP           (1<<5)
-#define BT878_ACAP_EN          (1<<4)
-#define BT878_PKTP             (3<<2)
-#define BT878_RISC_EN          (1<<1)
-#define BT878_FIFO_EN          1
-
-#define BT878_APACK_LEN                0x110
-#define BT878_AFP_LEN          (0xff<<16)
-#define BT878_ALP_LEN          0xfff
-
-#define BT878_ARISC_START      0x114
-
-#define BT878_ARISC_PC         0x120
-
-/* BT878 FUNCTION 0 REGISTERS */
-#define BT878_GPIO_DMA_CTL     0x10c
-
-/* Interrupt register */
-#define BT878_INT_STAT         0x100
-#define BT878_INT_MASK         0x104
-#define BT878_I2CRACK          (1<<25)
-#define BT878_I2CDONE          (1<<8)
-
-#define BT878_MAX 4
-
-#define BT878_RISC_SYNC_MASK   (1 << 15)
-
-
-#define BTTV_BOARD_UNKNOWN                 0x00
-#define BTTV_BOARD_PINNACLESAT             0x5e
-#define BTTV_BOARD_NEBULA_DIGITV           0x68
-#define BTTV_BOARD_PC_HDTV                 0x70
-#define BTTV_BOARD_TWINHAN_DST             0x71
-#define BTTV_BOARD_AVDVBT_771              0x7b
-#define BTTV_BOARD_AVDVBT_761              0x7c
-#define BTTV_BOARD_DVICO_DVBT_LITE         0x80
-#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
-
-extern int bt878_num;
-
-struct bt878 {
-       struct mutex gpio_lock;
-       unsigned int nr;
-       unsigned int bttv_nr;
-       struct i2c_adapter *adapter;
-       struct pci_dev *dev;
-       unsigned int id;
-       unsigned int TS_Size;
-       unsigned char revision;
-       unsigned int irq;
-       unsigned long bt878_adr;
-       volatile void __iomem *bt878_mem; /* function 1 */
-
-       volatile u32 finished_block;
-       volatile u32 last_block;
-       u32 block_count;
-       u32 block_bytes;
-       u32 line_bytes;
-       u32 line_count;
-
-       u32 buf_size;
-       u8 *buf_cpu;
-       dma_addr_t buf_dma;
-
-       u32 risc_size;
-       __le32 *risc_cpu;
-       dma_addr_t risc_dma;
-       u32 risc_pos;
-
-       struct tasklet_struct tasklet;
-       int shutdown;
-};
-
-extern struct bt878 bt878[BT878_MAX];
-
-void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
-               u32 irq_err_ignore);
-void bt878_stop(struct bt878 *bt);
-
-#if defined(__powerpc__)       /* big-endian */
-static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
-{
-       st_le32(addr, val);
-       eieio();
-}
-
-#define bmtwrite(dat,adr)  io_st_le32((adr),(dat))
-#define bmtread(adr)       ld_le32((adr))
-#else
-#define bmtwrite(dat,adr)  writel((dat), (adr))
-#define bmtread(adr)       readl(adr)
-#endif
-
-#endif
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
deleted file mode 100644 (file)
index 430b3eb..0000000
+++ /dev/null
@@ -1,1873 +0,0 @@
-/*
-       Frontend/Card driver for TwinHan DST Frontend
-       Copyright (C) 2003 Jamie Honan
-       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <asm/div64.h>
-#include "dvb_frontend.h"
-#include "dst_priv.h"
-#include "dst_common.h"
-
-static unsigned int verbose = 1;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-
-static unsigned int dst_addons;
-module_param(dst_addons, int, 0644);
-MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
-
-static unsigned int dst_algo;
-module_param(dst_algo, int, 0644);
-MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
-
-#define HAS_LOCK               1
-#define ATTEMPT_TUNE           2
-#define HAS_POWER              4
-
-#define DST_ERROR              0
-#define DST_NOTICE             1
-#define DST_INFO               2
-#define DST_DEBUG              3
-
-#define dprintk(x, y, z, format, arg...) do {                          \
-       if (z) {                                                        \
-               if      ((x > DST_ERROR) && (x > y))                    \
-                       printk(KERN_ERR "dst(%d) %s: " format "\n",     \
-                               state->bt->nr, __func__ , ##arg);       \
-               else if ((x > DST_NOTICE) && (x > y))                   \
-                       printk(KERN_NOTICE "dst(%d) %s: " format "\n",  \
-                               state->bt->nr, __func__ , ##arg);       \
-               else if ((x > DST_INFO) && (x > y))                     \
-                       printk(KERN_INFO "dst(%d) %s: " format "\n",    \
-                               state->bt->nr, __func__ , ##arg);       \
-               else if ((x > DST_DEBUG) && (x > y))                    \
-                       printk(KERN_DEBUG "dst(%d) %s: " format "\n",   \
-                               state->bt->nr,  __func__ , ##arg);      \
-       } else {                                                        \
-               if (x > y)                                              \
-                       printk(format, ##arg);                          \
-       }                                                               \
-} while(0)
-
-static int dst_command(struct dst_state *state, u8 *data, u8 len);
-
-static void dst_packsize(struct dst_state *state, int psize)
-{
-       union dst_gpio_packet bits;
-
-       bits.psize = psize;
-       bt878_device_control(state->bt, DST_IG_TS, &bits);
-}
-
-static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
-                        u32 outhigh, int delay)
-{
-       union dst_gpio_packet enb;
-       union dst_gpio_packet bits;
-       int err;
-
-       enb.enb.mask = mask;
-       enb.enb.enable = enbb;
-
-       dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
-       if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
-               dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
-               return -EREMOTEIO;
-       }
-       udelay(1000);
-       /* because complete disabling means no output, no need to do output packet */
-       if (enbb == 0)
-               return 0;
-       if (delay)
-               msleep(10);
-       bits.outp.mask = enbb;
-       bits.outp.highvals = outhigh;
-       if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
-               dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int dst_gpio_inb(struct dst_state *state, u8 *result)
-{
-       union dst_gpio_packet rd_packet;
-       int err;
-
-       *result = 0;
-       if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err);
-               return -EREMOTEIO;
-       }
-       *result = (u8) rd_packet.rd.value;
-
-       return 0;
-}
-
-int rdc_reset_state(struct dst_state *state)
-{
-       dprintk(verbose, DST_INFO, 1, "Resetting state machine");
-       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               return -1;
-       }
-       msleep(10);
-       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               msleep(10);
-               return -1;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(rdc_reset_state);
-
-static int rdc_8820_reset(struct dst_state *state)
-{
-       dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
-       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               return -1;
-       }
-       udelay(1000);
-       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               return -1;
-       }
-
-       return 0;
-}
-
-static int dst_pio_enable(struct dst_state *state)
-{
-       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               return -1;
-       }
-       udelay(1000);
-
-       return 0;
-}
-
-int dst_pio_disable(struct dst_state *state)
-{
-       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
-               return -1;
-       }
-       if (state->type_flags & DST_TYPE_HAS_FW_1)
-               udelay(1000);
-
-       return 0;
-}
-EXPORT_SYMBOL(dst_pio_disable);
-
-int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
-{
-       u8 reply;
-       int i;
-
-       for (i = 0; i < 200; i++) {
-               if (dst_gpio_inb(state, &reply) < 0) {
-                       dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
-                       return -1;
-               }
-               if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
-                       dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
-                       return 1;
-               }
-               msleep(10);
-       }
-       dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
-
-       return 0;
-}
-EXPORT_SYMBOL(dst_wait_dst_ready);
-
-int dst_error_recovery(struct dst_state *state)
-{
-       dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
-       dst_pio_disable(state);
-       msleep(10);
-       dst_pio_enable(state);
-       msleep(10);
-
-       return 0;
-}
-EXPORT_SYMBOL(dst_error_recovery);
-
-int dst_error_bailout(struct dst_state *state)
-{
-       dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
-       rdc_8820_reset(state);
-       dst_pio_disable(state);
-       msleep(10);
-
-       return 0;
-}
-EXPORT_SYMBOL(dst_error_bailout);
-
-int dst_comm_init(struct dst_state *state)
-{
-       dprintk(verbose, DST_INFO, 1, "Initializing DST.");
-       if ((dst_pio_enable(state)) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
-               return -1;
-       }
-       if ((rdc_reset_state(state)) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
-               return -1;
-       }
-       if (state->type_flags & DST_TYPE_HAS_FW_1)
-               msleep(100);
-       else
-               msleep(5);
-
-       return 0;
-}
-EXPORT_SYMBOL(dst_comm_init);
-
-int write_dst(struct dst_state *state, u8 *data, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address,
-               .flags = 0,
-               .buf = data,
-               .len = len
-       };
-
-       int err;
-       u8 cnt, i;
-
-       dprintk(verbose, DST_NOTICE, 0, "writing [ ");
-       for (i = 0; i < len; i++)
-               dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
-       dprintk(verbose, DST_NOTICE, 0, "]\n");
-
-       for (cnt = 0; cnt < 2; cnt++) {
-               if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
-                       dst_error_recovery(state);
-                       continue;
-               } else
-                       break;
-       }
-       if (cnt >= 2) {
-               dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
-               dst_error_bailout(state);
-
-               return -1;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(write_dst);
-
-int read_dst(struct dst_state *state, u8 *ret, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address,
-               .flags = I2C_M_RD,
-               .buf = ret,
-               .len = len
-       };
-
-       int err;
-       int cnt;
-
-       for (cnt = 0; cnt < 2; cnt++) {
-               if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
-                       dst_error_recovery(state);
-                       continue;
-               } else
-                       break;
-       }
-       if (cnt >= 2) {
-               dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
-               dst_error_bailout(state);
-
-               return -1;
-       }
-       dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
-       for (err = 1; err < len; err++)
-               dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
-       if (err > 1)
-               dprintk(verbose, DST_DEBUG, 0, "\n");
-
-       return 0;
-}
-EXPORT_SYMBOL(read_dst);
-
-static int dst_set_polarization(struct dst_state *state)
-{
-       switch (state->voltage) {
-       case SEC_VOLTAGE_13:    /*      Vertical        */
-               dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
-               state->tx_tuna[8] &= ~0x40;
-               break;
-       case SEC_VOLTAGE_18:    /*      Horizontal      */
-               dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
-               state->tx_tuna[8] |= 0x40;
-               break;
-       case SEC_VOLTAGE_OFF:
-               break;
-       }
-
-       return 0;
-}
-
-static int dst_set_freq(struct dst_state *state, u32 freq)
-{
-       state->frequency = freq;
-       dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
-
-       if (state->dst_type == DST_TYPE_IS_SAT) {
-               freq = freq / 1000;
-               if (freq < 950 || freq > 2150)
-                       return -EINVAL;
-               state->tx_tuna[2] = (freq >> 8);
-               state->tx_tuna[3] = (u8) freq;
-               state->tx_tuna[4] = 0x01;
-               state->tx_tuna[8] &= ~0x04;
-               if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
-                       if (freq < 1531)
-                               state->tx_tuna[8] |= 0x04;
-               }
-       } else if (state->dst_type == DST_TYPE_IS_TERR) {
-               freq = freq / 1000;
-               if (freq < 137000 || freq > 858000)
-                       return -EINVAL;
-               state->tx_tuna[2] = (freq >> 16) & 0xff;
-               state->tx_tuna[3] = (freq >> 8) & 0xff;
-               state->tx_tuna[4] = (u8) freq;
-       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
-               freq = freq / 1000;
-               state->tx_tuna[2] = (freq >> 16) & 0xff;
-               state->tx_tuna[3] = (freq >> 8) & 0xff;
-               state->tx_tuna[4] = (u8) freq;
-       } else if (state->dst_type == DST_TYPE_IS_ATSC) {
-               freq = freq / 1000;
-               if (freq < 51000 || freq > 858000)
-                       return -EINVAL;
-               state->tx_tuna[2] = (freq >> 16) & 0xff;
-               state->tx_tuna[3] = (freq >>  8) & 0xff;
-               state->tx_tuna[4] = (u8) freq;
-               state->tx_tuna[5] = 0x00;               /*      ATSC    */
-               state->tx_tuna[6] = 0x00;
-               if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
-                       state->tx_tuna[7] = 0x00;       /*      Digital */
-       } else
-               return -EINVAL;
-
-       return 0;
-}
-
-static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth)
-{
-       state->bandwidth = bandwidth;
-
-       if (state->dst_type != DST_TYPE_IS_TERR)
-               return -EOPNOTSUPP;
-
-       switch (bandwidth) {
-       case 6000000:
-               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
-                       state->tx_tuna[7] = 0x06;
-               else {
-                       state->tx_tuna[6] = 0x06;
-                       state->tx_tuna[7] = 0x00;
-               }
-               break;
-       case 7000000:
-               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
-                       state->tx_tuna[7] = 0x07;
-               else {
-                       state->tx_tuna[6] = 0x07;
-                       state->tx_tuna[7] = 0x00;
-               }
-               break;
-       case 8000000:
-               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
-                       state->tx_tuna[7] = 0x08;
-               else {
-                       state->tx_tuna[6] = 0x08;
-                       state->tx_tuna[7] = 0x00;
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
-{
-       state->inversion = inversion;
-       switch (inversion) {
-       case INVERSION_OFF:     /*      Inversion = Normal      */
-               state->tx_tuna[8] &= ~0x80;
-               break;
-       case INVERSION_ON:
-               state->tx_tuna[8] |= 0x80;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
-{
-       state->fec = fec;
-       return 0;
-}
-
-static fe_code_rate_t dst_get_fec(struct dst_state *state)
-{
-       return state->fec;
-}
-
-static int dst_set_symbolrate(struct dst_state *state, u32 srate)
-{
-       u32 symcalc;
-       u64 sval;
-
-       state->symbol_rate = srate;
-       if (state->dst_type == DST_TYPE_IS_TERR) {
-               return -EOPNOTSUPP;
-       }
-       dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
-       srate /= 1000;
-       if (state->dst_type == DST_TYPE_IS_SAT) {
-               if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
-                       sval = srate;
-                       sval <<= 20;
-                       do_div(sval, 88000);
-                       symcalc = (u32) sval;
-                       dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
-                       state->tx_tuna[5] = (u8) (symcalc >> 12);
-                       state->tx_tuna[6] = (u8) (symcalc >> 4);
-                       state->tx_tuna[7] = (u8) (symcalc << 4);
-               } else {
-                       state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
-                       state->tx_tuna[6] = (u8) (srate >> 8);
-                       state->tx_tuna[7] = (u8) srate;
-               }
-               state->tx_tuna[8] &= ~0x20;
-               if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
-                       if (srate > 8000)
-                               state->tx_tuna[8] |= 0x20;
-               }
-       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
-               dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name);
-               if (!strncmp(state->fw_name, "DCTNEW", 6)) {
-                       state->tx_tuna[5] = (u8) (srate >> 8);
-                       state->tx_tuna[6] = (u8) srate;
-                       state->tx_tuna[7] = 0x00;
-               } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
-                       state->tx_tuna[5] = 0x00;
-                       state->tx_tuna[6] = (u8) (srate >> 8);
-                       state->tx_tuna[7] = (u8) srate;
-               }
-       }
-       return 0;
-}
-
-static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
-{
-       if (state->dst_type != DST_TYPE_IS_CABLE)
-               return -EOPNOTSUPP;
-
-       state->modulation = modulation;
-       switch (modulation) {
-       case QAM_16:
-               state->tx_tuna[8] = 0x10;
-               break;
-       case QAM_32:
-               state->tx_tuna[8] = 0x20;
-               break;
-       case QAM_64:
-               state->tx_tuna[8] = 0x40;
-               break;
-       case QAM_128:
-               state->tx_tuna[8] = 0x80;
-               break;
-       case QAM_256:
-               if (!strncmp(state->fw_name, "DCTNEW", 6))
-                       state->tx_tuna[8] = 0xff;
-               else if (!strncmp(state->fw_name, "DCT-CI", 6))
-                       state->tx_tuna[8] = 0x00;
-               break;
-       case QPSK:
-       case QAM_AUTO:
-       case VSB_8:
-       case VSB_16:
-       default:
-               return -EINVAL;
-
-       }
-
-       return 0;
-}
-
-static fe_modulation_t dst_get_modulation(struct dst_state *state)
-{
-       return state->modulation;
-}
-
-
-u8 dst_check_sum(u8 *buf, u32 len)
-{
-       u32 i;
-       u8 val = 0;
-       if (!len)
-               return 0;
-       for (i = 0; i < len; i++) {
-               val += buf[i];
-       }
-       return ((~val) + 1);
-}
-EXPORT_SYMBOL(dst_check_sum);
-
-static void dst_type_flags_print(struct dst_state *state)
-{
-       u32 type_flags = state->type_flags;
-
-       dprintk(verbose, DST_ERROR, 0, "DST type flags :");
-       if (type_flags & DST_TYPE_HAS_TS188)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188);
-       if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
-       if (type_flags & DST_TYPE_HAS_TS204)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
-       if (type_flags & DST_TYPE_HAS_VLF)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF);
-       if (type_flags & DST_TYPE_HAS_SYMDIV)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
-       if (type_flags & DST_TYPE_HAS_FW_1)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
-       if (type_flags & DST_TYPE_HAS_FW_2)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
-       if (type_flags & DST_TYPE_HAS_FW_3)
-               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
-       dprintk(verbose, DST_ERROR, 0, "\n");
-}
-
-
-static int dst_type_print(struct dst_state *state, u8 type)
-{
-       char *otype;
-       switch (type) {
-       case DST_TYPE_IS_SAT:
-               otype = "satellite";
-               break;
-
-       case DST_TYPE_IS_TERR:
-               otype = "terrestrial";
-               break;
-
-       case DST_TYPE_IS_CABLE:
-               otype = "cable";
-               break;
-
-       case DST_TYPE_IS_ATSC:
-               otype = "atsc";
-               break;
-
-       default:
-               dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
-               return -EINVAL;
-       }
-       dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
-
-       return 0;
-}
-
-static struct tuner_types tuner_list[] = {
-       {
-               .tuner_type = TUNER_TYPE_L64724,
-               .tuner_name = "L 64724",
-               .board_name = "UNKNOWN",
-               .fw_name    = "UNKNOWN"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_STV0299,
-               .tuner_name = "STV 0299",
-               .board_name = "VP1020",
-               .fw_name    = "DST-MOT"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_STV0299,
-               .tuner_name = "STV 0299",
-               .board_name = "VP1020",
-               .fw_name    = "DST-03T"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_MB86A15,
-               .tuner_name = "MB 86A15",
-               .board_name = "VP1022",
-               .fw_name    = "DST-03T"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_MB86A15,
-               .tuner_name = "MB 86A15",
-               .board_name = "VP1025",
-               .fw_name    = "DST-03T"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_STV0299,
-               .tuner_name = "STV 0299",
-               .board_name = "VP1030",
-               .fw_name    = "DST-CI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_STV0299,
-               .tuner_name = "STV 0299",
-               .board_name = "VP1030",
-               .fw_name    = "DSTMCI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP2021",
-               .fw_name    = "DCTNEW"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP2030",
-               .fw_name    = "DCT-CI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP2031",
-               .fw_name    = "DCT-CI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP2040",
-               .fw_name    = "DCT-CI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP3020",
-               .fw_name    = "DTTFTA"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP3021",
-               .fw_name    = "DTTFTA"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_TDA10046,
-               .tuner_name = "TDA10046",
-               .board_name = "VP3040",
-               .fw_name    = "DTT-CI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_UNKNOWN,
-               .tuner_name = "UNKNOWN",
-               .board_name = "VP3051",
-               .fw_name    = "DTTNXT"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_NXT200x,
-               .tuner_name = "NXT200x",
-               .board_name = "VP3220",
-               .fw_name    = "ATSCDI"
-       },
-
-       {
-               .tuner_type = TUNER_TYPE_NXT200x,
-               .tuner_name = "NXT200x",
-               .board_name = "VP3250",
-               .fw_name    = "ATSCAD"
-       },
-};
-
-/*
-       Known cards list
-       Satellite
-       -------------------
-                 200103A
-       VP-1020   DST-MOT       LG(old), TS=188
-
-       VP-1020   DST-03T       LG(new), TS=204
-       VP-1022   DST-03T       LG(new), TS=204
-       VP-1025   DST-03T       LG(new), TS=204
-
-       VP-1030   DSTMCI,       LG(new), TS=188
-       VP-1032   DSTMCI,       LG(new), TS=188
-
-       Cable
-       -------------------
-       VP-2030   DCT-CI,       Samsung, TS=204
-       VP-2021   DCT-CI,       Unknown, TS=204
-       VP-2031   DCT-CI,       Philips, TS=188
-       VP-2040   DCT-CI,       Philips, TS=188, with CA daughter board
-       VP-2040   DCT-CI,       Philips, TS=204, without CA daughter board
-
-       Terrestrial
-       -------------------
-       VP-3050  DTTNXT                  TS=188
-       VP-3040  DTT-CI,        Philips, TS=188
-       VP-3040  DTT-CI,        Philips, TS=204
-
-       ATSC
-       -------------------
-       VP-3220  ATSCDI,                 TS=188
-       VP-3250  ATSCAD,                 TS=188
-
-*/
-
-static struct dst_types dst_tlist[] = {
-       {
-               .device_id = "200103A",
-               .offset = 0,
-               .dst_type =  DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },      /*      obsolete        */
-
-       {
-               .device_id = "DST-020",
-               .offset = 0,
-               .dst_type =  DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },      /*      obsolete        */
-
-       {
-               .device_id = "DST-030",
-               .offset =  0,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },      /*      obsolete        */
-
-       {
-               .device_id = "DST-03T",
-               .offset = 0,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
-               .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
-                                                        | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
-               .tuner_type = TUNER_TYPE_MULTI
-        },
-
-       {
-               .device_id = "DST-MOT",
-               .offset =  0,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },      /*      obsolete        */
-
-       {
-               .device_id = "DST-CI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
-               .dst_feature = DST_TYPE_HAS_CA,
-               .tuner_type = 0
-       },      /*      An OEM board    */
-
-       {
-               .device_id = "DSTMCI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
-               .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
-                                                       | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
-               .tuner_type = TUNER_TYPE_MULTI
-       },
-
-       {
-               .device_id = "DSTFCI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_SAT,
-               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },      /* unknown to vendor    */
-
-       {
-               .device_id = "DCT-CI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_CABLE,
-               .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
-               .dst_feature = DST_TYPE_HAS_CA,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "DCTNEW",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_CABLE,
-               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "DTT-CI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_TERR,
-               .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
-               .dst_feature = DST_TYPE_HAS_CA,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "DTTDIG",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_TERR,
-               .type_flags = DST_TYPE_HAS_FW_2,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "DTTNXT",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_TERR,
-               .type_flags = DST_TYPE_HAS_FW_2,
-               .dst_feature = DST_TYPE_HAS_ANALOG,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "ATSCDI",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_ATSC,
-               .type_flags = DST_TYPE_HAS_FW_2,
-               .dst_feature = 0,
-               .tuner_type = 0
-       },
-
-       {
-               .device_id = "ATSCAD",
-               .offset = 1,
-               .dst_type = DST_TYPE_IS_ATSC,
-               .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
-               .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
-               .tuner_type = 0
-       },
-
-       { }
-
-};
-
-static int dst_get_mac(struct dst_state *state)
-{
-       u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       get_mac[7] = dst_check_sum(get_mac, 7);
-       if (dst_command(state, get_mac, 8) < 0) {
-               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
-               return -1;
-       }
-       memset(&state->mac_address, '\0', 8);
-       memcpy(&state->mac_address, &state->rxbuffer, 6);
-       dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address);
-
-       return 0;
-}
-
-static int dst_fw_ver(struct dst_state *state)
-{
-       u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       get_ver[7] = dst_check_sum(get_ver, 7);
-       if (dst_command(state, get_ver, 8) < 0) {
-               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
-               return -1;
-       }
-       memcpy(&state->fw_version, &state->rxbuffer, 8);
-       dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
-               state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
-               state->fw_version[1],
-               state->fw_version[5], state->fw_version[6],
-               state->fw_version[4], state->fw_version[3], state->fw_version[2]);
-
-       return 0;
-}
-
-static int dst_card_type(struct dst_state *state)
-{
-       int j;
-       struct tuner_types *p_tuner_list = NULL;
-
-       u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       get_type[7] = dst_check_sum(get_type, 7);
-       if (dst_command(state, get_type, 8) < 0) {
-               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
-               return -1;
-       }
-       memset(&state->card_info, '\0', 8);
-       memcpy(&state->card_info, &state->rxbuffer, 7);
-       dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
-
-       for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
-               if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
-                       state->tuner_type = p_tuner_list->tuner_type;
-                       dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
-                               p_tuner_list->tuner_name, p_tuner_list->tuner_type);
-               }
-       }
-
-       return 0;
-}
-
-static int dst_get_vendor(struct dst_state *state)
-{
-       u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       get_vendor[7] = dst_check_sum(get_vendor, 7);
-       if (dst_command(state, get_vendor, 8) < 0) {
-               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
-               return -1;
-       }
-       memset(&state->vendor, '\0', 8);
-       memcpy(&state->vendor, &state->rxbuffer, 7);
-       dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
-
-       return 0;
-}
-
-static void debug_dst_buffer(struct dst_state *state)
-{
-       int i;
-
-       if (verbose > 2) {
-               printk("%s: [", __func__);
-               for (i = 0; i < 8; i++)
-                       printk(" %02x", state->rxbuffer[i]);
-               printk("]\n");
-       }
-}
-
-static int dst_check_stv0299(struct dst_state *state)
-{
-       u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-       check_stv0299[7] = dst_check_sum(check_stv0299, 7);
-       if (dst_command(state, check_stv0299, 8) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
-               return -1;
-       }
-       debug_dst_buffer(state);
-
-       if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
-               dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
-               state->tuner_type = TUNER_TYPE_STV0299;
-               return 0;
-       }
-
-       return -1;
-}
-
-static int dst_check_mb86a15(struct dst_state *state)
-{
-       u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-       check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
-       if (dst_command(state, check_mb86a15, 8) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
-               return -1;
-       }
-       debug_dst_buffer(state);
-
-       if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
-               state->tuner_type = TUNER_TYPE_MB86A15;
-               return 0;
-       }
-
-       return -1;
-}
-
-static int dst_get_tuner_info(struct dst_state *state)
-{
-       u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-       get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
-       get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
-       dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
-       if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
-               if (dst_command(state, get_tuner_1, 8) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
-                       goto force;
-               }
-       } else {
-               if (dst_command(state, get_tuner_2, 8) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
-                       goto force;
-               }
-       }
-       memcpy(&state->board_info, &state->rxbuffer, 8);
-       if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
-               dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
-       }
-       if (state->board_info[0] == 0xbc) {
-               if (state->dst_type != DST_TYPE_IS_ATSC)
-                       state->type_flags |= DST_TYPE_HAS_TS188;
-               else
-                       state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
-
-               if (state->board_info[1] == 0x01) {
-                       state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
-                       dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");
-               }
-       }
-
-       return 0;
-force:
-       if (!strncmp(state->fw_name, "DCT-CI", 6)) {
-               state->type_flags |= DST_TYPE_HAS_TS204;
-               dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);
-       }
-
-       return -1;
-}
-
-static int dst_get_device_id(struct dst_state *state)
-{
-       u8 reply;
-
-       int i, j;
-       struct dst_types *p_dst_type = NULL;
-       struct tuner_types *p_tuner_list = NULL;
-
-       u8 use_dst_type = 0;
-       u32 use_type_flags = 0;
-
-       static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
-
-       state->tuner_type = 0;
-       device_type[7] = dst_check_sum(device_type, 7);
-
-       if (write_dst(state, device_type, FIXED_COMM))
-               return -1;              /*      Write failed            */
-       if ((dst_pio_disable(state)) < 0)
-               return -1;
-       if (read_dst(state, &reply, GET_ACK))
-               return -1;              /*      Read failure            */
-       if (reply != ACK) {
-               dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
-               return -1;              /*      Unack'd write           */
-       }
-       if (!dst_wait_dst_ready(state, DEVICE_INIT))
-               return -1;              /*      DST not ready yet       */
-       if (read_dst(state, state->rxbuffer, FIXED_COMM))
-               return -1;
-
-       dst_pio_disable(state);
-       if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
-               dprintk(verbose, DST_INFO, 1, "Checksum failure!");
-               return -1;              /*      Checksum failure        */
-       }
-       state->rxbuffer[7] = '\0';
-
-       for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
-               if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
-                       use_type_flags = p_dst_type->type_flags;
-                       use_dst_type = p_dst_type->dst_type;
-
-                       /*      Card capabilities       */
-                       state->dst_hw_cap = p_dst_type->dst_feature;
-                       dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);
-                       strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
-                       /*      Multiple tuners         */
-                       if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
-                               switch (use_dst_type) {
-                               case DST_TYPE_IS_SAT:
-                                       /*      STV0299 check   */
-                                       if (dst_check_stv0299(state) < 0) {
-                                               dprintk(verbose, DST_ERROR, 1, "Unsupported");
-                                               state->tuner_type = TUNER_TYPE_MB86A15;
-                                       }
-                                       break;
-                               default:
-                                       break;
-                               }
-                               if (dst_check_mb86a15(state) < 0)
-                                       dprintk(verbose, DST_ERROR, 1, "Unsupported");
-                       /*      Single tuner            */
-                       } else {
-                               state->tuner_type = p_dst_type->tuner_type;
-                       }
-                       for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
-                               if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
-                                       p_tuner_list->tuner_type == state->tuner_type) {
-                                       dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",
-                                               p_dst_type->device_id, p_tuner_list->tuner_name);
-                               }
-                       }
-                       break;
-               }
-       }
-
-       if (i >= ARRAY_SIZE(dst_tlist)) {
-               dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
-               dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
-               use_dst_type = DST_TYPE_IS_SAT;
-               use_type_flags = DST_TYPE_HAS_SYMDIV;
-       }
-       dst_type_print(state, use_dst_type);
-       state->type_flags = use_type_flags;
-       state->dst_type = use_dst_type;
-       dst_type_flags_print(state);
-
-       return 0;
-}
-
-static int dst_probe(struct dst_state *state)
-{
-       mutex_init(&state->dst_mutex);
-       if (dst_addons & DST_TYPE_HAS_CA) {
-               if ((rdc_8820_reset(state)) < 0) {
-                       dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
-                       return -1;
-               }
-               msleep(4000);
-       } else {
-               msleep(100);
-       }
-       if ((dst_comm_init(state)) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
-               return -1;
-       }
-       msleep(100);
-       if (dst_get_device_id(state) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "unknown device.");
-               return -1;
-       }
-       if (dst_get_mac(state) < 0) {
-               dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
-       }
-       if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
-               if (dst_get_tuner_info(state) < 0)
-                       dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
-       }
-       if (state->type_flags & DST_TYPE_HAS_TS204) {
-               dst_packsize(state, 204);
-       }
-       if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
-               if (dst_fw_ver(state) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
-                       return 0;
-               }
-               if (dst_card_type(state) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
-                       return 0;
-               }
-               if (dst_get_vendor(state) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
-                       return 0;
-               }
-       }
-
-       return 0;
-}
-
-static int dst_command(struct dst_state *state, u8 *data, u8 len)
-{
-       u8 reply;
-
-       mutex_lock(&state->dst_mutex);
-       if ((dst_comm_init(state)) < 0) {
-               dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
-               goto error;
-       }
-       if (write_dst(state, data, len)) {
-               dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");
-               if ((dst_error_recovery(state)) < 0) {
-                       dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
-                       goto error;
-               }
-               goto error;
-       }
-       if ((dst_pio_disable(state)) < 0) {
-               dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
-               goto error;
-       }
-       if (state->type_flags & DST_TYPE_HAS_FW_1)
-               mdelay(3);
-       if (read_dst(state, &reply, GET_ACK)) {
-               dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
-               if ((dst_error_recovery(state)) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
-                       goto error;
-               }
-               goto error;
-       }
-       if (reply != ACK) {
-               dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
-               goto error;
-       }
-       if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
-               goto error;
-       if (state->type_flags & DST_TYPE_HAS_FW_1)
-               mdelay(3);
-       else
-               udelay(2000);
-       if (!dst_wait_dst_ready(state, NO_DELAY))
-               goto error;
-       if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
-               dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
-               if ((dst_error_recovery(state)) < 0) {
-                       dprintk(verbose, DST_INFO, 1, "Recovery failed.");
-                       goto error;
-               }
-               goto error;
-       }
-       if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
-               dprintk(verbose, DST_INFO, 1, "checksum failure");
-               goto error;
-       }
-       mutex_unlock(&state->dst_mutex);
-       return 0;
-
-error:
-       mutex_unlock(&state->dst_mutex);
-       return -EIO;
-
-}
-
-static int dst_get_signal(struct dst_state *state)
-{
-       int retval;
-       u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
-       //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
-       if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
-               state->decode_lock = state->decode_strength = state->decode_snr = 0;
-               return 0;
-       }
-       if (0 == (state->diseq_flags & HAS_LOCK)) {
-               state->decode_lock = state->decode_strength = state->decode_snr = 0;
-               return 0;
-       }
-       if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
-               retval = dst_command(state, get_signal, 8);
-               if (retval < 0)
-                       return retval;
-               if (state->dst_type == DST_TYPE_IS_SAT) {
-                       state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
-                       state->decode_strength = state->rxbuffer[5] << 8;
-                       state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
-               } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
-                       state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
-                       state->decode_strength = state->rxbuffer[4] << 8;
-                       state->decode_snr = state->rxbuffer[3] << 8;
-               } else if (state->dst_type == DST_TYPE_IS_ATSC) {
-                       state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
-                       state->decode_strength = state->rxbuffer[4] << 8;
-                       state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
-               }
-               state->cur_jiff = jiffies;
-       }
-       return 0;
-}
-
-static int dst_tone_power_cmd(struct dst_state *state)
-{
-       u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
-
-       if (state->dst_type != DST_TYPE_IS_SAT)
-               return -EOPNOTSUPP;
-       paket[4] = state->tx_tuna[4];
-       paket[2] = state->tx_tuna[2];
-       paket[3] = state->tx_tuna[3];
-       paket[7] = dst_check_sum (paket, 7);
-       return dst_command(state, paket, 8);
-}
-
-static int dst_get_tuna(struct dst_state *state)
-{
-       int retval;
-
-       if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
-               return 0;
-       state->diseq_flags &= ~(HAS_LOCK);
-       if (!dst_wait_dst_ready(state, NO_DELAY))
-               return -EIO;
-       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
-               !(state->dst_type == DST_TYPE_IS_ATSC))
-
-               retval = read_dst(state, state->rx_tuna, 10);
-       else
-               retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
-       if (retval < 0) {
-               dprintk(verbose, DST_DEBUG, 1, "read not successful");
-               return retval;
-       }
-       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
-          !(state->dst_type == DST_TYPE_IS_ATSC)) {
-
-               if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
-                       dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
-                       return -EIO;
-               }
-       } else {
-               if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
-                       dprintk(verbose, DST_INFO, 1, "checksum failure? ");
-                       return -EIO;
-               }
-       }
-       if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
-               return 0;
-       if (state->dst_type == DST_TYPE_IS_SAT) {
-               state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
-       } else {
-               state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
-       }
-       state->decode_freq = state->decode_freq * 1000;
-       state->decode_lock = 1;
-       state->diseq_flags |= HAS_LOCK;
-
-       return 1;
-}
-
-static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-
-static int dst_write_tuna(struct dvb_frontend *fe)
-{
-       struct dst_state *state = fe->demodulator_priv;
-       int retval;
-       u8 reply;
-
-       dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
-       state->decode_freq = 0;
-       state->decode_lock = state->decode_strength = state->decode_snr = 0;
-       if (state->dst_type == DST_TYPE_IS_SAT) {
-               if (!(state->diseq_flags & HAS_POWER))
-                       dst_set_voltage(fe, SEC_VOLTAGE_13);
-       }
-       state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
-       mutex_lock(&state->dst_mutex);
-       if ((dst_comm_init(state)) < 0) {
-               dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
-               goto error;
-       }
-//     if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
-       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
-               (!(state->dst_type == DST_TYPE_IS_ATSC))) {
-
-               state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
-               retval = write_dst(state, &state->tx_tuna[0], 10);
-       } else {
-               state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
-               retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
-       }
-       if (retval < 0) {
-               dst_pio_disable(state);
-               dprintk(verbose, DST_DEBUG, 1, "write not successful");
-               goto werr;
-       }
-       if ((dst_pio_disable(state)) < 0) {
-               dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
-               goto error;
-       }
-       if ((read_dst(state, &reply, GET_ACK) < 0)) {
-               dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
-               goto error;
-       }
-       if (reply != ACK) {
-               dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
-               goto error;
-       }
-       state->diseq_flags |= ATTEMPT_TUNE;
-       retval = dst_get_tuna(state);
-werr:
-       mutex_unlock(&state->dst_mutex);
-       return retval;
-
-error:
-       mutex_unlock(&state->dst_mutex);
-       return -EIO;
-}
-
-/*
- * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
- * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
- * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
- * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
- * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
- * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
- * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
- * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
- * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
- * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
- * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
- */
-
-static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct dst_state *state = fe->demodulator_priv;
-       u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
-
-       if (state->dst_type != DST_TYPE_IS_SAT)
-               return -EOPNOTSUPP;
-       if (cmd->msg_len > 0 && cmd->msg_len < 5)
-               memcpy(&paket[3], cmd->msg, cmd->msg_len);
-       else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
-               memcpy(&paket[2], cmd->msg, cmd->msg_len);
-       else
-               return -EINVAL;
-       paket[7] = dst_check_sum(&paket[0], 7);
-       return dst_command(state, paket, 8);
-}
-
-static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       int need_cmd, retval = 0;
-       struct dst_state *state = fe->demodulator_priv;
-
-       state->voltage = voltage;
-       if (state->dst_type != DST_TYPE_IS_SAT)
-               return -EOPNOTSUPP;
-
-       need_cmd = 0;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-       case SEC_VOLTAGE_18:
-               if ((state->diseq_flags & HAS_POWER) == 0)
-                       need_cmd = 1;
-               state->diseq_flags |= HAS_POWER;
-               state->tx_tuna[4] = 0x01;
-               break;
-       case SEC_VOLTAGE_OFF:
-               need_cmd = 1;
-               state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
-               state->tx_tuna[4] = 0x00;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (need_cmd)
-               retval = dst_tone_power_cmd(state);
-
-       return retval;
-}
-
-static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       state->tone = tone;
-       if (state->dst_type != DST_TYPE_IS_SAT)
-               return -EOPNOTSUPP;
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
-                   state->tx_tuna[2] = 0x00;
-               else
-                   state->tx_tuna[2] = 0xff;
-               break;
-
-       case SEC_TONE_ON:
-               state->tx_tuna[2] = 0x02;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return dst_tone_power_cmd(state);
-}
-
-static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       if (state->dst_type != DST_TYPE_IS_SAT)
-               return -EOPNOTSUPP;
-       state->minicmd = minicmd;
-       switch (minicmd) {
-       case SEC_MINI_A:
-               state->tx_tuna[3] = 0x02;
-               break;
-       case SEC_MINI_B:
-               state->tx_tuna[3] = 0xff;
-               break;
-       }
-       return dst_tone_power_cmd(state);
-}
-
-
-static int dst_init(struct dvb_frontend *fe)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
-       static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
-       static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
-       static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
-       static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
-       static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
-       static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
-
-       state->inversion = INVERSION_OFF;
-       state->voltage = SEC_VOLTAGE_13;
-       state->tone = SEC_TONE_OFF;
-       state->diseq_flags = 0;
-       state->k22 = 0x02;
-       state->bandwidth = 7000000;
-       state->cur_jiff = jiffies;
-       if (state->dst_type == DST_TYPE_IS_SAT)
-               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
-       else if (state->dst_type == DST_TYPE_IS_TERR)
-               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
-       else if (state->dst_type == DST_TYPE_IS_CABLE)
-               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
-       else if (state->dst_type == DST_TYPE_IS_ATSC)
-               memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
-
-       return 0;
-}
-
-static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       *status = 0;
-       if (state->diseq_flags & HAS_LOCK) {
-//             dst_get_signal(state);  // don't require(?) to ask MCU
-               if (state->decode_lock)
-                       *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
-       }
-
-       return 0;
-}
-
-static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       int retval = dst_get_signal(state);
-       *strength = state->decode_strength;
-
-       return retval;
-}
-
-static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct dst_state *state = fe->demodulator_priv;
-
-       int retval = dst_get_signal(state);
-       *snr = state->decode_snr;
-
-       return retval;
-}
-
-static int dst_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       int retval = -EINVAL;
-       struct dst_state *state = fe->demodulator_priv;
-
-       if (p != NULL) {
-               retval = dst_set_freq(state, p->frequency);
-               if(retval != 0)
-                       return retval;
-               dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
-
-               if (state->dst_type == DST_TYPE_IS_SAT) {
-                       if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
-                               dst_set_inversion(state, p->inversion);
-                       dst_set_fec(state, p->fec_inner);
-                       dst_set_symbolrate(state, p->symbol_rate);
-                       dst_set_polarization(state);
-                       dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
-
-               } else if (state->dst_type == DST_TYPE_IS_TERR)
-                       dst_set_bandwidth(state, p->bandwidth_hz);
-               else if (state->dst_type == DST_TYPE_IS_CABLE) {
-                       dst_set_fec(state, p->fec_inner);
-                       dst_set_symbolrate(state, p->symbol_rate);
-                       dst_set_modulation(state, p->modulation);
-               }
-               retval = dst_write_tuna(fe);
-       }
-
-       return retval;
-}
-
-static int dst_tune_frontend(struct dvb_frontend* fe,
-                           bool re_tune,
-                           unsigned int mode_flags,
-                           unsigned int *delay,
-                           fe_status_t *status)
-{
-       struct dst_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       if (re_tune) {
-               dst_set_freq(state, p->frequency);
-               dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
-
-               if (state->dst_type == DST_TYPE_IS_SAT) {
-                       if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
-                               dst_set_inversion(state, p->inversion);
-                       dst_set_fec(state, p->fec_inner);
-                       dst_set_symbolrate(state, p->symbol_rate);
-                       dst_set_polarization(state);
-                       dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
-
-               } else if (state->dst_type == DST_TYPE_IS_TERR)
-                       dst_set_bandwidth(state, p->bandwidth_hz);
-               else if (state->dst_type == DST_TYPE_IS_CABLE) {
-                       dst_set_fec(state, p->fec_inner);
-                       dst_set_symbolrate(state, p->symbol_rate);
-                       dst_set_modulation(state, p->modulation);
-               }
-               dst_write_tuna(fe);
-       }
-
-       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
-               dst_read_status(fe, status);
-
-       *delay = HZ/10;
-       return 0;
-}
-
-static int dst_get_tuning_algo(struct dvb_frontend *fe)
-{
-       return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
-}
-
-static int dst_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dst_state *state = fe->demodulator_priv;
-
-       p->frequency = state->decode_freq;
-       if (state->dst_type == DST_TYPE_IS_SAT) {
-               if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
-                       p->inversion = state->inversion;
-               p->symbol_rate = state->symbol_rate;
-               p->fec_inner = dst_get_fec(state);
-       } else if (state->dst_type == DST_TYPE_IS_TERR) {
-               p->bandwidth_hz = state->bandwidth;
-       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
-               p->symbol_rate = state->symbol_rate;
-               p->fec_inner = dst_get_fec(state);
-               p->modulation = dst_get_modulation(state);
-       }
-
-       return 0;
-}
-
-static void dst_release(struct dvb_frontend *fe)
-{
-       struct dst_state *state = fe->demodulator_priv;
-       if (state->dst_ca) {
-               dvb_unregister_device(state->dst_ca);
-#ifdef CONFIG_MEDIA_ATTACH
-               symbol_put(dst_ca_attach);
-#endif
-       }
-       kfree(state);
-}
-
-static struct dvb_frontend_ops dst_dvbt_ops;
-static struct dvb_frontend_ops dst_dvbs_ops;
-static struct dvb_frontend_ops dst_dvbc_ops;
-static struct dvb_frontend_ops dst_atsc_ops;
-
-struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
-{
-       /* check if the ASIC is there */
-       if (dst_probe(state) < 0) {
-               kfree(state);
-               return NULL;
-       }
-       /* determine settings based on type */
-       /* create dvb_frontend */
-       switch (state->dst_type) {
-       case DST_TYPE_IS_TERR:
-               memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       case DST_TYPE_IS_CABLE:
-               memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       case DST_TYPE_IS_SAT:
-               memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       case DST_TYPE_IS_ATSC:
-               memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       default:
-               dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
-               kfree(state);
-               return NULL;
-       }
-       state->frontend.demodulator_priv = state;
-
-       return state;                           /*      Manu (DST is a card not a frontend)     */
-}
-
-EXPORT_SYMBOL(dst_attach);
-
-static struct dvb_frontend_ops dst_dvbt_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "DST DVB-T",
-               .frequency_min = 137000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 166667,
-               .caps = FE_CAN_FEC_AUTO                 |
-                       FE_CAN_QAM_AUTO                 |
-                       FE_CAN_QAM_16                   |
-                       FE_CAN_QAM_32                   |
-                       FE_CAN_QAM_64                   |
-                       FE_CAN_QAM_128                  |
-                       FE_CAN_QAM_256                  |
-                       FE_CAN_TRANSMISSION_MODE_AUTO   |
-                       FE_CAN_GUARD_INTERVAL_AUTO
-       },
-
-       .release = dst_release,
-       .init = dst_init,
-       .tune = dst_tune_frontend,
-       .set_frontend = dst_set_frontend,
-       .get_frontend = dst_get_frontend,
-       .get_frontend_algo = dst_get_tuning_algo,
-       .read_status = dst_read_status,
-       .read_signal_strength = dst_read_signal_strength,
-       .read_snr = dst_read_snr,
-};
-
-static struct dvb_frontend_ops dst_dvbs_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name = "DST DVB-S",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1000,     /* kHz for QPSK frontends */
-               .frequency_tolerance = 29500,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-       /*     . symbol_rate_tolerance  =       ???,*/
-               .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
-       },
-
-       .release = dst_release,
-       .init = dst_init,
-       .tune = dst_tune_frontend,
-       .set_frontend = dst_set_frontend,
-       .get_frontend = dst_get_frontend,
-       .get_frontend_algo = dst_get_tuning_algo,
-       .read_status = dst_read_status,
-       .read_signal_strength = dst_read_signal_strength,
-       .read_snr = dst_read_snr,
-       .diseqc_send_burst = dst_send_burst,
-       .diseqc_send_master_cmd = dst_set_diseqc,
-       .set_voltage = dst_set_voltage,
-       .set_tone = dst_set_tone,
-};
-
-static struct dvb_frontend_ops dst_dvbc_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-               .name = "DST DVB-C",
-               .frequency_stepsize = 62500,
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_QAM_16   |
-                       FE_CAN_QAM_32   |
-                       FE_CAN_QAM_64   |
-                       FE_CAN_QAM_128  |
-                       FE_CAN_QAM_256
-       },
-
-       .release = dst_release,
-       .init = dst_init,
-       .tune = dst_tune_frontend,
-       .set_frontend = dst_set_frontend,
-       .get_frontend = dst_get_frontend,
-       .get_frontend_algo = dst_get_tuning_algo,
-       .read_status = dst_read_status,
-       .read_signal_strength = dst_read_signal_strength,
-       .read_snr = dst_read_snr,
-};
-
-static struct dvb_frontend_ops dst_atsc_ops = {
-       .delsys = { SYS_ATSC },
-       .info = {
-               .name = "DST ATSC",
-               .frequency_stepsize = 62500,
-               .frequency_min = 510000000,
-               .frequency_max = 858000000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-
-       .release = dst_release,
-       .init = dst_init,
-       .tune = dst_tune_frontend,
-       .set_frontend = dst_set_frontend,
-       .get_frontend = dst_get_frontend,
-       .get_frontend_algo = dst_get_tuning_algo,
-       .read_status = dst_read_status,
-       .read_signal_strength = dst_read_signal_strength,
-       .read_snr = dst_read_snr,
-};
-
-MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
-MODULE_AUTHOR("Jamie Honan, Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
deleted file mode 100644 (file)
index ee3884f..0000000
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
-       CA-driver for TwinHan DST Frontend/Card
-
-       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/dvb/ca.h>
-#include "dvbdev.h"
-#include "dvb_frontend.h"
-#include "dst_ca.h"
-#include "dst_common.h"
-
-#define DST_CA_ERROR           0
-#define DST_CA_NOTICE          1
-#define DST_CA_INFO            2
-#define DST_CA_DEBUG           3
-
-#define dprintk(x, y, z, format, arg...) do {                                          \
-       if (z) {                                                                        \
-               if      ((x > DST_CA_ERROR) && (x > y))                                 \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);  \
-               else if ((x > DST_CA_NOTICE) && (x > y))                                \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((x > DST_CA_INFO) && (x > y))                                  \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
-               else if ((x > DST_CA_DEBUG) && (x > y))                                 \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (x > y)                                                              \
-                       printk(format, ## arg);                                         \
-       }                                                                               \
-} while(0)
-
-
-static DEFINE_MUTEX(dst_ca_mutex);
-static unsigned int verbose = 5;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-
-/*     Need some more work     */
-static int ca_set_slot_descr(void)
-{
-       /*      We could make this more graceful ?      */
-       return -EOPNOTSUPP;
-}
-
-/*     Need some more work     */
-static int ca_set_pid(void)
-{
-       /*      We could make this more graceful ?      */
-       return -EOPNOTSUPP;
-}
-
-static void put_command_and_length(u8 *data, int command, int length)
-{
-       data[0] = (command >> 16) & 0xff;
-       data[1] = (command >> 8) & 0xff;
-       data[2] = command & 0xff;
-       data[3] = length;
-}
-
-static void put_checksum(u8 *check_string, int length)
-{
-       dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
-       dprintk(verbose, DST_CA_DEBUG, 1, "  -> string length : 0x%02x", length);
-       check_string[length] = dst_check_sum (check_string, length);
-       dprintk(verbose, DST_CA_DEBUG, 1, "  -> checksum      : 0x%02x", check_string[length]);
-}
-
-static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
-{
-       u8 reply;
-
-       mutex_lock(&state->dst_mutex);
-       dst_comm_init(state);
-       msleep(65);
-
-       if (write_dst(state, data, len)) {
-               dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
-               dst_error_recovery(state);
-               goto error;
-       }
-       if ((dst_pio_disable(state)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
-               goto error;
-       }
-       if (read_dst(state, &reply, GET_ACK) < 0) {
-               dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
-               dst_error_recovery(state);
-               goto error;
-       }
-       if (read) {
-               if (! dst_wait_dst_ready(state, LONG_DELAY)) {
-                       dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
-                       goto error;
-               }
-               if (read_dst(state, ca_string, 128) < 0) {      /*      Try to make this dynamic        */
-                       dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
-                       dst_error_recovery(state);
-                       goto error;
-               }
-       }
-       mutex_unlock(&state->dst_mutex);
-       return 0;
-
-error:
-       mutex_unlock(&state->dst_mutex);
-       return -EIO;
-}
-
-
-static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
-{
-       u8 dst_ca_comm_err = 0;
-
-       while (dst_ca_comm_err < RETRIES) {
-               dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
-               if (dst_ci_command(state, data, ca_string, len, read)) {        // If error
-                       dst_error_recovery(state);
-                       dst_ca_comm_err++; // work required here.
-               } else {
-                       break;
-               }
-       }
-
-       if(dst_ca_comm_err == RETRIES)
-               return -1;
-
-       return 0;
-}
-
-
-
-static int ca_get_app_info(struct dst_state *state)
-{
-       int length, str_length;
-       static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
-
-       put_checksum(&command[0], command[0]);
-       if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
-               return -1;
-       }
-       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
-       dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
-       dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
-               state->messages[7], (state->messages[8] << 8) | state->messages[9],
-               (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12]));
-       dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
-
-       // Transform dst message to correct application_info message
-       length = state->messages[5];
-       str_length = length - 6;
-       if (str_length < 0) {
-               str_length = 0;
-               dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering.");
-       }
-
-       // First, the command and length fields
-       put_command_and_length(&state->messages[0], CA_APP_INFO, length);
-
-       // Copy application_type, application_manufacturer and manufacturer_code
-       memcpy(&state->messages[4], &state->messages[7], 5);
-
-       // Set string length and copy string
-       state->messages[9] = str_length;
-       memcpy(&state->messages[10], &state->messages[12], str_length);
-
-       return 0;
-}
-
-static int ca_get_ca_info(struct dst_state *state)
-{
-       int srcPtr, dstPtr, i, num_ids;
-       static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff};
-       const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7;
-
-       put_checksum(&slot_command[0], slot_command[0]);
-       if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
-               return -1;
-       }
-       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
-
-       // Print raw data
-       dprintk(verbose, DST_CA_INFO, 0, " DST data = [");
-       for (i = 0; i < state->messages[0] + 1; i++) {
-               dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]);
-       }
-       dprintk(verbose, DST_CA_INFO, 0, "]\n");
-
-       // Set the command and length of the output
-       num_ids = state->messages[in_num_ids_pos];
-       if (num_ids >= 100) {
-               num_ids = 100;
-               dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering.");
-       }
-       put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2);
-
-       dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = [");
-       srcPtr = in_system_id_pos;
-       dstPtr = out_system_id_pos;
-       for(i = 0; i < num_ids; i++) {
-               dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]);
-               // Append to output
-               state->messages[dstPtr + 0] = state->messages[srcPtr + 0];
-               state->messages[dstPtr + 1] = state->messages[srcPtr + 1];
-               srcPtr += 2;
-               dstPtr += 2;
-       }
-       dprintk(verbose, DST_CA_INFO, 0, "]\n");
-
-       return 0;
-}
-
-static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
-{
-       int i;
-       u8 slot_cap[256];
-       static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
-
-       put_checksum(&slot_command[0], slot_command[0]);
-       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
-               return -1;
-       }
-       dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
-
-       /*      Will implement the rest soon            */
-
-       dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
-       dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
-       for (i = 0; i < slot_cap[0] + 1; i++)
-               dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
-       dprintk(verbose, DST_CA_INFO, 0, "\n");
-
-       p_ca_caps->slot_num = 1;
-       p_ca_caps->slot_type = 1;
-       p_ca_caps->descr_num = slot_cap[7];
-       p_ca_caps->descr_type = 1;
-
-       if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
-               return -EFAULT;
-
-       return 0;
-}
-
-/*     Need some more work     */
-static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
-{
-       return -EOPNOTSUPP;
-}
-
-
-static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
-{
-       int i;
-       static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
-
-       u8 *slot_info = state->messages;
-
-       put_checksum(&slot_command[0], 7);
-       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
-               return -1;
-       }
-       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
-
-       /*      Will implement the rest soon            */
-
-       dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
-       dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
-       for (i = 0; i < 8; i++)
-               dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
-       dprintk(verbose, DST_CA_INFO, 0, "\n");
-
-       if (slot_info[4] & 0x80) {
-               p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
-               p_ca_slot_info->num = 1;
-               p_ca_slot_info->type = CA_CI;
-       } else if (slot_info[4] & 0x40) {
-               p_ca_slot_info->flags = CA_CI_MODULE_READY;
-               p_ca_slot_info->num = 1;
-               p_ca_slot_info->type = CA_CI;
-       } else
-               p_ca_slot_info->flags = 0;
-
-       if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
-               return -EFAULT;
-
-       return 0;
-}
-
-
-static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
-{
-       u8 i = 0;
-       u32 command = 0;
-
-       if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
-               return -EFAULT;
-
-       if (p_ca_message->msg) {
-               dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]",
-                       3, p_ca_message->msg);
-
-               for (i = 0; i < 3; i++) {
-                       command = command | p_ca_message->msg[i];
-                       if (i < 2)
-                               command = command << 8;
-               }
-               dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
-
-               switch (command) {
-               case CA_APP_INFO:
-                       memcpy(p_ca_message->msg, state->messages, 128);
-                       if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
-                               return -EFAULT;
-                       break;
-               case CA_INFO:
-                       memcpy(p_ca_message->msg, state->messages, 128);
-                       if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
-                               return -EFAULT;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
-{
-       if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
-               hw_buffer->msg[2] = p_ca_message->msg[1];       /*      MSB     */
-               hw_buffer->msg[3] = p_ca_message->msg[2];       /*      LSB     */
-       } else {
-               if (length > 247) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
-                       return -1;
-               }
-               hw_buffer->msg[0] = (length & 0xff) + 7;
-               hw_buffer->msg[1] = 0x40;
-               hw_buffer->msg[2] = 0x03;
-               hw_buffer->msg[3] = 0x00;
-               hw_buffer->msg[4] = 0x03;
-               hw_buffer->msg[5] = length & 0xff;
-               hw_buffer->msg[6] = 0x00;
-
-               /*
-                *      Need to compute length for EN50221 section 8.3.2, for the time being
-                *      assuming 8.3.2 is not applicable
-                */
-               memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
-       }
-
-       return 0;
-}
-
-static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
-{
-       if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
-               dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
-               dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
-               rdc_reset_state(state);
-               return -1;
-       }
-       dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success.");
-
-       return 0;
-}
-
-static u32 asn_1_decode(u8 *asn_1_array)
-{
-       u8 length_field = 0, word_count = 0, count = 0;
-       u32 length = 0;
-
-       length_field = asn_1_array[0];
-       dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
-       if (length_field < 0x80) {
-               length = length_field & 0x7f;
-               dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
-       } else {
-               word_count = length_field & 0x7f;
-               for (count = 0; count < word_count; count++) {
-                       length = length  << 8;
-                       length += asn_1_array[count + 1];
-                       dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
-               }
-       }
-       return length;
-}
-
-static int debug_string(u8 *msg, u32 length, u32 offset)
-{
-       u32 i;
-
-       dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
-       for (i = offset; i < length; i++)
-               dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
-       dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
-
-       return 0;
-}
-
-
-static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
-{
-       u32 length = 0;
-       u8 tag_length = 8;
-
-       length = asn_1_decode(&p_ca_message->msg[3]);
-       dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
-       debug_string(&p_ca_message->msg[4], length, 0); /*      length is excluding tag & length        */
-
-       memset(hw_buffer->msg, '\0', length);
-       handle_dst_tag(state, p_ca_message, hw_buffer, length);
-       put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
-
-       debug_string(hw_buffer->msg, (length + tag_length), 0); /*      tags too        */
-       write_to_8820(state, hw_buffer, (length + tag_length), reply);
-
-       return 0;
-}
-
-
-/*     Board supports CA PMT reply ?           */
-static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
-{
-       int ca_pmt_reply_test = 0;
-
-       /*      Do test board                   */
-       /*      Not there yet but soon          */
-
-       /*      CA PMT Reply capable            */
-       if (ca_pmt_reply_test) {
-               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
-                       return -1;
-               }
-
-       /*      Process CA PMT Reply            */
-       /*      will implement soon             */
-               dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
-       }
-       /*      CA PMT Reply not capable        */
-       if (!ca_pmt_reply_test) {
-               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
-                       return -1;
-               }
-               dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
-       /*      put a dummy message             */
-
-       }
-       return 0;
-}
-
-static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
-{
-       int i = 0;
-
-       u32 command = 0;
-       struct ca_msg *hw_buffer;
-       int result = 0;
-
-       if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
-               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
-               return -ENOMEM;
-       }
-       dprintk(verbose, DST_CA_DEBUG, 1, " ");
-
-       if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
-               result = -EFAULT;
-               goto free_mem_and_exit;
-       }
-
-
-       if (p_ca_message->msg) {
-               /*      EN50221 tag     */
-               command = 0;
-
-               for (i = 0; i < 3; i++) {
-                       command = command | p_ca_message->msg[i];
-                       if (i < 2)
-                               command = command << 8;
-               }
-               dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
-
-               switch (command) {
-               case CA_PMT:
-                       dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
-                       if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {   // code simplification started
-                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
-                               result = -1;
-                               goto free_mem_and_exit;
-                       }
-                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
-                       break;
-               case CA_PMT_REPLY:
-                       dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
-                       /*      Have to handle the 2 basic types of cards here  */
-                       if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
-                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
-                               result = -1;
-                               goto free_mem_and_exit;
-                       }
-                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
-                       break;
-               case CA_APP_INFO_ENQUIRY:               // only for debugging
-                       dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
-
-                       if ((ca_get_app_info(state)) < 0) {
-                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
-                               result = -1;
-                               goto free_mem_and_exit;
-                       }
-                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
-                       break;
-               case CA_INFO_ENQUIRY:
-                       dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information");
-
-                       if ((ca_get_ca_info(state)) < 0) {
-                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !");
-                               result = -1;
-                               goto free_mem_and_exit;
-                       }
-                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !");
-                       break;
-               }
-       }
-free_mem_and_exit:
-       kfree (hw_buffer);
-
-       return result;
-}
-
-static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
-{
-       struct dvb_device *dvbdev;
-       struct dst_state *state;
-       struct ca_slot_info *p_ca_slot_info;
-       struct ca_caps *p_ca_caps;
-       struct ca_msg *p_ca_message;
-       void __user *arg = (void __user *)ioctl_arg;
-       int result = 0;
-
-       mutex_lock(&dst_ca_mutex);
-       dvbdev = file->private_data;
-       state = (struct dst_state *)dvbdev->priv;
-       p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
-       p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
-       p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
-       if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
-               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
-               result = -ENOMEM;
-               goto free_mem_and_exit;
-       }
-
-       /*      We have now only the standard ioctl's, the driver is upposed to handle internals.       */
-       switch (cmd) {
-       case CA_SEND_MSG:
-               dprintk(verbose, DST_CA_INFO, 1, " Sending message");
-               if ((ca_send_message(state, p_ca_message, arg)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               break;
-       case CA_GET_MSG:
-               dprintk(verbose, DST_CA_INFO, 1, " Getting message");
-               if ((ca_get_message(state, p_ca_message, arg)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
-               break;
-       case CA_RESET:
-               dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
-               dst_error_bailout(state);
-               msleep(4000);
-               break;
-       case CA_GET_SLOT_INFO:
-               dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
-               if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
-               break;
-       case CA_GET_CAP:
-               dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
-               if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
-               break;
-       case CA_GET_DESCR_INFO:
-               dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
-               if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
-               break;
-       case CA_SET_DESCR:
-               dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
-               if ((ca_set_slot_descr()) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
-               break;
-       case CA_SET_PID:
-               dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
-               if ((ca_set_pid()) < 0) {
-                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
-                       result = -1;
-                       goto free_mem_and_exit;
-               }
-               dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
-       default:
-               result = -EOPNOTSUPP;
-       };
- free_mem_and_exit:
-       kfree (p_ca_message);
-       kfree (p_ca_slot_info);
-       kfree (p_ca_caps);
-
-       mutex_unlock(&dst_ca_mutex);
-       return result;
-}
-
-static int dst_ca_open(struct inode *inode, struct file *file)
-{
-       dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
-       try_module_get(THIS_MODULE);
-
-       return 0;
-}
-
-static int dst_ca_release(struct inode *inode, struct file *file)
-{
-       dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
-       module_put(THIS_MODULE);
-
-       return 0;
-}
-
-static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
-{
-       ssize_t bytes_read = 0;
-
-       dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
-
-       return bytes_read;
-}
-
-static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
-{
-       dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
-
-       return 0;
-}
-
-static const struct file_operations dst_ca_fops = {
-       .owner = THIS_MODULE,
-       .unlocked_ioctl = dst_ca_ioctl,
-       .open = dst_ca_open,
-       .release = dst_ca_release,
-       .read = dst_ca_read,
-       .write = dst_ca_write,
-       .llseek = noop_llseek,
-};
-
-static struct dvb_device dvbdev_ca = {
-       .priv = NULL,
-       .users = 1,
-       .readers = 1,
-       .writers = 1,
-       .fops = &dst_ca_fops
-};
-
-struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
-{
-       struct dvb_device *dvbdev;
-
-       dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
-       if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
-               dst->dst_ca = dvbdev;
-               return dst->dst_ca;
-       }
-
-       return NULL;
-}
-
-EXPORT_SYMBOL(dst_ca_attach);
-
-MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h
deleted file mode 100644 (file)
index 59cd0dd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-       CA-driver for TwinHan DST Frontend/Card
-
-       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 _DST_CA_H_
-#define _DST_CA_H_
-
-#define RETRIES                        5
-
-
-#define        CA_APP_INFO_ENQUIRY     0x9f8020
-#define        CA_APP_INFO             0x9f8021
-#define        CA_ENTER_MENU           0x9f8022
-#define CA_INFO_ENQUIRY                0x9f8030
-#define        CA_INFO                 0x9f8031
-#define CA_PMT                 0x9f8032
-#define CA_PMT_REPLY           0x9f8033
-
-#define CA_CLOSE_MMI           0x9f8800
-#define CA_DISPLAY_CONTROL     0x9f8801
-#define CA_DISPLAY_REPLY       0x9f8802
-#define CA_TEXT_LAST           0x9f8803
-#define CA_TEXT_MORE           0x9f8804
-#define CA_KEYPAD_CONTROL      0x9f8805
-#define CA_KEYPRESS            0x9f8806
-
-#define CA_ENQUIRY             0x9f8807
-#define CA_ANSWER              0x9f8808
-#define CA_MENU_LAST           0x9f8809
-#define CA_MENU_MORE           0x9f880a
-#define CA_MENU_ANSWER         0x9f880b
-#define CA_LIST_LAST           0x9f880c
-#define CA_LIST_MORE           0x9f880d
-
-
-struct dst_ca_private {
-       struct dst_state *dst;
-       struct dvb_device *dvbdev;
-};
-
-
-#endif
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
deleted file mode 100644 (file)
index d70d98f..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-       Frontend-driver for TwinHan DST Frontend
-
-       Copyright (C) 2003 Jamie Honan
-       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 DST_COMMON_H
-#define DST_COMMON_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-#include "bt878.h"
-
-#include "dst_ca.h"
-
-
-#define NO_DELAY               0
-#define LONG_DELAY             1
-#define DEVICE_INIT            2
-
-#define DELAY                  1
-
-#define DST_TYPE_IS_SAT                0
-#define DST_TYPE_IS_TERR       1
-#define DST_TYPE_IS_CABLE      2
-#define DST_TYPE_IS_ATSC       3
-
-#define DST_TYPE_HAS_TS188     1
-#define DST_TYPE_HAS_TS204     2
-#define DST_TYPE_HAS_SYMDIV    4
-#define DST_TYPE_HAS_FW_1      8
-#define DST_TYPE_HAS_FW_2      16
-#define DST_TYPE_HAS_FW_3      32
-#define DST_TYPE_HAS_FW_BUILD  64
-#define DST_TYPE_HAS_OBS_REGS  128
-#define DST_TYPE_HAS_INC_COUNT 256
-#define DST_TYPE_HAS_MULTI_FE  512
-#define DST_TYPE_HAS_NEWTUNE_2 1024
-#define DST_TYPE_HAS_DBOARD    2048
-#define DST_TYPE_HAS_VLF       4096
-
-/*     Card capability list    */
-
-#define DST_TYPE_HAS_MAC       1
-#define DST_TYPE_HAS_DISEQC3   2
-#define DST_TYPE_HAS_DISEQC4   4
-#define DST_TYPE_HAS_DISEQC5   8
-#define DST_TYPE_HAS_MOTO      16
-#define DST_TYPE_HAS_CA                32
-#define        DST_TYPE_HAS_ANALOG     64      /*      Analog inputs   */
-#define DST_TYPE_HAS_SESSION   128
-
-#define TUNER_TYPE_MULTI       1
-#define TUNER_TYPE_UNKNOWN     2
-/*     DVB-S           */
-#define TUNER_TYPE_L64724      4
-#define TUNER_TYPE_STV0299     8
-#define TUNER_TYPE_MB86A15     16
-
-/*     DVB-T           */
-#define TUNER_TYPE_TDA10046    32
-
-/*     ATSC            */
-#define TUNER_TYPE_NXT200x     64
-
-
-#define RDC_8820_PIO_0_DISABLE 0
-#define RDC_8820_PIO_0_ENABLE  1
-#define RDC_8820_INT           2
-#define RDC_8820_RESET         4
-
-/*     DST Communication       */
-#define GET_REPLY              1
-#define NO_REPLY               0
-
-#define GET_ACK                        1
-#define FIXED_COMM             8
-
-#define ACK                    0xff
-
-struct dst_state {
-
-       struct i2c_adapter* i2c;
-
-       struct bt878* bt;
-
-       /* configuration settings */
-       const struct dst_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* private ASIC data */
-       u8 tx_tuna[10];
-       u8 rx_tuna[10];
-       u8 rxbuffer[10];
-       u8 diseq_flags;
-       u8 dst_type;
-       u32 type_flags;
-       u32 frequency;          /* intermediate frequency in kHz for QPSK */
-       fe_spectral_inversion_t inversion;
-       u32 symbol_rate;        /* symbol rate in Symbols per second */
-       fe_code_rate_t fec;
-       fe_sec_voltage_t voltage;
-       fe_sec_tone_mode_t tone;
-       u32 decode_freq;
-       u8 decode_lock;
-       u16 decode_strength;
-       u16 decode_snr;
-       unsigned long cur_jiff;
-       u8 k22;
-       u32 bandwidth;
-       u32 dst_hw_cap;
-       u8 dst_fw_version;
-       fe_sec_mini_cmd_t minicmd;
-       fe_modulation_t modulation;
-       u8 messages[256];
-       u8 mac_address[8];
-       u8 fw_version[8];
-       u8 card_info[8];
-       u8 vendor[8];
-       u8 board_info[8];
-       u32 tuner_type;
-       char *tuner_name;
-       struct mutex dst_mutex;
-       u8 fw_name[8];
-       struct dvb_device *dst_ca;
-};
-
-struct tuner_types {
-       u32 tuner_type;
-       char *tuner_name;
-       char *board_name;
-       char *fw_name;
-};
-
-struct dst_types {
-       char *device_id;
-       int offset;
-       u8 dst_type;
-       u32 type_flags;
-       u32 dst_feature;
-       u32 tuner_type;
-};
-
-struct dst_config
-{
-       /* the ASIC i2c address */
-       u8 demod_address;
-};
-
-int rdc_reset_state(struct dst_state *state);
-
-int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
-int dst_pio_disable(struct dst_state *state);
-int dst_error_recovery(struct dst_state* state);
-int dst_error_bailout(struct dst_state *state);
-int dst_comm_init(struct dst_state* state);
-
-int write_dst(struct dst_state *state, u8 * data, u8 len);
-int read_dst(struct dst_state *state, u8 * ret, u8 len);
-u8 dst_check_sum(u8 * buf, u32 len);
-struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
-struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
-
-
-#endif // DST_COMMON_H
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
deleted file mode 100644 (file)
index 3974a4c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
- *
- * Copyright (C) 2003 Jamie Honan
- */
-
-struct dst_gpio_enable {
-       u32     mask;
-       u32     enable;
-};
-
-struct dst_gpio_output {
-       u32     mask;
-       u32     highvals;
-};
-
-struct dst_gpio_read {
-       unsigned long value;
-};
-
-union dst_gpio_packet {
-       struct dst_gpio_enable enb;
-       struct dst_gpio_output outp;
-       struct dst_gpio_read rd;
-       int    psize;
-};
-
-#define DST_IG_ENABLE  0
-#define DST_IG_WRITE   1
-#define DST_IG_READ    2
-#define DST_IG_TS       3
-
-struct bt878;
-
-int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
deleted file mode 100644 (file)
index 81fab9a..0000000
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * Bt8xx based DVB adapter driver
- *
- * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
- *
- * 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.
- *
- */
-
-#define pr_fmt(fmt) "dvb_bt8xx: " fmt
-
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb-bt8xx.h"
-#include "bt878.h"
-
-static int debug;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk( args... ) \
-       do { \
-               if (debug) printk(KERN_DEBUG args); \
-       } while (0)
-
-#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-
-static void dvb_bt8xx_task(unsigned long data)
-{
-       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
-
-       //printk("%d ", card->bt->finished_block);
-
-       while (card->bt->last_block != card->bt->finished_block) {
-               (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
-                       (&card->demux,
-                        &card->bt->buf_cpu[card->bt->last_block *
-                                           card->bt->block_bytes],
-                        card->bt->block_bytes);
-               card->bt->last_block = (card->bt->last_block + 1) %
-                                       card->bt->block_count;
-       }
-}
-
-static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
-       struct dvb_bt8xx_card *card = dvbdmx->priv;
-       int rc;
-
-       dprintk("dvb_bt8xx: start_feed\n");
-
-       if (!dvbdmx->dmx.frontend)
-               return -EINVAL;
-
-       mutex_lock(&card->lock);
-       card->nfeeds++;
-       rc = card->nfeeds;
-       if (card->nfeeds == 1)
-               bt878_start(card->bt, card->gpio_mode,
-                           card->op_sync_orin, card->irq_err_ignore);
-       mutex_unlock(&card->lock);
-       return rc;
-}
-
-static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct dvb_bt8xx_card *card = dvbdmx->priv;
-
-       dprintk("dvb_bt8xx: stop_feed\n");
-
-       if (!dvbdmx->dmx.frontend)
-               return -EINVAL;
-
-       mutex_lock(&card->lock);
-       card->nfeeds--;
-       if (card->nfeeds == 0)
-               bt878_stop(card->bt);
-       mutex_unlock(&card->lock);
-
-       return 0;
-}
-
-static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
-{
-       if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
-               (adev->subsystem_device == bdev->subsystem_device) &&
-               (adev->bus->number == bdev->bus->number) &&
-               (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
-               return 1;
-       return 0;
-}
-
-static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
-{
-       unsigned int card_nr;
-
-       /* Hmm, n squared. Hope n is small */
-       for (card_nr = 0; card_nr < bt878_num; card_nr++)
-               if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
-                       return &bt878[card_nr];
-       return NULL;
-}
-
-static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
-{
-       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
-       static u8 mt352_reset [] = { 0x50, 0x80 };
-       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
-       static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
-       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
-       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-       mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
-       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
-       return 0;
-}
-
-static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 div;
-       unsigned char bs = 0;
-       unsigned char cp = 0;
-
-       if (buf_len < 5)
-               return -EINVAL;
-
-       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
-       if (c->frequency < 542000000)
-               cp = 0xb4;
-       else if (c->frequency < 771000000)
-               cp = 0xbc;
-       else
-               cp = 0xf4;
-
-       if (c->frequency == 0)
-               bs = 0x03;
-       else if (c->frequency < 443250000)
-               bs = 0x02;
-       else
-               bs = 0x08;
-
-       pllbuf[0] = 0x60;
-       pllbuf[1] = div >> 8;
-       pllbuf[2] = div & 0xff;
-       pllbuf[3] = cp;
-       pllbuf[4] = bs;
-
-       return 5;
-}
-
-static struct mt352_config thomson_dtt7579_config = {
-       .demod_address = 0x0f,
-       .demod_init = thomson_dtt7579_demod_init,
-};
-
-static struct zl10353_config thomson_dtt7579_zl10353_config = {
-       .demod_address = 0x0f,
-};
-
-static int cx24108_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 freq = c->frequency;
-       int i, a, n, pump;
-       u32 band, pll;
-       u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
-               1576000,1718000,1856000,2036000,2150000};
-       u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
-               0x00102000,0x00104000,0x00108000,0x00110000,
-               0x00120000,0x00140000};
-
-       #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
-       dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq);
-
-       /* This is really the bit driving the tuner chip cx24108 */
-
-       if (freq<950000)
-               freq = 950000; /* kHz */
-       else if (freq>2150000)
-               freq = 2150000; /* satellite IF is 950..2150MHz */
-
-       /* decide which VCO to use for the input frequency */
-       for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
-       dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq);
-       band=bandsel[i];
-       /* the gain values must be set by SetSymbolrate */
-       /* compute the pll divider needed, from Conexant data sheet,
-          resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
-          depending on the divider bit. It is set to /4 on the 2 lowest
-          bands  */
-       n=((i<=2?2:1)*freq*10L)/(XTAL/100);
-       a=n%32; n/=32; if(a==0) n--;
-       pump=(freq<(osci[i-1]+osci[i])/2);
-       pll=0xf8000000|
-           ((pump?1:2)<<(14+11))|
-           ((n&0x1ff)<<(5+11))|
-           ((a&0x1f)<<11);
-       /* everything is shifted left 11 bits to left-align the bits in the
-          32bit word. Output to the tuner goes MSB-aligned, after all */
-       dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a);
-       cx24110_pll_write(fe,band);
-       /* set vga and vca to their widest-band settings, as a precaution.
-          SetSymbolrate might not be called to set this up */
-       cx24110_pll_write(fe,0x500c0000);
-       cx24110_pll_write(fe,0x83f1f800);
-       cx24110_pll_write(fe,pll);
-       //writereg(client,0x56,0x7f);
-
-       return 0;
-}
-
-static int pinnsat_tuner_init(struct dvb_frontend* fe)
-{
-       struct dvb_bt8xx_card *card = fe->dvb->priv;
-
-       bttv_gpio_enable(card->bttv_nr, 1, 1);  /* output */
-       bttv_write_gpio(card->bttv_nr, 1, 1);   /* relay on */
-
-       return 0;
-}
-
-static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
-{
-       struct dvb_bt8xx_card *card = fe->dvb->priv;
-
-       bttv_write_gpio(card->bttv_nr, 1, 0);   /* relay off */
-
-       return 0;
-}
-
-static struct cx24110_config pctvsat_config = {
-       .demod_address = 0x55,
-};
-
-static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
-       u8 cfg, cpump, band_select;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (36000000 + c->frequency + 83333) / 166666;
-       cfg = 0x88;
-
-       if (c->frequency < 175000000)
-               cpump = 2;
-       else if (c->frequency < 390000000)
-               cpump = 1;
-       else if (c->frequency < 470000000)
-               cpump = 2;
-       else if (c->frequency < 750000000)
-               cpump = 2;
-       else
-               cpump = 3;
-
-       if (c->frequency < 175000000)
-               band_select = 0x0e;
-       else if (c->frequency < 470000000)
-               band_select = 0x05;
-       else
-               band_select = 0x03;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = ((div >> 10) & 0x60) | cfg;
-       data[3] = (cpump << 6) | band_select;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       i2c_transfer(card->i2c_adapter, &msg, 1);
-       return (div * 166666 - 36000000);
-}
-
-static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
-       struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
-
-       return request_firmware(fw, name, &bt->bt->dev->dev);
-}
-
-static struct sp887x_config microtune_mt7202dtf_config = {
-       .demod_address = 0x70,
-       .request_firmware = microtune_mt7202dtf_request_firmware,
-};
-
-static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
-{
-       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
-       static u8 mt352_reset [] = { 0x50, 0x80 };
-       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
-                                      0x00, 0xFF, 0x00, 0x40, 0x40 };
-       static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
-       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
-       mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
-       udelay(2000);
-       mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
-       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
-       return 0;
-}
-
-static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 div;
-       unsigned char bs = 0;
-       unsigned char cp = 0;
-
-       if (buf_len < 5) return -EINVAL;
-
-       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
-       if (c->frequency < 150000000)
-               cp = 0xB4;
-       else if (c->frequency < 173000000)
-               cp = 0xBC;
-       else if (c->frequency < 250000000)
-               cp = 0xB4;
-       else if (c->frequency < 400000000)
-               cp = 0xBC;
-       else if (c->frequency < 420000000)
-               cp = 0xF4;
-       else if (c->frequency < 470000000)
-               cp = 0xFC;
-       else if (c->frequency < 600000000)
-               cp = 0xBC;
-       else if (c->frequency < 730000000)
-               cp = 0xF4;
-       else
-               cp = 0xFC;
-
-       if (c->frequency < 150000000)
-               bs = 0x01;
-       else if (c->frequency < 173000000)
-               bs = 0x01;
-       else if (c->frequency < 250000000)
-               bs = 0x02;
-       else if (c->frequency < 400000000)
-               bs = 0x02;
-       else if (c->frequency < 420000000)
-               bs = 0x02;
-       else if (c->frequency < 470000000)
-               bs = 0x02;
-       else if (c->frequency < 600000000)
-               bs = 0x08;
-       else if (c->frequency < 730000000)
-               bs = 0x08;
-       else
-               bs = 0x08;
-
-       pllbuf[0] = 0x61;
-       pllbuf[1] = div >> 8;
-       pllbuf[2] = div & 0xff;
-       pllbuf[3] = cp;
-       pllbuf[4] = bs;
-
-       return 5;
-}
-
-static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
-       .demod_address = 0x0f,
-       .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
-};
-
-static struct dst_config dst_config = {
-       .demod_address = 0x55,
-};
-
-static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
-       struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
-
-       return request_firmware(fw, name, &bt->bt->dev->dev);
-}
-
-static void or51211_setmode(struct dvb_frontend * fe, int mode)
-{
-       struct dvb_bt8xx_card *bt = fe->dvb->priv;
-       bttv_write_gpio(bt->bttv_nr, 0x0002, mode);   /* Reset */
-       msleep(20);
-}
-
-static void or51211_reset(struct dvb_frontend * fe)
-{
-       struct dvb_bt8xx_card *bt = fe->dvb->priv;
-
-       /* RESET DEVICE
-        * reset is controlled by GPIO-0
-        * when set to 0 causes reset and when to 1 for normal op
-        * must remain reset for 128 clock cycles on a 50Mhz clock
-        * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4
-        * We assume that the reset has be held low long enough or we
-        * have been reset by a power on.  When the driver is unloaded
-        * reset set to 0 so if reloaded we have been reset.
-        */
-       /* reset & PRM1,2&4 are outputs */
-       int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
-       if (ret != 0)
-               printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
-       bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000);   /* Reset */
-       msleep(20);
-       /* Now set for normal operation */
-       bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
-       /* wait for operation to begin */
-       msleep(500);
-}
-
-static void or51211_sleep(struct dvb_frontend * fe)
-{
-       struct dvb_bt8xx_card *bt = fe->dvb->priv;
-       bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
-}
-
-static struct or51211_config or51211_config = {
-       .demod_address = 0x15,
-       .request_firmware = or51211_request_firmware,
-       .setmode = or51211_setmode,
-       .reset = or51211_reset,
-       .sleep = or51211_sleep,
-};
-
-static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
-
-       div = (c->frequency + 36166667) / 166667;
-
-       buf[0] = (div >> 8) & 0x7F;
-       buf[1] = div & 0xFF;
-       buf[2] = 0x85;
-       if ((c->frequency >= 47000000) && (c->frequency < 153000000))
-               buf[3] = 0x01;
-       else if ((c->frequency >= 153000000) && (c->frequency < 430000000))
-               buf[3] = 0x02;
-       else if ((c->frequency >= 430000000) && (c->frequency < 824000000))
-               buf[3] = 0x0C;
-       else if ((c->frequency >= 824000000) && (c->frequency < 863000000))
-               buf[3] = 0x8C;
-       else
-               return -EINVAL;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       i2c_transfer(card->i2c_adapter, &msg, 1);
-       return 0;
-}
-
-static struct nxt6000_config vp3021_alps_tded4_config = {
-       .demod_address = 0x0a,
-       .clock_inversion = 1,
-};
-
-static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
-{
-       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
-       static u8 mt352_reset [] = { 0x50, 0x80 };
-       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
-       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-       mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
-       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
-       return 0;
-}
-
-static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe,  u8 *pllbuf, int buf_len)
-{
-       u32 div;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-       if (buf_len < 5)
-               return -EINVAL;
-
-       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
-       pllbuf[0] = 0x61;
-       pllbuf[1] = (div >> 8) & 0x7F;
-       pllbuf[2] = div & 0xFF;
-       pllbuf[3] = 0x85;
-
-       dprintk("frequency %u, div %u\n", c->frequency, div);
-
-       if (c->frequency < 470000000)
-               pllbuf[4] = 0x02;
-       else if (c->frequency > 823000000)
-               pllbuf[4] = 0x88;
-       else
-               pllbuf[4] = 0x08;
-
-       if (c->bandwidth_hz == 8000000)
-               pllbuf[4] |= 0x04;
-
-       return 5;
-}
-
-static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
-{
-       /*
-        * Reset the frontend, must be called before trying
-        * to initialise the MT352 or mt352_attach
-        * will fail. Same goes for the nxt6000 frontend.
-        *
-        */
-
-       int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
-       if (ret != 0)
-               printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
-
-       /* Pulse the reset line */
-       bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
-       bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low  */
-       msleep(100);
-
-       bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
-}
-
-static struct mt352_config digitv_alps_tded4_config = {
-       .demod_address = 0x0a,
-       .demod_init = digitv_alps_tded4_demod_init,
-};
-
-static struct lgdt330x_config tdvs_tua6034_config = {
-       .demod_address    = 0x0e,
-       .demod_chip       = LGDT3303,
-       .serial_mpeg      = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
-};
-
-static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
-{
-       /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
-
-       /* Pulse the reset line */
-       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
-       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low  */
-       msleep(100);
-
-       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
-       msleep(100);
-}
-
-static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
-{
-       struct dst_state* state = NULL;
-
-       switch(type) {
-       case BTTV_BOARD_DVICO_DVBT_LITE:
-               card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
-
-               if (card->fe == NULL)
-                       card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
-                                                 card->i2c_adapter);
-
-               if (card->fe != NULL) {
-                       card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
-                       card->fe->ops.info.frequency_min = 174000000;
-                       card->fe->ops.info.frequency_max = 862000000;
-               }
-               break;
-
-       case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
-               lgdt330x_reset(card);
-               card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
-               if (card->fe != NULL) {
-                       dvb_attach(simple_tuner_attach, card->fe,
-                                  card->i2c_adapter, 0x61,
-                                  TUNER_LG_TDVS_H06XF);
-                       dprintk ("dvb_bt8xx: lgdt330x detected\n");
-               }
-               break;
-
-       case BTTV_BOARD_NEBULA_DIGITV:
-               /*
-                * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
-                * this would be a cleaner solution than trying each frontend in turn.
-                */
-
-               /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
-               digitv_alps_tded4_reset(card);
-               card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
-               if (card->fe != NULL) {
-                       card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
-                       dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
-                       break;
-               }
-
-               /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
-               digitv_alps_tded4_reset(card);
-               card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
-
-               if (card->fe != NULL) {
-                       card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
-                       dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
-               }
-               break;
-
-       case BTTV_BOARD_AVDVBT_761:
-               card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
-               if (card->fe) {
-                       card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
-               }
-               break;
-
-       case BTTV_BOARD_AVDVBT_771:
-               card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
-               if (card->fe != NULL) {
-                       card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
-                       card->fe->ops.info.frequency_min = 174000000;
-                       card->fe->ops.info.frequency_max = 862000000;
-               }
-               break;
-
-       case BTTV_BOARD_TWINHAN_DST:
-               /*      DST is not a frontend driver !!!                */
-               state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
-               if (!state) {
-                       pr_err("No memory\n");
-                       break;
-               }
-               /*      Setup the Card                                  */
-               state->config = &dst_config;
-               state->i2c = card->i2c_adapter;
-               state->bt = card->bt;
-               state->dst_ca = NULL;
-               /*      DST is not a frontend, attaching the ASIC       */
-               if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
-                       pr_err("%s: Could not find a Twinhan DST\n", __func__);
-                       break;
-               }
-               /*      Attach other DST peripherals if any             */
-               /*      Conditional Access device                       */
-               card->fe = &state->frontend;
-               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
-                       dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
-               break;
-
-       case BTTV_BOARD_PINNACLESAT:
-               card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
-               if (card->fe) {
-                       card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
-                       card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
-                       card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
-               }
-               break;
-
-       case BTTV_BOARD_PC_HDTV:
-               card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
-               if (card->fe != NULL)
-                       dvb_attach(simple_tuner_attach, card->fe,
-                                  card->i2c_adapter, 0x61,
-                                  TUNER_PHILIPS_FCV1236D);
-               break;
-       }
-
-       if (card->fe == NULL)
-               pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      card->bt->dev->vendor,
-                      card->bt->dev->device,
-                      card->bt->dev->subsystem_vendor,
-                      card->bt->dev->subsystem_device);
-       else
-               if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
-                       pr_err("Frontend registration failed!\n");
-                       dvb_frontend_detach(card->fe);
-                       card->fe = NULL;
-               }
-}
-
-static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
-{
-       int result;
-
-       result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
-                                     THIS_MODULE, &card->bt->dev->dev,
-                                     adapter_nr);
-       if (result < 0) {
-               pr_err("dvb_register_adapter failed (errno = %d)\n", result);
-               return result;
-       }
-       card->dvb_adapter.priv = card;
-
-       card->bt->adapter = card->i2c_adapter;
-
-       memset(&card->demux, 0, sizeof(struct dvb_demux));
-
-       card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
-
-       card->demux.priv = card;
-       card->demux.filternum = 256;
-       card->demux.feednum = 256;
-       card->demux.start_feed = dvb_bt8xx_start_feed;
-       card->demux.stop_feed = dvb_bt8xx_stop_feed;
-       card->demux.write_to_decoder = NULL;
-
-       result = dvb_dmx_init(&card->demux);
-       if (result < 0) {
-               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
-               goto err_unregister_adaptor;
-       }
-
-       card->dmxdev.filternum = 256;
-       card->dmxdev.demux = &card->demux.dmx;
-       card->dmxdev.capabilities = 0;
-
-       result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter);
-       if (result < 0) {
-               pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
-               goto err_dmx_release;
-       }
-
-       card->fe_hw.source = DMX_FRONTEND_0;
-
-       result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw);
-       if (result < 0) {
-               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
-               goto err_dmxdev_release;
-       }
-
-       card->fe_mem.source = DMX_MEMORY_FE;
-
-       result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem);
-       if (result < 0) {
-               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
-               goto err_remove_hw_frontend;
-       }
-
-       result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw);
-       if (result < 0) {
-               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
-               goto err_remove_mem_frontend;
-       }
-
-       result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
-       if (result < 0) {
-               pr_err("dvb_net_init failed (errno = %d)\n", result);
-               goto err_disconnect_frontend;
-       }
-
-       tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
-
-       frontend_init(card, type);
-
-       return 0;
-
-err_disconnect_frontend:
-       card->demux.dmx.disconnect_frontend(&card->demux.dmx);
-err_remove_mem_frontend:
-       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
-err_remove_hw_frontend:
-       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
-err_dmxdev_release:
-       dvb_dmxdev_release(&card->dmxdev);
-err_dmx_release:
-       dvb_dmx_release(&card->demux);
-err_unregister_adaptor:
-       dvb_unregister_adapter(&card->dvb_adapter);
-       return result;
-}
-
-static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
-{
-       struct dvb_bt8xx_card *card;
-       struct pci_dev* bttv_pci_dev;
-       int ret;
-
-       if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
-               return -ENOMEM;
-
-       mutex_init(&card->lock);
-       card->bttv_nr = sub->core->nr;
-       strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
-       card->i2c_adapter = &sub->core->i2c_adap;
-
-       switch(sub->core->type) {
-       case BTTV_BOARD_PINNACLESAT:
-               card->gpio_mode = 0x0400c060;
-               /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
-                             BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               break;
-
-       case BTTV_BOARD_DVICO_DVBT_LITE:
-               card->gpio_mode = 0x0400C060;
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               /* 26, 15, 14, 6, 5
-                * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA
-                * DA_APP(parallel) */
-               break;
-
-       case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
-               card->gpio_mode = 0x0400c060;
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               break;
-
-       case BTTV_BOARD_NEBULA_DIGITV:
-       case BTTV_BOARD_AVDVBT_761:
-               card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               /* A_PWRDN DA_SBR DA_APP (high speed serial) */
-               break;
-
-       case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
-               card->gpio_mode = 0x0400402B;
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               /* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
-               break;
-
-       case BTTV_BOARD_TWINHAN_DST:
-               card->gpio_mode = 0x2204f2c;
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
-                                      BT878_APPERR | BT878_AFBUS;
-               /* 25,21,14,11,10,9,8,3,2 then
-                * 0x33 = 5,4,1,0
-                * A_SEL=SML, DA_MLB, DA_SBR,
-                * DA_SDR=f, fifo trigger = 32 DWORDS
-                * IOM = 0 == audio A/D
-                * DPM = 0 == digital audio mode
-                * == async data parallel port
-                * then 0x33 (13 is set by start_capture)
-                * DA_APP = async data parallel port,
-                * ACAP_EN = 1,
-                * RISC+FIFO ENABLE */
-               break;
-
-       case BTTV_BOARD_PC_HDTV:
-               card->gpio_mode = 0x0100EC7B;
-               card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
-               break;
-
-       default:
-               pr_err("Unknown bttv card type: %d\n", sub->core->type);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
-
-       if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
-               pr_err("no pci device for card %d\n", card->bttv_nr);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
-               pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr);
-               pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n");
-
-               kfree(card);
-               return -ENODEV;
-       }
-
-       mutex_init(&card->bt->gpio_lock);
-       card->bt->bttv_nr = sub->core->nr;
-
-       if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
-               kfree(card);
-               return ret;
-       }
-
-       dev_set_drvdata(&sub->dev, card);
-       return 0;
-}
-
-static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
-{
-       struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
-
-       dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
-
-       bt878_stop(card->bt);
-       tasklet_kill(&card->bt->tasklet);
-       dvb_net_release(&card->dvbnet);
-       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
-       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
-       dvb_dmxdev_release(&card->dmxdev);
-       dvb_dmx_release(&card->demux);
-       if (card->fe) {
-               dvb_unregister_frontend(card->fe);
-               dvb_frontend_detach(card->fe);
-       }
-       dvb_unregister_adapter(&card->dvb_adapter);
-
-       kfree(card);
-}
-
-static struct bttv_sub_driver driver = {
-       .drv = {
-               .name           = "dvb-bt8xx",
-       },
-       .probe          = dvb_bt8xx_probe,
-       .remove         = dvb_bt8xx_remove,
-       /* FIXME:
-        * .shutdown    = dvb_bt8xx_shutdown,
-        * .suspend     = dvb_bt8xx_suspend,
-        * .resume      = dvb_bt8xx_resume,
-        */
-};
-
-static int __init dvb_bt8xx_init(void)
-{
-       return bttv_sub_register(&driver, "dvb");
-}
-
-static void __exit dvb_bt8xx_exit(void)
-{
-       bttv_sub_unregister(&driver);
-}
-
-module_init(dvb_bt8xx_init);
-module_exit(dvb_bt8xx_exit);
-
-MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
-MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
deleted file mode 100644 (file)
index 4499ed2..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Bt8xx based DVB adapter driver
- *
- * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
- * Copyright (C) 1999-2001 Ralph  Metzler & Marcus Metzler for convergence integrated media GmbH
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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 DVB_BT8XX_H
-#define DVB_BT8XX_H
-
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include "dvbdev.h"
-#include "dvb_net.h"
-#include "bttv.h"
-#include "mt352.h"
-#include "sp887x.h"
-#include "dst_common.h"
-#include "nxt6000.h"
-#include "cx24110.h"
-#include "or51211.h"
-#include "lgdt330x.h"
-#include "zl10353.h"
-#include "tuner-simple.h"
-
-struct dvb_bt8xx_card {
-       struct mutex lock;
-       int nfeeds;
-       char card_name[32];
-       struct dvb_adapter dvb_adapter;
-       struct bt878 *bt;
-       unsigned int bttv_nr;
-       struct dvb_demux demux;
-       struct dmxdev dmxdev;
-       struct dmx_frontend fe_hw;
-       struct dmx_frontend fe_mem;
-       u32 gpio_mode;
-       u32 op_sync_orin;
-       u32 irq_err_ignore;
-       struct i2c_adapter *i2c_adapter;
-       struct dvb_net dvbnet;
-
-       struct dvb_frontend* fe;
-};
-
-#endif /* DVB_BT8XX_H */
diff --git a/drivers/media/dvb/ddbridge/Kconfig b/drivers/media/dvb/ddbridge/Kconfig
deleted file mode 100644 (file)
index d099e1a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-config DVB_DDBRIDGE
-       tristate "Digital Devices bridge support"
-       depends on DVB_CORE && PCI && I2C
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_STV6110x if !DVB_FE_CUSTOMISE
-       select DVB_STV090x if !DVB_FE_CUSTOMISE
-       select DVB_DRXK if !DVB_FE_CUSTOMISE
-       select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
-       ---help---
-         Support for cards with the Digital Devices PCI express bridge:
-         - Octopus PCIe Bridge
-         - Octopus mini PCIe Bridge
-         - Octopus LE
-         - DuoFlex S2 Octopus
-         - DuoFlex CT Octopus
-         - cineS2(v6)
-
-         Say Y if you own such a card and want to use it.
diff --git a/drivers/media/dvb/ddbridge/Makefile b/drivers/media/dvb/ddbridge/Makefile
deleted file mode 100644 (file)
index 9d083c9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile for the ddbridge device driver
-#
-
-ddbridge-objs := ddbridge-core.o
-
-obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
-
-ccflags-y += -Idrivers/media/dvb-core/
-ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
-
-# For the staging CI driver cxd2099
-ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c
deleted file mode 100644 (file)
index ebf3f05..0000000
+++ /dev/null
@@ -1,1723 +0,0 @@
-/*
- * ddbridge.c: Digital Devices PCIe bridge driver
- *
- * Copyright (C) 2010-2011 Digital Devices GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/io.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/timer.h>
-#include <linux/i2c.h>
-#include <linux/swab.h>
-#include <linux/vmalloc.h>
-#include "ddbridge.h"
-
-#include "ddbridge-regs.h"
-
-#include "tda18271c2dd.h"
-#include "stv6110x.h"
-#include "stv090x.h"
-#include "lnbh24.h"
-#include "drxk.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* MSI had problems with lost interrupts, fixed but needs testing */
-#undef CONFIG_PCI_MSI
-
-/******************************************************************************/
-
-static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
-{
-       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
-                                  .buf  = val,  .len   = 1 } };
-       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
-}
-
-static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
-{
-       struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0,
-                                  .buf  = &reg, .len   = 1 },
-                                 {.addr = adr,  .flags = I2C_M_RD,
-                                  .buf  = val,  .len   = 1 } };
-       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
-}
-
-static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
-                         u16 reg, u8 *val)
-{
-       u8 msg[2] = {reg>>8, reg&0xff};
-       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
-                                  .buf  = msg, .len   = 2},
-                                 {.addr = adr, .flags = I2C_M_RD,
-                                  .buf  = val, .len   = 1} };
-       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
-}
-
-static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
-{
-       struct ddb *dev = i2c->dev;
-       int stat;
-       u32 val;
-
-       i2c->done = 0;
-       ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND);
-       stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ);
-       if (stat <= 0) {
-               printk(KERN_ERR "I2C timeout\n");
-               { /* MSI debugging*/
-                       u32 istat = ddbreadl(INTERRUPT_STATUS);
-                       printk(KERN_ERR "IRS %08x\n", istat);
-                       ddbwritel(istat, INTERRUPT_ACK);
-               }
-               return -EIO;
-       }
-       val = ddbreadl(i2c->regs+I2C_COMMAND);
-       if (val & 0x70000)
-               return -EIO;
-       return 0;
-}
-
-static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
-                              struct i2c_msg msg[], int num)
-{
-       struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter);
-       struct ddb *dev = i2c->dev;
-       u8 addr = 0;
-
-       if (num)
-               addr = msg[0].addr;
-
-       if (num == 2 && msg[1].flags & I2C_M_RD &&
-           !(msg[0].flags & I2C_M_RD)) {
-               memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf,
-                           msg[0].buf, msg[0].len);
-               ddbwritel(msg[0].len|(msg[1].len << 16),
-                         i2c->regs+I2C_TASKLENGTH);
-               if (!ddb_i2c_cmd(i2c, addr, 1)) {
-                       memcpy_fromio(msg[1].buf,
-                                     dev->regs + I2C_TASKMEM_BASE + i2c->rbuf,
-                                     msg[1].len);
-                       return num;
-               }
-       }
-
-       if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
-               ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len);
-               ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH);
-               if (!ddb_i2c_cmd(i2c, addr, 2))
-                       return num;
-       }
-       if (num == 1 && (msg[0].flags & I2C_M_RD)) {
-               ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
-               if (!ddb_i2c_cmd(i2c, addr, 3)) {
-                       ddbcpyfrom(msg[0].buf,
-                                  I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len);
-                       return num;
-               }
-       }
-       return -EIO;
-}
-
-
-static u32 ddb_i2c_functionality(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_SMBUS_EMUL;
-}
-
-struct i2c_algorithm ddb_i2c_algo = {
-       .master_xfer   = ddb_i2c_master_xfer,
-       .functionality = ddb_i2c_functionality,
-};
-
-static void ddb_i2c_release(struct ddb *dev)
-{
-       int i;
-       struct ddb_i2c *i2c;
-       struct i2c_adapter *adap;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               i2c = &dev->i2c[i];
-               adap = &i2c->adap;
-               i2c_del_adapter(adap);
-       }
-}
-
-static int ddb_i2c_init(struct ddb *dev)
-{
-       int i, j, stat = 0;
-       struct ddb_i2c *i2c;
-       struct i2c_adapter *adap;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               i2c = &dev->i2c[i];
-               i2c->dev = dev;
-               i2c->nr = i;
-               i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4);
-               i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8);
-               i2c->regs = 0x80 + i * 0x20;
-               ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING);
-               ddbwritel((i2c->rbuf << 16) | i2c->wbuf,
-                         i2c->regs + I2C_TASKADDRESS);
-               init_waitqueue_head(&i2c->wq);
-
-               adap = &i2c->adap;
-               i2c_set_adapdata(adap, i2c);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
-               adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
-#else
-#ifdef I2C_CLASS_TV_ANALOG
-               adap->class = I2C_CLASS_TV_ANALOG;
-#endif
-#endif
-               strcpy(adap->name, "ddbridge");
-               adap->algo = &ddb_i2c_algo;
-               adap->algo_data = (void *)i2c;
-               adap->dev.parent = &dev->pdev->dev;
-               stat = i2c_add_adapter(adap);
-               if (stat)
-                       break;
-       }
-       if (stat)
-               for (j = 0; j < i; j++) {
-                       i2c = &dev->i2c[j];
-                       adap = &i2c->adap;
-                       i2c_del_adapter(adap);
-               }
-       return stat;
-}
-
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-
-#if 0
-static void set_table(struct ddb *dev, u32 off,
-                     dma_addr_t *pbuf, u32 num)
-{
-       u32 i, base;
-       u64 mem;
-
-       base = DMA_BASE_ADDRESS_TABLE + off;
-       for (i = 0; i < num; i++) {
-               mem = pbuf[i];
-               ddbwritel(mem & 0xffffffff, base + i * 8);
-               ddbwritel(mem >> 32, base + i * 8 + 4);
-       }
-}
-#endif
-
-static void ddb_address_table(struct ddb *dev)
-{
-       u32 i, j, base;
-       u64 mem;
-       dma_addr_t *pbuf;
-
-       for (i = 0; i < dev->info->port_num * 2; i++) {
-               base = DMA_BASE_ADDRESS_TABLE + i * 0x100;
-               pbuf = dev->input[i].pbuf;
-               for (j = 0; j < dev->input[i].dma_buf_num; j++) {
-                       mem = pbuf[j];
-                       ddbwritel(mem & 0xffffffff, base + j * 8);
-                       ddbwritel(mem >> 32, base + j * 8 + 4);
-               }
-       }
-       for (i = 0; i < dev->info->port_num; i++) {
-               base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100;
-               pbuf = dev->output[i].pbuf;
-               for (j = 0; j < dev->output[i].dma_buf_num; j++) {
-                       mem = pbuf[j];
-                       ddbwritel(mem & 0xffffffff, base + j * 8);
-                       ddbwritel(mem >> 32, base + j * 8 + 4);
-               }
-       }
-}
-
-static void io_free(struct pci_dev *pdev, u8 **vbuf,
-                   dma_addr_t *pbuf, u32 size, int num)
-{
-       int i;
-
-       for (i = 0; i < num; i++) {
-               if (vbuf[i]) {
-                       pci_free_consistent(pdev, size, vbuf[i], pbuf[i]);
-                       vbuf[i] = 0;
-               }
-       }
-}
-
-static int io_alloc(struct pci_dev *pdev, u8 **vbuf,
-                   dma_addr_t *pbuf, u32 size, int num)
-{
-       int i;
-
-       for (i = 0; i < num; i++) {
-               vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]);
-               if (!vbuf[i])
-                       return -ENOMEM;
-       }
-       return 0;
-}
-
-static int ddb_buffers_alloc(struct ddb *dev)
-{
-       int i;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               switch (port->class) {
-               case DDB_PORT_TUNER:
-                       if (io_alloc(dev->pdev, port->input[0]->vbuf,
-                                    port->input[0]->pbuf,
-                                    port->input[0]->dma_buf_size,
-                                    port->input[0]->dma_buf_num) < 0)
-                               return -1;
-                       if (io_alloc(dev->pdev, port->input[1]->vbuf,
-                                    port->input[1]->pbuf,
-                                    port->input[1]->dma_buf_size,
-                                    port->input[1]->dma_buf_num) < 0)
-                               return -1;
-                       break;
-               case DDB_PORT_CI:
-                       if (io_alloc(dev->pdev, port->input[0]->vbuf,
-                                    port->input[0]->pbuf,
-                                    port->input[0]->dma_buf_size,
-                                    port->input[0]->dma_buf_num) < 0)
-                               return -1;
-                       if (io_alloc(dev->pdev, port->output->vbuf,
-                                    port->output->pbuf,
-                                    port->output->dma_buf_size,
-                                    port->output->dma_buf_num) < 0)
-                               return -1;
-                       break;
-               default:
-                       break;
-               }
-       }
-       ddb_address_table(dev);
-       return 0;
-}
-
-static void ddb_buffers_free(struct ddb *dev)
-{
-       int i;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               io_free(dev->pdev, port->input[0]->vbuf,
-                       port->input[0]->pbuf,
-                       port->input[0]->dma_buf_size,
-                       port->input[0]->dma_buf_num);
-               io_free(dev->pdev, port->input[1]->vbuf,
-                       port->input[1]->pbuf,
-                       port->input[1]->dma_buf_size,
-                       port->input[1]->dma_buf_num);
-               io_free(dev->pdev, port->output->vbuf,
-                       port->output->pbuf,
-                       port->output->dma_buf_size,
-                       port->output->dma_buf_num);
-       }
-}
-
-static void ddb_input_start(struct ddb_input *input)
-{
-       struct ddb *dev = input->port->dev;
-
-       spin_lock_irq(&input->lock);
-       input->cbuf = 0;
-       input->coff = 0;
-
-       /* reset */
-       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
-       ddbwritel(2, TS_INPUT_CONTROL(input->nr));
-       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
-
-       ddbwritel((1 << 16) |
-                 (input->dma_buf_num << 11) |
-                 (input->dma_buf_size >> 7),
-                 DMA_BUFFER_SIZE(input->nr));
-       ddbwritel(0, DMA_BUFFER_ACK(input->nr));
-
-       ddbwritel(1, DMA_BASE_WRITE);
-       ddbwritel(3, DMA_BUFFER_CONTROL(input->nr));
-       ddbwritel(9, TS_INPUT_CONTROL(input->nr));
-       input->running = 1;
-       spin_unlock_irq(&input->lock);
-}
-
-static void ddb_input_stop(struct ddb_input *input)
-{
-       struct ddb *dev = input->port->dev;
-
-       spin_lock_irq(&input->lock);
-       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
-       ddbwritel(0, DMA_BUFFER_CONTROL(input->nr));
-       input->running = 0;
-       spin_unlock_irq(&input->lock);
-}
-
-static void ddb_output_start(struct ddb_output *output)
-{
-       struct ddb *dev = output->port->dev;
-
-       spin_lock_irq(&output->lock);
-       output->cbuf = 0;
-       output->coff = 0;
-       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
-       ddbwritel(2, TS_OUTPUT_CONTROL(output->nr));
-       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
-       ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr));
-       ddbwritel((1 << 16) |
-                 (output->dma_buf_num << 11) |
-                 (output->dma_buf_size >> 7),
-                 DMA_BUFFER_SIZE(output->nr + 8));
-       ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8));
-
-       ddbwritel(1, DMA_BASE_READ);
-       ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8));
-       /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */
-       ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr));
-       output->running = 1;
-       spin_unlock_irq(&output->lock);
-}
-
-static void ddb_output_stop(struct ddb_output *output)
-{
-       struct ddb *dev = output->port->dev;
-
-       spin_lock_irq(&output->lock);
-       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
-       ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8));
-       output->running = 0;
-       spin_unlock_irq(&output->lock);
-}
-
-static u32 ddb_output_free(struct ddb_output *output)
-{
-       u32 idx, off, stat = output->stat;
-       s32 diff;
-
-       idx = (stat >> 11) & 0x1f;
-       off = (stat & 0x7ff) << 7;
-
-       if (output->cbuf != idx) {
-               if ((((output->cbuf + 1) % output->dma_buf_num) == idx) &&
-                   (output->dma_buf_size - output->coff <= 188))
-                       return 0;
-               return 188;
-       }
-       diff = off - output->coff;
-       if (diff <= 0 || diff > 188)
-               return 188;
-       return 0;
-}
-
-static ssize_t ddb_output_write(struct ddb_output *output,
-                               const u8 *buf, size_t count)
-{
-       struct ddb *dev = output->port->dev;
-       u32 idx, off, stat = output->stat;
-       u32 left = count, len;
-
-       idx = (stat >> 11) & 0x1f;
-       off = (stat & 0x7ff) << 7;
-
-       while (left) {
-               len = output->dma_buf_size - output->coff;
-               if ((((output->cbuf + 1) % output->dma_buf_num) == idx) &&
-                   (off == 0)) {
-                       if (len <= 188)
-                               break;
-                       len -= 188;
-               }
-               if (output->cbuf == idx) {
-                       if (off > output->coff) {
-#if 1
-                               len = off - output->coff;
-                               len -= (len % 188);
-                               if (len <= 188)
-
-#endif
-                                       break;
-                               len -= 188;
-                       }
-               }
-               if (len > left)
-                       len = left;
-               if (copy_from_user(output->vbuf[output->cbuf] + output->coff,
-                                  buf, len))
-                       return -EIO;
-               left -= len;
-               buf += len;
-               output->coff += len;
-               if (output->coff == output->dma_buf_size) {
-                       output->coff = 0;
-                       output->cbuf = ((output->cbuf + 1) % output->dma_buf_num);
-               }
-               ddbwritel((output->cbuf << 11) | (output->coff >> 7),
-                         DMA_BUFFER_ACK(output->nr + 8));
-       }
-       return count - left;
-}
-
-static u32 ddb_input_avail(struct ddb_input *input)
-{
-       struct ddb *dev = input->port->dev;
-       u32 idx, off, stat = input->stat;
-       u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr));
-
-       idx = (stat >> 11) & 0x1f;
-       off = (stat & 0x7ff) << 7;
-
-       if (ctrl & 4) {
-               printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl);
-               ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr));
-               return 0;
-       }
-       if (input->cbuf != idx)
-               return 188;
-       return 0;
-}
-
-static ssize_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count)
-{
-       struct ddb *dev = input->port->dev;
-       u32 left = count;
-       u32 idx, free, stat = input->stat;
-       int ret;
-
-       idx = (stat >> 11) & 0x1f;
-
-       while (left) {
-               if (input->cbuf == idx)
-                       return count - left;
-               free = input->dma_buf_size - input->coff;
-               if (free > left)
-                       free = left;
-               ret = copy_to_user(buf, input->vbuf[input->cbuf] +
-                                  input->coff, free);
-               if (ret)
-                       return -EFAULT;
-               input->coff += free;
-               if (input->coff == input->dma_buf_size) {
-                       input->coff = 0;
-                       input->cbuf = (input->cbuf+1) % input->dma_buf_num;
-               }
-               left -= free;
-               ddbwritel((input->cbuf << 11) | (input->coff >> 7),
-                         DMA_BUFFER_ACK(input->nr));
-       }
-       return count;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-
-#if 0
-static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe)
-{
-       int i;
-
-       for (i = 0; i < dev->info->port_num * 2; i++) {
-               if (dev->input[i].fe == fe)
-                       return &dev->input[i];
-       }
-       return NULL;
-}
-#endif
-
-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct ddb_input *input = fe->sec_priv;
-       struct ddb_port *port = input->port;
-       int status;
-
-       if (enable) {
-               mutex_lock(&port->i2c_gate_lock);
-               status = input->gate_ctrl(fe, 1);
-       } else {
-               status = input->gate_ctrl(fe, 0);
-               mutex_unlock(&port->i2c_gate_lock);
-       }
-       return status;
-}
-
-static int demod_attach_drxk(struct ddb_input *input)
-{
-       struct i2c_adapter *i2c = &input->port->i2c->adap;
-       struct dvb_frontend *fe;
-       struct drxk_config config;
-
-       memset(&config, 0, sizeof(config));
-       config.microcode_name = "drxk_a3.mc";
-       config.qam_demod_parameter_count = 4;
-       config.adr = 0x29 + (input->nr & 1);
-
-       fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
-       if (!input->fe) {
-               printk(KERN_ERR "No DRXK found!\n");
-               return -ENODEV;
-       }
-       fe->sec_priv = input;
-       input->gate_ctrl = fe->ops.i2c_gate_ctrl;
-       fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
-       return 0;
-}
-
-static int tuner_attach_tda18271(struct ddb_input *input)
-{
-       struct i2c_adapter *i2c = &input->port->i2c->adap;
-       struct dvb_frontend *fe;
-
-       if (input->fe->ops.i2c_gate_ctrl)
-               input->fe->ops.i2c_gate_ctrl(input->fe, 1);
-       fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60);
-       if (!fe) {
-               printk(KERN_ERR "No TDA18271 found!\n");
-               return -ENODEV;
-       }
-       if (input->fe->ops.i2c_gate_ctrl)
-               input->fe->ops.i2c_gate_ctrl(input->fe, 0);
-       return 0;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-
-static struct stv090x_config stv0900 = {
-       .device         = STV0900,
-       .demod_mode     = STV090x_DUAL,
-       .clk_mode       = STV090x_CLK_EXT,
-
-       .xtal           = 27000000,
-       .address        = 0x69,
-
-       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-
-       .repeater_level = STV090x_RPTLEVEL_16,
-
-       .adc1_range     = STV090x_ADC_1Vpp,
-       .adc2_range     = STV090x_ADC_1Vpp,
-
-       .diseqc_envelope_mode = true,
-};
-
-static struct stv090x_config stv0900_aa = {
-       .device         = STV0900,
-       .demod_mode     = STV090x_DUAL,
-       .clk_mode       = STV090x_CLK_EXT,
-
-       .xtal           = 27000000,
-       .address        = 0x68,
-
-       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-
-       .repeater_level = STV090x_RPTLEVEL_16,
-
-       .adc1_range     = STV090x_ADC_1Vpp,
-       .adc2_range     = STV090x_ADC_1Vpp,
-
-       .diseqc_envelope_mode = true,
-};
-
-static struct stv6110x_config stv6110a = {
-       .addr    = 0x60,
-       .refclk  = 27000000,
-       .clk_div = 1,
-};
-
-static struct stv6110x_config stv6110b = {
-       .addr    = 0x63,
-       .refclk  = 27000000,
-       .clk_div = 1,
-};
-
-static int demod_attach_stv0900(struct ddb_input *input, int type)
-{
-       struct i2c_adapter *i2c = &input->port->i2c->adap;
-       struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
-
-       input->fe = dvb_attach(stv090x_attach, feconf, i2c,
-                              (input->nr & 1) ? STV090x_DEMODULATOR_1
-                              : STV090x_DEMODULATOR_0);
-       if (!input->fe) {
-               printk(KERN_ERR "No STV0900 found!\n");
-               return -ENODEV;
-       }
-       if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0,
-                       0, (input->nr & 1) ?
-                       (0x09 - type) : (0x0b - type))) {
-               printk(KERN_ERR "No LNBH24 found!\n");
-               return -ENODEV;
-       }
-       return 0;
-}
-
-static int tuner_attach_stv6110(struct ddb_input *input, int type)
-{
-       struct i2c_adapter *i2c = &input->port->i2c->adap;
-       struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
-       struct stv6110x_config *tunerconf = (input->nr & 1) ?
-               &stv6110b : &stv6110a;
-       struct stv6110x_devctl *ctl;
-
-       ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c);
-       if (!ctl) {
-               printk(KERN_ERR "No STV6110X found!\n");
-               return -ENODEV;
-       }
-       printk(KERN_INFO "attach tuner input %d adr %02x\n",
-                        input->nr, tunerconf->addr);
-
-       feconf->tuner_init          = ctl->tuner_init;
-       feconf->tuner_sleep         = ctl->tuner_sleep;
-       feconf->tuner_set_mode      = ctl->tuner_set_mode;
-       feconf->tuner_set_frequency = ctl->tuner_set_frequency;
-       feconf->tuner_get_frequency = ctl->tuner_get_frequency;
-       feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-       feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-       feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
-       feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
-       feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
-       feconf->tuner_get_status    = ctl->tuner_get_status;
-
-       return 0;
-}
-
-static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
-                           int (*start_feed)(struct dvb_demux_feed *),
-                           int (*stop_feed)(struct dvb_demux_feed *),
-                           void *priv)
-{
-       dvbdemux->priv = priv;
-
-       dvbdemux->filternum = 256;
-       dvbdemux->feednum = 256;
-       dvbdemux->start_feed = start_feed;
-       dvbdemux->stop_feed = stop_feed;
-       dvbdemux->write_to_decoder = NULL;
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
-                                     DMX_SECTION_FILTERING |
-                                     DMX_MEMORY_BASED_FILTERING);
-       return dvb_dmx_init(dvbdemux);
-}
-
-static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
-                              struct dvb_demux *dvbdemux,
-                              struct dmx_frontend *hw_frontend,
-                              struct dmx_frontend *mem_frontend,
-                              struct dvb_adapter *dvb_adapter)
-{
-       int ret;
-
-       dmxdev->filternum = 256;
-       dmxdev->demux = &dvbdemux->dmx;
-       dmxdev->capabilities = 0;
-       ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
-       if (ret < 0)
-               return ret;
-
-       hw_frontend->source = DMX_FRONTEND_0;
-       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
-       mem_frontend->source = DMX_MEMORY_FE;
-       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
-       return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
-}
-
-static int start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct ddb_input *input = dvbdmx->priv;
-
-       if (!input->users)
-               ddb_input_start(input);
-
-       return ++input->users;
-}
-
-static int stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct ddb_input *input = dvbdmx->priv;
-
-       if (--input->users)
-               return input->users;
-
-       ddb_input_stop(input);
-       return 0;
-}
-
-
-static void dvb_input_detach(struct ddb_input *input)
-{
-       struct dvb_adapter *adap = &input->adap;
-       struct dvb_demux *dvbdemux = &input->demux;
-
-       switch (input->attached) {
-       case 5:
-               if (input->fe2)
-                       dvb_unregister_frontend(input->fe2);
-               if (input->fe) {
-                       dvb_unregister_frontend(input->fe);
-                       dvb_frontend_detach(input->fe);
-                       input->fe = NULL;
-               }
-       case 4:
-               dvb_net_release(&input->dvbnet);
-
-       case 3:
-               dvbdemux->dmx.close(&dvbdemux->dmx);
-               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
-                                             &input->hw_frontend);
-               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
-                                             &input->mem_frontend);
-               dvb_dmxdev_release(&input->dmxdev);
-
-       case 2:
-               dvb_dmx_release(&input->demux);
-
-       case 1:
-               dvb_unregister_adapter(adap);
-       }
-       input->attached = 0;
-}
-
-static int dvb_input_attach(struct ddb_input *input)
-{
-       int ret;
-       struct ddb_port *port = input->port;
-       struct dvb_adapter *adap = &input->adap;
-       struct dvb_demux *dvbdemux = &input->demux;
-
-       ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE,
-                                  &input->port->dev->pdev->dev,
-                                  adapter_nr);
-       if (ret < 0) {
-               printk(KERN_ERR "ddbridge: Could not register adapter."
-                      "Check if you enabled enough adapters in dvb-core!\n");
-               return ret;
-       }
-       input->attached = 1;
-
-       ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
-                                     start_feed,
-                                     stop_feed, input);
-       if (ret < 0)
-               return ret;
-       input->attached = 2;
-
-       ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux,
-                                        &input->hw_frontend,
-                                        &input->mem_frontend, adap);
-       if (ret < 0)
-               return ret;
-       input->attached = 3;
-
-       ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux);
-       if (ret < 0)
-               return ret;
-       input->attached = 4;
-
-       input->fe = 0;
-       switch (port->type) {
-       case DDB_TUNER_DVBS_ST:
-               if (demod_attach_stv0900(input, 0) < 0)
-                       return -ENODEV;
-               if (tuner_attach_stv6110(input, 0) < 0)
-                       return -ENODEV;
-               if (input->fe) {
-                       if (dvb_register_frontend(adap, input->fe) < 0)
-                               return -ENODEV;
-               }
-               break;
-       case DDB_TUNER_DVBS_ST_AA:
-               if (demod_attach_stv0900(input, 1) < 0)
-                       return -ENODEV;
-               if (tuner_attach_stv6110(input, 1) < 0)
-                       return -ENODEV;
-               if (input->fe) {
-                       if (dvb_register_frontend(adap, input->fe) < 0)
-                               return -ENODEV;
-               }
-               break;
-       case DDB_TUNER_DVBCT_TR:
-               if (demod_attach_drxk(input) < 0)
-                       return -ENODEV;
-               if (tuner_attach_tda18271(input) < 0)
-                       return -ENODEV;
-               if (input->fe) {
-                       if (dvb_register_frontend(adap, input->fe) < 0)
-                               return -ENODEV;
-               }
-               if (input->fe2) {
-                       if (dvb_register_frontend(adap, input->fe2) < 0)
-                               return -ENODEV;
-                       input->fe2->tuner_priv = input->fe->tuner_priv;
-                       memcpy(&input->fe2->ops.tuner_ops,
-                              &input->fe->ops.tuner_ops,
-                              sizeof(struct dvb_tuner_ops));
-               }
-               break;
-       }
-       input->attached = 5;
-       return 0;
-}
-
-/****************************************************************************/
-/****************************************************************************/
-
-static ssize_t ts_write(struct file *file, const char *buf,
-                       size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct ddb_output *output = dvbdev->priv;
-       size_t left = count;
-       int stat;
-
-       while (left) {
-               if (ddb_output_free(output) < 188) {
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-                       if (wait_event_interruptible(
-                                   output->wq, ddb_output_free(output) >= 188) < 0)
-                               break;
-               }
-               stat = ddb_output_write(output, buf, left);
-               if (stat < 0)
-                       break;
-               buf += stat;
-               left -= stat;
-       }
-       return (left == count) ? -EAGAIN : (count - left);
-}
-
-static ssize_t ts_read(struct file *file, char *buf,
-                      size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct ddb_output *output = dvbdev->priv;
-       struct ddb_input *input = output->port->input[0];
-       int left, read;
-
-       count -= count % 188;
-       left = count;
-       while (left) {
-               if (ddb_input_avail(input) < 188) {
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-                       if (wait_event_interruptible(
-                                   input->wq, ddb_input_avail(input) >= 188) < 0)
-                               break;
-               }
-               read = ddb_input_read(input, buf, left);
-               if (read < 0)
-                       return read;
-               left -= read;
-               buf += read;
-       }
-       return (left == count) ? -EAGAIN : (count - left);
-}
-
-static unsigned int ts_poll(struct file *file, poll_table *wait)
-{
-       /*
-       struct dvb_device *dvbdev = file->private_data;
-       struct ddb_output *output = dvbdev->priv;
-       struct ddb_input *input = output->port->input[0];
-       */
-       unsigned int mask = 0;
-
-#if 0
-       if (data_avail_to_read)
-               mask |= POLLIN | POLLRDNORM;
-       if (data_avail_to_write)
-               mask |= POLLOUT | POLLWRNORM;
-
-       poll_wait(file, &read_queue, wait);
-       poll_wait(file, &write_queue, wait);
-#endif
-       return mask;
-}
-
-static const struct file_operations ci_fops = {
-       .owner   = THIS_MODULE,
-       .read    = ts_read,
-       .write   = ts_write,
-       .open    = dvb_generic_open,
-       .release = dvb_generic_release,
-       .poll    = ts_poll,
-       .mmap    = 0,
-};
-
-static struct dvb_device dvbdev_ci = {
-       .priv    = 0,
-       .readers = -1,
-       .writers = -1,
-       .users   = -1,
-       .fops    = &ci_fops,
-};
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static void input_tasklet(unsigned long data)
-{
-       struct ddb_input *input = (struct ddb_input *) data;
-       struct ddb *dev = input->port->dev;
-
-       spin_lock(&input->lock);
-       if (!input->running) {
-               spin_unlock(&input->lock);
-               return;
-       }
-       input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr));
-
-       if (input->port->class == DDB_PORT_TUNER) {
-               if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))
-                       printk(KERN_ERR "Overflow input %d\n", input->nr);
-               while (input->cbuf != ((input->stat >> 11) & 0x1f)
-                      || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) {
-                       dvb_dmx_swfilter_packets(&input->demux,
-                                                input->vbuf[input->cbuf],
-                                                input->dma_buf_size / 188);
-
-                       input->cbuf = (input->cbuf + 1) % input->dma_buf_num;
-                       ddbwritel((input->cbuf << 11),
-                                 DMA_BUFFER_ACK(input->nr));
-                       input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr));
-                      }
-       }
-       if (input->port->class == DDB_PORT_CI)
-               wake_up(&input->wq);
-       spin_unlock(&input->lock);
-}
-
-static void output_tasklet(unsigned long data)
-{
-       struct ddb_output *output = (struct ddb_output *) data;
-       struct ddb *dev = output->port->dev;
-
-       spin_lock(&output->lock);
-       if (!output->running) {
-               spin_unlock(&output->lock);
-               return;
-       }
-       output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8));
-       wake_up(&output->wq);
-       spin_unlock(&output->lock);
-}
-
-
-struct cxd2099_cfg cxd_cfg = {
-       .bitrate =  62000,
-       .adr     =  0x40,
-       .polarity = 1,
-       .clock_mode = 1,
-};
-
-static int ddb_ci_attach(struct ddb_port *port)
-{
-       int ret;
-
-       ret = dvb_register_adapter(&port->output->adap,
-                                  "DDBridge",
-                                  THIS_MODULE,
-                                  &port->dev->pdev->dev,
-                                  adapter_nr);
-       if (ret < 0)
-               return ret;
-       port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
-       if (!port->en) {
-               dvb_unregister_adapter(&port->output->adap);
-               return -ENODEV;
-       }
-       ddb_input_start(port->input[0]);
-       ddb_output_start(port->output);
-       dvb_ca_en50221_init(&port->output->adap,
-                           port->en, 0, 1);
-       ret = dvb_register_device(&port->output->adap, &port->output->dev,
-                                 &dvbdev_ci, (void *) port->output,
-                                 DVB_DEVICE_SEC);
-       return ret;
-}
-
-static int ddb_port_attach(struct ddb_port *port)
-{
-       int ret = 0;
-
-       switch (port->class) {
-       case DDB_PORT_TUNER:
-               ret = dvb_input_attach(port->input[0]);
-               if (ret < 0)
-                       break;
-               ret = dvb_input_attach(port->input[1]);
-               break;
-       case DDB_PORT_CI:
-               ret = ddb_ci_attach(port);
-               break;
-       default:
-               break;
-       }
-       if (ret < 0)
-               printk(KERN_ERR "port_attach on port %d failed\n", port->nr);
-       return ret;
-}
-
-static int ddb_ports_attach(struct ddb *dev)
-{
-       int i, ret = 0;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               ret = ddb_port_attach(port);
-               if (ret < 0)
-                       break;
-       }
-       return ret;
-}
-
-static void ddb_ports_detach(struct ddb *dev)
-{
-       int i;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               switch (port->class) {
-               case DDB_PORT_TUNER:
-                       dvb_input_detach(port->input[0]);
-                       dvb_input_detach(port->input[1]);
-                       break;
-               case DDB_PORT_CI:
-                       if (port->output->dev)
-                               dvb_unregister_device(port->output->dev);
-                       if (port->en) {
-                               ddb_input_stop(port->input[0]);
-                               ddb_output_stop(port->output);
-                               dvb_ca_en50221_release(port->en);
-                               kfree(port->en);
-                               port->en = 0;
-                               dvb_unregister_adapter(&port->output->adap);
-                       }
-                       break;
-               }
-       }
-}
-
-/****************************************************************************/
-/****************************************************************************/
-
-static int port_has_ci(struct ddb_port *port)
-{
-       u8 val;
-       return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1;
-}
-
-static int port_has_stv0900(struct ddb_port *port)
-{
-       u8 val;
-       if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0)
-               return 0;
-       return 1;
-}
-
-static int port_has_stv0900_aa(struct ddb_port *port)
-{
-       u8 val;
-       if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0)
-               return 0;
-       return 1;
-}
-
-static int port_has_drxks(struct ddb_port *port)
-{
-       u8 val;
-       if (i2c_read(&port->i2c->adap, 0x29, &val) < 0)
-               return 0;
-       if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0)
-               return 0;
-       return 1;
-}
-
-static void ddb_port_probe(struct ddb_port *port)
-{
-       struct ddb *dev = port->dev;
-       char *modname = "NO MODULE";
-
-       port->class = DDB_PORT_NONE;
-
-       if (port_has_ci(port)) {
-               modname = "CI";
-               port->class = DDB_PORT_CI;
-               ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
-       } else if (port_has_stv0900(port)) {
-               modname = "DUAL DVB-S2";
-               port->class = DDB_PORT_TUNER;
-               port->type = DDB_TUNER_DVBS_ST;
-               ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
-       } else if (port_has_stv0900_aa(port)) {
-               modname = "DUAL DVB-S2";
-               port->class = DDB_PORT_TUNER;
-               port->type = DDB_TUNER_DVBS_ST_AA;
-               ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
-       } else if (port_has_drxks(port)) {
-               modname = "DUAL DVB-C/T";
-               port->class = DDB_PORT_TUNER;
-               port->type = DDB_TUNER_DVBCT_TR;
-               ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
-       }
-       printk(KERN_INFO "Port %d (TAB %d): %s\n",
-                        port->nr, port->nr+1, modname);
-}
-
-static void ddb_input_init(struct ddb_port *port, int nr)
-{
-       struct ddb *dev = port->dev;
-       struct ddb_input *input = &dev->input[nr];
-
-       input->nr = nr;
-       input->port = port;
-       input->dma_buf_num = INPUT_DMA_BUFS;
-       input->dma_buf_size = INPUT_DMA_SIZE;
-       ddbwritel(0, TS_INPUT_CONTROL(nr));
-       ddbwritel(2, TS_INPUT_CONTROL(nr));
-       ddbwritel(0, TS_INPUT_CONTROL(nr));
-       ddbwritel(0, DMA_BUFFER_ACK(nr));
-       tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input);
-       spin_lock_init(&input->lock);
-       init_waitqueue_head(&input->wq);
-}
-
-static void ddb_output_init(struct ddb_port *port, int nr)
-{
-       struct ddb *dev = port->dev;
-       struct ddb_output *output = &dev->output[nr];
-       output->nr = nr;
-       output->port = port;
-       output->dma_buf_num = OUTPUT_DMA_BUFS;
-       output->dma_buf_size = OUTPUT_DMA_SIZE;
-
-       ddbwritel(0, TS_OUTPUT_CONTROL(nr));
-       ddbwritel(2, TS_OUTPUT_CONTROL(nr));
-       ddbwritel(0, TS_OUTPUT_CONTROL(nr));
-       tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output);
-       init_waitqueue_head(&output->wq);
-}
-
-static void ddb_ports_init(struct ddb *dev)
-{
-       int i;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               port->dev = dev;
-               port->nr = i;
-               port->i2c = &dev->i2c[i];
-               port->input[0] = &dev->input[2 * i];
-               port->input[1] = &dev->input[2 * i + 1];
-               port->output = &dev->output[i];
-
-               mutex_init(&port->i2c_gate_lock);
-               ddb_port_probe(port);
-               ddb_input_init(port, 2 * i);
-               ddb_input_init(port, 2 * i + 1);
-               ddb_output_init(port, i);
-       }
-}
-
-static void ddb_ports_release(struct ddb *dev)
-{
-       int i;
-       struct ddb_port *port;
-
-       for (i = 0; i < dev->info->port_num; i++) {
-               port = &dev->port[i];
-               port->dev = dev;
-               tasklet_kill(&port->input[0]->tasklet);
-               tasklet_kill(&port->input[1]->tasklet);
-               tasklet_kill(&port->output->tasklet);
-       }
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static void irq_handle_i2c(struct ddb *dev, int n)
-{
-       struct ddb_i2c *i2c = &dev->i2c[n];
-
-       i2c->done = 1;
-       wake_up(&i2c->wq);
-}
-
-static irqreturn_t irq_handler(int irq, void *dev_id)
-{
-       struct ddb *dev = (struct ddb *) dev_id;
-       u32 s = ddbreadl(INTERRUPT_STATUS);
-
-       if (!s)
-               return IRQ_NONE;
-
-       do {
-               ddbwritel(s, INTERRUPT_ACK);
-
-               if (s & 0x00000001)
-                       irq_handle_i2c(dev, 0);
-               if (s & 0x00000002)
-                       irq_handle_i2c(dev, 1);
-               if (s & 0x00000004)
-                       irq_handle_i2c(dev, 2);
-               if (s & 0x00000008)
-                       irq_handle_i2c(dev, 3);
-
-               if (s & 0x00000100)
-                       tasklet_schedule(&dev->input[0].tasklet);
-               if (s & 0x00000200)
-                       tasklet_schedule(&dev->input[1].tasklet);
-               if (s & 0x00000400)
-                       tasklet_schedule(&dev->input[2].tasklet);
-               if (s & 0x00000800)
-                       tasklet_schedule(&dev->input[3].tasklet);
-               if (s & 0x00001000)
-                       tasklet_schedule(&dev->input[4].tasklet);
-               if (s & 0x00002000)
-                       tasklet_schedule(&dev->input[5].tasklet);
-               if (s & 0x00004000)
-                       tasklet_schedule(&dev->input[6].tasklet);
-               if (s & 0x00008000)
-                       tasklet_schedule(&dev->input[7].tasklet);
-
-               if (s & 0x00010000)
-                       tasklet_schedule(&dev->output[0].tasklet);
-               if (s & 0x00020000)
-                       tasklet_schedule(&dev->output[1].tasklet);
-               if (s & 0x00040000)
-                       tasklet_schedule(&dev->output[2].tasklet);
-               if (s & 0x00080000)
-                       tasklet_schedule(&dev->output[3].tasklet);
-
-               /* if (s & 0x000f0000)  printk(KERN_DEBUG "%08x\n", istat); */
-       } while ((s = ddbreadl(INTERRUPT_STATUS)));
-
-       return IRQ_HANDLED;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-
-static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
-{
-       u32 data, shift;
-
-       if (wlen > 4)
-               ddbwritel(1, SPI_CONTROL);
-       while (wlen > 4) {
-               /* FIXME: check for big-endian */
-               data = swab32(*(u32 *)wbuf);
-               wbuf += 4;
-               wlen -= 4;
-               ddbwritel(data, SPI_DATA);
-               while (ddbreadl(SPI_CONTROL) & 0x0004)
-                       ;
-       }
-
-       if (rlen)
-               ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL);
-       else
-               ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL);
-
-       data = 0;
-       shift = ((4 - wlen) * 8);
-       while (wlen) {
-               data <<= 8;
-               data |= *wbuf;
-               wlen--;
-               wbuf++;
-       }
-       if (shift)
-               data <<= shift;
-       ddbwritel(data, SPI_DATA);
-       while (ddbreadl(SPI_CONTROL) & 0x0004)
-               ;
-
-       if (!rlen) {
-               ddbwritel(0, SPI_CONTROL);
-               return 0;
-       }
-       if (rlen > 4)
-               ddbwritel(1, SPI_CONTROL);
-
-       while (rlen > 4) {
-               ddbwritel(0xffffffff, SPI_DATA);
-               while (ddbreadl(SPI_CONTROL) & 0x0004)
-                       ;
-               data = ddbreadl(SPI_DATA);
-               *(u32 *) rbuf = swab32(data);
-               rbuf += 4;
-               rlen -= 4;
-       }
-       ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL);
-       ddbwritel(0xffffffff, SPI_DATA);
-       while (ddbreadl(SPI_CONTROL) & 0x0004)
-               ;
-
-       data = ddbreadl(SPI_DATA);
-       ddbwritel(0, SPI_CONTROL);
-
-       if (rlen < 4)
-               data <<= ((4 - rlen) * 8);
-
-       while (rlen > 0) {
-               *rbuf = ((data >> 24) & 0xff);
-               data <<= 8;
-               rbuf++;
-               rlen--;
-       }
-       return 0;
-}
-
-#define DDB_MAGIC 'd'
-
-struct ddb_flashio {
-       __u8 *write_buf;
-       __u32 write_len;
-       __u8 *read_buf;
-       __u32 read_len;
-};
-
-#define IOCTL_DDB_FLASHIO  _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
-
-#define DDB_NAME "ddbridge"
-
-static u32 ddb_num;
-static struct ddb *ddbs[32];
-static struct class *ddb_class;
-static int ddb_major;
-
-static int ddb_open(struct inode *inode, struct file *file)
-{
-       struct ddb *dev = ddbs[iminor(inode)];
-
-       file->private_data = dev;
-       return 0;
-}
-
-static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ddb *dev = file->private_data;
-       void *parg = (void *)arg;
-       int res;
-
-       switch (cmd) {
-       case IOCTL_DDB_FLASHIO:
-       {
-               struct ddb_flashio fio;
-               u8 *rbuf, *wbuf;
-
-               if (copy_from_user(&fio, parg, sizeof(fio)))
-                       return -EFAULT;
-
-               if (fio.write_len > 1028 || fio.read_len > 1028)
-                       return -EINVAL;
-               if (fio.write_len + fio.read_len > 1028)
-                       return -EINVAL;
-
-               wbuf = &dev->iobuf[0];
-               rbuf = wbuf + fio.write_len;
-
-               if (copy_from_user(wbuf, fio.write_buf, fio.write_len))
-                       return -EFAULT;
-               res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len);
-               if (res)
-                       return res;
-               if (copy_to_user(fio.read_buf, rbuf, fio.read_len))
-                       return -EFAULT;
-               break;
-       }
-       default:
-               return -ENOTTY;
-       }
-       return 0;
-}
-
-static const struct file_operations ddb_fops = {
-       .unlocked_ioctl = ddb_ioctl,
-       .open           = ddb_open,
-};
-
-static char *ddb_devnode(struct device *device, umode_t *mode)
-{
-       struct ddb *dev = dev_get_drvdata(device);
-
-       return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr);
-}
-
-static int ddb_class_create(void)
-{
-       ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops);
-       if (ddb_major < 0)
-               return ddb_major;
-
-       ddb_class = class_create(THIS_MODULE, DDB_NAME);
-       if (IS_ERR(ddb_class)) {
-               unregister_chrdev(ddb_major, DDB_NAME);
-               return -1;
-       }
-       ddb_class->devnode = ddb_devnode;
-       return 0;
-}
-
-static void ddb_class_destroy(void)
-{
-       class_destroy(ddb_class);
-       unregister_chrdev(ddb_major, DDB_NAME);
-}
-
-static int ddb_device_create(struct ddb *dev)
-{
-       dev->nr = ddb_num++;
-       dev->ddb_dev = device_create(ddb_class, NULL,
-                                    MKDEV(ddb_major, dev->nr),
-                                    dev, "ddbridge%d", dev->nr);
-       ddbs[dev->nr] = dev;
-       if (IS_ERR(dev->ddb_dev))
-               return -1;
-       return 0;
-}
-
-static void ddb_device_destroy(struct ddb *dev)
-{
-       ddb_num--;
-       if (IS_ERR(dev->ddb_dev))
-               return;
-       device_destroy(ddb_class, MKDEV(ddb_major, 0));
-}
-
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static void ddb_unmap(struct ddb *dev)
-{
-       if (dev->regs)
-               iounmap(dev->regs);
-       vfree(dev);
-}
-
-
-static void __devexit ddb_remove(struct pci_dev *pdev)
-{
-       struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
-
-       ddb_ports_detach(dev);
-       ddb_i2c_release(dev);
-
-       ddbwritel(0, INTERRUPT_ENABLE);
-       free_irq(dev->pdev->irq, dev);
-#ifdef CONFIG_PCI_MSI
-       if (dev->msi)
-               pci_disable_msi(dev->pdev);
-#endif
-       ddb_ports_release(dev);
-       ddb_buffers_free(dev);
-       ddb_device_destroy(dev);
-
-       ddb_unmap(dev);
-       pci_set_drvdata(pdev, 0);
-       pci_disable_device(pdev);
-}
-
-
-static int __devinit ddb_probe(struct pci_dev *pdev,
-                              const struct pci_device_id *id)
-{
-       struct ddb *dev;
-       int stat = 0;
-       int irq_flag = IRQF_SHARED;
-
-       if (pci_enable_device(pdev) < 0)
-               return -ENODEV;
-
-       dev = vmalloc(sizeof(struct ddb));
-       if (dev == NULL)
-               return -ENOMEM;
-       memset(dev, 0, sizeof(struct ddb));
-
-       dev->pdev = pdev;
-       pci_set_drvdata(pdev, dev);
-       dev->info = (struct ddb_info *) id->driver_data;
-       printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name);
-
-       dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
-                           pci_resource_len(dev->pdev, 0));
-       if (!dev->regs) {
-               stat = -ENOMEM;
-               goto fail;
-       }
-       printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4));
-
-#ifdef CONFIG_PCI_MSI
-       if (pci_msi_enabled())
-               stat = pci_enable_msi(dev->pdev);
-       if (stat) {
-               printk(KERN_INFO ": MSI not available.\n");
-       } else {
-               irq_flag = 0;
-               dev->msi = 1;
-       }
-#endif
-       stat = request_irq(dev->pdev->irq, irq_handler,
-                          irq_flag, "DDBridge", (void *) dev);
-       if (stat < 0)
-               goto fail1;
-       ddbwritel(0, DMA_BASE_WRITE);
-       ddbwritel(0, DMA_BASE_READ);
-       ddbwritel(0xffffffff, INTERRUPT_ACK);
-       ddbwritel(0xfff0f, INTERRUPT_ENABLE);
-       ddbwritel(0, MSI1_ENABLE);
-
-       if (ddb_i2c_init(dev) < 0)
-               goto fail1;
-       ddb_ports_init(dev);
-       if (ddb_buffers_alloc(dev) < 0) {
-               printk(KERN_INFO ": Could not allocate buffer memory\n");
-               goto fail2;
-       }
-       if (ddb_ports_attach(dev) < 0)
-               goto fail3;
-       ddb_device_create(dev);
-       return 0;
-
-fail3:
-       ddb_ports_detach(dev);
-       printk(KERN_ERR "fail3\n");
-       ddb_ports_release(dev);
-fail2:
-       printk(KERN_ERR "fail2\n");
-       ddb_buffers_free(dev);
-fail1:
-       printk(KERN_ERR "fail1\n");
-       if (dev->msi)
-               pci_disable_msi(dev->pdev);
-       free_irq(dev->pdev->irq, dev);
-fail:
-       printk(KERN_ERR "fail\n");
-       ddb_unmap(dev);
-       pci_set_drvdata(pdev, 0);
-       pci_disable_device(pdev);
-       return -1;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-
-static struct ddb_info ddb_none = {
-       .type     = DDB_NONE,
-       .name     = "Digital Devices PCIe bridge",
-};
-
-static struct ddb_info ddb_octopus = {
-       .type     = DDB_OCTOPUS,
-       .name     = "Digital Devices Octopus DVB adapter",
-       .port_num = 4,
-};
-
-static struct ddb_info ddb_octopus_le = {
-       .type     = DDB_OCTOPUS,
-       .name     = "Digital Devices Octopus LE DVB adapter",
-       .port_num = 2,
-};
-
-static struct ddb_info ddb_v6 = {
-       .type     = DDB_OCTOPUS,
-       .name     = "Digital Devices Cine S2 V6 DVB adapter",
-       .port_num = 3,
-};
-
-#define DDVID 0xdd01 /* Digital Devices Vendor ID */
-
-#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) {  \
-       .vendor      = _vend,    .device    = _dev, \
-       .subvendor   = _subvend, .subdevice = _subdev, \
-       .driver_data = (unsigned long)&_driverdata }
-
-static const struct pci_device_id ddb_id_tbl[] __devinitdata = {
-       DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
-       DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
-       DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
-       DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus),
-       DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
-       /* in case sub-ids got deleted in flash */
-       DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
-       {0}
-};
-MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
-
-
-static struct pci_driver ddb_pci_driver = {
-       .name        = "DDBridge",
-       .id_table    = ddb_id_tbl,
-       .probe       = ddb_probe,
-       .remove      = __devexit_p(ddb_remove),
-};
-
-static __init int module_init_ddbridge(void)
-{
-       printk(KERN_INFO "Digital Devices PCIE bridge driver, "
-              "Copyright (C) 2010-11 Digital Devices GmbH\n");
-       if (ddb_class_create())
-               return -1;
-       return pci_register_driver(&ddb_pci_driver);
-}
-
-static __exit void module_exit_ddbridge(void)
-{
-       pci_unregister_driver(&ddb_pci_driver);
-       ddb_class_destroy();
-}
-
-module_init(module_init_ddbridge);
-module_exit(module_exit_ddbridge);
-
-MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
-MODULE_AUTHOR("Ralph Metzler");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.5");
diff --git a/drivers/media/dvb/ddbridge/ddbridge-regs.h b/drivers/media/dvb/ddbridge/ddbridge-regs.h
deleted file mode 100644 (file)
index a3ccb31..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * ddbridge-regs.h: Digital Devices PCIe bridge driver
- *
- * Copyright (C) 2010-2011 Digital Devices GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-/* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */
-
-/* Register Definitions */
-
-#define CUR_REGISTERMAP_VERSION 0x10000
-
-#define HARDWARE_VERSION       0x00
-#define REGISTERMAP_VERSION    0x04
-
-/* ------------------------------------------------------------------------- */
-/* SPI Controller */
-
-#define SPI_CONTROL     0x10
-#define SPI_DATA        0x14
-
-/* ------------------------------------------------------------------------- */
-
-/* Interrupt controller                                     */
-/* How many MSI's are available depends on HW (Min 2 max 8) */
-/* How many are usable also depends on Host platform        */
-
-#define INTERRUPT_BASE   (0x40)
-
-#define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00)
-#define MSI0_ENABLE      (INTERRUPT_BASE + 0x00)
-#define MSI1_ENABLE      (INTERRUPT_BASE + 0x04)
-#define MSI2_ENABLE      (INTERRUPT_BASE + 0x08)
-#define MSI3_ENABLE      (INTERRUPT_BASE + 0x0C)
-#define MSI4_ENABLE      (INTERRUPT_BASE + 0x10)
-#define MSI5_ENABLE      (INTERRUPT_BASE + 0x14)
-#define MSI6_ENABLE      (INTERRUPT_BASE + 0x18)
-#define MSI7_ENABLE      (INTERRUPT_BASE + 0x1C)
-
-#define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20)
-#define INTERRUPT_ACK    (INTERRUPT_BASE + 0x20)
-
-#define INTMASK_I2C1        (0x00000001)
-#define INTMASK_I2C2        (0x00000002)
-#define INTMASK_I2C3        (0x00000004)
-#define INTMASK_I2C4        (0x00000008)
-
-#define INTMASK_CIRQ1       (0x00000010)
-#define INTMASK_CIRQ2       (0x00000020)
-#define INTMASK_CIRQ3       (0x00000040)
-#define INTMASK_CIRQ4       (0x00000080)
-
-#define INTMASK_TSINPUT1    (0x00000100)
-#define INTMASK_TSINPUT2    (0x00000200)
-#define INTMASK_TSINPUT3    (0x00000400)
-#define INTMASK_TSINPUT4    (0x00000800)
-#define INTMASK_TSINPUT5    (0x00001000)
-#define INTMASK_TSINPUT6    (0x00002000)
-#define INTMASK_TSINPUT7    (0x00004000)
-#define INTMASK_TSINPUT8    (0x00008000)
-
-#define INTMASK_TSOUTPUT1   (0x00010000)
-#define INTMASK_TSOUTPUT2   (0x00020000)
-#define INTMASK_TSOUTPUT3   (0x00040000)
-#define INTMASK_TSOUTPUT4   (0x00080000)
-
-/* ------------------------------------------------------------------------- */
-/* I2C Master Controller */
-
-#define I2C_BASE        (0x80)  /* Byte offset */
-
-#define I2C_COMMAND     (0x00)
-#define I2C_TIMING      (0x04)
-#define I2C_TASKLENGTH  (0x08)     /* High read, low write */
-#define I2C_TASKADDRESS (0x0C)     /* High read, low write */
-
-#define I2C_MONITOR     (0x1C)
-
-#define I2C_BASE_1      (I2C_BASE + 0x00)
-#define I2C_BASE_2      (I2C_BASE + 0x20)
-#define I2C_BASE_3      (I2C_BASE + 0x40)
-#define I2C_BASE_4      (I2C_BASE + 0x60)
-
-#define I2C_BASE_N(i)   (I2C_BASE + (i) * 0x20)
-
-#define I2C_TASKMEM_BASE    (0x1000)    /* Byte offset */
-#define I2C_TASKMEM_SIZE    (0x1000)
-
-#define I2C_SPEED_400   (0x04030404)
-#define I2C_SPEED_200   (0x09080909)
-#define I2C_SPEED_154   (0x0C0B0C0C)
-#define I2C_SPEED_100   (0x13121313)
-#define I2C_SPEED_77    (0x19181919)
-#define I2C_SPEED_50    (0x27262727)
-
-
-/* ------------------------------------------------------------------------- */
-/* DMA  Controller */
-
-#define DMA_BASE_WRITE        (0x100)
-#define DMA_BASE_READ         (0x140)
-
-#define DMA_CONTROL     (0x00)                  /* 64 */
-#define DMA_ERROR       (0x04)                  /* 65 ( only read instance ) */
-
-#define DMA_DIAG_CONTROL                (0x1C)  /* 71 */
-#define DMA_DIAG_PACKETCOUNTER_LOW      (0x20)  /* 72 */
-#define DMA_DIAG_PACKETCOUNTER_HIGH     (0x24)  /* 73 */
-#define DMA_DIAG_TIMECOUNTER_LOW        (0x28)  /* 74 */
-#define DMA_DIAG_TIMECOUNTER_HIGH       (0x2C)  /* 75 */
-#define DMA_DIAG_RECHECKCOUNTER         (0x30)  /* 76  ( Split completions on read ) */
-#define DMA_DIAG_WAITTIMEOUTINIT        (0x34)  /* 77 */
-#define DMA_DIAG_WAITOVERFLOWCOUNTER    (0x38)  /* 78 */
-#define DMA_DIAG_WAITCOUNTER            (0x3C)  /* 79 */
-
-/* ------------------------------------------------------------------------- */
-/* DMA  Buffer */
-
-#define TS_INPUT_BASE       (0x200)
-#define TS_INPUT_CONTROL(i)         (TS_INPUT_BASE + (i) * 16 + 0x00)
-
-#define TS_OUTPUT_BASE       (0x280)
-#define TS_OUTPUT_CONTROL(i)         (TS_OUTPUT_BASE + (i) * 16 + 0x00)
-
-#define DMA_BUFFER_BASE     (0x300)
-
-#define DMA_BUFFER_CONTROL(i)       (DMA_BUFFER_BASE + (i) * 16 + 0x00)
-#define DMA_BUFFER_ACK(i)           (DMA_BUFFER_BASE + (i) * 16 + 0x04)
-#define DMA_BUFFER_CURRENT(i)       (DMA_BUFFER_BASE + (i) * 16 + 0x08)
-#define DMA_BUFFER_SIZE(i)          (DMA_BUFFER_BASE + (i) * 16 + 0x0c)
-
-#define DMA_BASE_ADDRESS_TABLE  (0x2000)
-#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512)
-
diff --git a/drivers/media/dvb/ddbridge/ddbridge.h b/drivers/media/dvb/ddbridge/ddbridge.h
deleted file mode 100644 (file)
index 8b1b41d..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * ddbridge.h: Digital Devices PCIe bridge driver
- *
- * Copyright (C) 2010-2011 Digital Devices GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef _DDBRIDGE_H_
-#define _DDBRIDGE_H_
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <asm/dma.h>
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/ca.h>
-#include <linux/socket.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_net.h"
-#include "cxd2099.h"
-
-#define DDB_MAX_I2C     4
-#define DDB_MAX_PORT    4
-#define DDB_MAX_INPUT   8
-#define DDB_MAX_OUTPUT  4
-
-struct ddb_info {
-       int   type;
-#define DDB_NONE         0
-#define DDB_OCTOPUS      1
-       char *name;
-       int   port_num;
-       u32   port_type[DDB_MAX_PORT];
-};
-
-/* DMA_SIZE MUST be divisible by 188 and 128 !!! */
-
-#define INPUT_DMA_MAX_BUFS 32      /* hardware table limit */
-#define INPUT_DMA_BUFS 8
-#define INPUT_DMA_SIZE (128*47*21)
-
-#define OUTPUT_DMA_MAX_BUFS 32
-#define OUTPUT_DMA_BUFS 8
-#define OUTPUT_DMA_SIZE (128*47*21)
-
-struct ddb;
-struct ddb_port;
-
-struct ddb_input {
-       struct ddb_port       *port;
-       u32                    nr;
-       int                    attached;
-
-       dma_addr_t             pbuf[INPUT_DMA_MAX_BUFS];
-       u8                    *vbuf[INPUT_DMA_MAX_BUFS];
-       u32                    dma_buf_num;
-       u32                    dma_buf_size;
-
-       struct tasklet_struct  tasklet;
-       spinlock_t             lock;
-       wait_queue_head_t      wq;
-       int                    running;
-       u32                    stat;
-       u32                    cbuf;
-       u32                    coff;
-
-       struct dvb_adapter     adap;
-       struct dvb_device     *dev;
-       struct dvb_frontend   *fe;
-       struct dvb_frontend   *fe2;
-       struct dmxdev          dmxdev;
-       struct dvb_demux       demux;
-       struct dvb_net         dvbnet;
-       struct dmx_frontend    hw_frontend;
-       struct dmx_frontend    mem_frontend;
-       int                    users;
-       int (*gate_ctrl)(struct dvb_frontend *, int);
-};
-
-struct ddb_output {
-       struct ddb_port       *port;
-       u32                    nr;
-       dma_addr_t             pbuf[OUTPUT_DMA_MAX_BUFS];
-       u8                    *vbuf[OUTPUT_DMA_MAX_BUFS];
-       u32                    dma_buf_num;
-       u32                    dma_buf_size;
-       struct tasklet_struct  tasklet;
-       spinlock_t             lock;
-       wait_queue_head_t      wq;
-       int                    running;
-       u32                    stat;
-       u32                    cbuf;
-       u32                    coff;
-
-       struct dvb_adapter     adap;
-       struct dvb_device     *dev;
-};
-
-struct ddb_i2c {
-       struct ddb            *dev;
-       u32                    nr;
-       struct i2c_adapter     adap;
-       struct i2c_adapter     adap2;
-       u32                    regs;
-       u32                    rbuf;
-       u32                    wbuf;
-       int                    done;
-       wait_queue_head_t      wq;
-};
-
-struct ddb_port {
-       struct ddb            *dev;
-       u32                    nr;
-       struct ddb_i2c        *i2c;
-       struct mutex           i2c_gate_lock;
-       u32                    class;
-#define DDB_PORT_NONE           0
-#define DDB_PORT_CI             1
-#define DDB_PORT_TUNER          2
-       u32                    type;
-#define DDB_TUNER_NONE          0
-#define DDB_TUNER_DVBS_ST       1
-#define DDB_TUNER_DVBS_ST_AA    2
-#define DDB_TUNER_DVBCT_TR     16
-#define DDB_TUNER_DVBCT_ST     17
-       u32                    adr;
-
-       struct ddb_input      *input[2];
-       struct ddb_output     *output;
-       struct dvb_ca_en50221 *en;
-};
-
-struct ddb {
-       struct pci_dev        *pdev;
-       unsigned char         *regs;
-       struct ddb_port        port[DDB_MAX_PORT];
-       struct ddb_i2c         i2c[DDB_MAX_I2C];
-       struct ddb_input       input[DDB_MAX_INPUT];
-       struct ddb_output      output[DDB_MAX_OUTPUT];
-
-       struct device         *ddb_dev;
-       int                    nr;
-       u8                     iobuf[1028];
-
-       struct ddb_info       *info;
-       int                    msi;
-};
-
-/****************************************************************************/
-
-#define ddbwritel(_val, _adr)        writel((_val), \
-                                    (char *) (dev->regs+(_adr)))
-#define ddbreadl(_adr)               readl((char *) (dev->regs+(_adr)))
-#define ddbcpyto(_adr, _src, _count) memcpy_toio((char *)      \
-                                    (dev->regs+(_adr)), (_src), (_count))
-#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), (char *) \
-                                      (dev->regs+(_adr)), (_count))
-
-/****************************************************************************/
-
-#endif
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
deleted file mode 100644 (file)
index f3de0a4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-config DVB_DM1105
-       tristate "SDMC DM1105 based PCI cards"
-       depends on DVB_CORE && PCI && I2C
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_STV0288 if !DVB_FE_CUSTOMISE
-       select DVB_STB6000 if !DVB_FE_CUSTOMISE
-       select DVB_CX24116 if !DVB_FE_CUSTOMISE
-       select DVB_SI21XX if !DVB_FE_CUSTOMISE
-       select DVB_DS3000 if !DVB_FE_CUSTOMISE
-       depends on RC_CORE
-       help
-         Support for cards based on the SDMC DM1105 PCI chip like
-         DvbWorld 2002
-
-         Since these cards have no MPEG decoder onboard, they transmit
-         only compressed MPEG data over the PCI bus, so you need
-         an external software decoder to watch TV on your computer.
-
-         Say Y or M if you own such a device and want to use it.
diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile
deleted file mode 100644 (file)
index 3275851..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_DM1105) += dm1105.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
deleted file mode 100644 (file)
index a609b3a..0000000
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip
- *
- * Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
- *
- * 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/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <media/rc-core.h>
-
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
-#include "dvb-pll.h"
-
-#include "stv0299.h"
-#include "stv0288.h"
-#include "stb6000.h"
-#include "si21xx.h"
-#include "cx24116.h"
-#include "z0194a.h"
-#include "ds3000.h"
-
-#define MODULE_NAME "dm1105"
-
-#define UNSET (-1U)
-
-#define DM1105_BOARD_NOAUTO                    UNSET
-#define DM1105_BOARD_UNKNOWN                   0
-#define DM1105_BOARD_DVBWORLD_2002             1
-#define DM1105_BOARD_DVBWORLD_2004             2
-#define DM1105_BOARD_AXESS_DM05                        3
-#define DM1105_BOARD_UNBRANDED_I2C_ON_GPIO     4
-
-/* ----------------------------------------------- */
-/*
- * PCI ID's
- */
-#ifndef PCI_VENDOR_ID_TRIGEM
-#define PCI_VENDOR_ID_TRIGEM   0x109f
-#endif
-#ifndef PCI_VENDOR_ID_AXESS
-#define PCI_VENDOR_ID_AXESS    0x195d
-#endif
-#ifndef PCI_DEVICE_ID_DM1105
-#define PCI_DEVICE_ID_DM1105   0x036f
-#endif
-#ifndef PCI_DEVICE_ID_DW2002
-#define PCI_DEVICE_ID_DW2002   0x2002
-#endif
-#ifndef PCI_DEVICE_ID_DW2004
-#define PCI_DEVICE_ID_DW2004   0x2004
-#endif
-#ifndef PCI_DEVICE_ID_DM05
-#define PCI_DEVICE_ID_DM05     0x1105
-#endif
-/* ----------------------------------------------- */
-/* sdmc dm1105 registers */
-
-/* TS Control */
-#define DM1105_TSCTR                           0x00
-#define DM1105_DTALENTH                                0x04
-
-/* GPIO Interface */
-#define DM1105_GPIOVAL                         0x08
-#define DM1105_GPIOCTR                         0x0c
-
-/* PID serial number */
-#define DM1105_PIDN                            0x10
-
-/* Odd-even secret key select */
-#define DM1105_CWSEL                           0x14
-
-/* Host Command Interface */
-#define DM1105_HOST_CTR                                0x18
-#define DM1105_HOST_AD                         0x1c
-
-/* PCI Interface */
-#define DM1105_CR                              0x30
-#define DM1105_RST                             0x34
-#define DM1105_STADR                           0x38
-#define DM1105_RLEN                            0x3c
-#define DM1105_WRP                             0x40
-#define DM1105_INTCNT                          0x44
-#define DM1105_INTMAK                          0x48
-#define DM1105_INTSTS                          0x4c
-
-/* CW Value */
-#define DM1105_ODD                             0x50
-#define DM1105_EVEN                            0x58
-
-/* PID Value */
-#define DM1105_PID                             0x60
-
-/* IR Control */
-#define DM1105_IRCTR                           0x64
-#define DM1105_IRMODE                          0x68
-#define DM1105_SYSTEMCODE                      0x6c
-#define DM1105_IRCODE                          0x70
-
-/* Unknown Values */
-#define DM1105_ENCRYPT                         0x74
-#define DM1105_VER                             0x7c
-
-/* I2C Interface */
-#define DM1105_I2CCTR                          0x80
-#define DM1105_I2CSTS                          0x81
-#define DM1105_I2CDAT                          0x82
-#define DM1105_I2C_RA                          0x83
-/* ----------------------------------------------- */
-/* Interrupt Mask Bits */
-
-#define INTMAK_TSIRQM                          0x01
-#define INTMAK_HIRQM                           0x04
-#define INTMAK_IRM                             0x08
-#define INTMAK_ALLMASK                         (INTMAK_TSIRQM | \
-                                               INTMAK_HIRQM | \
-                                               INTMAK_IRM)
-#define INTMAK_NONEMASK                                0x00
-
-/* Interrupt Status Bits */
-#define INTSTS_TSIRQ                           0x01
-#define INTSTS_HIRQ                            0x04
-#define INTSTS_IR                              0x08
-
-/* IR Control Bits */
-#define DM1105_IR_EN                           0x01
-#define DM1105_SYS_CHK                         0x02
-#define DM1105_REP_FLG                         0x08
-
-/* EEPROM addr */
-#define IIC_24C01_addr                         0xa0
-/* Max board count */
-#define DM1105_MAX                             0x04
-
-#define DRIVER_NAME                            "dm1105"
-#define DM1105_I2C_GPIO_NAME                   "dm1105-gpio"
-
-#define DM1105_DMA_PACKETS                     47
-#define DM1105_DMA_PACKET_LENGTH               (128*4)
-#define DM1105_DMA_BYTES                       (128 * 4 * DM1105_DMA_PACKETS)
-
-/*  */
-#define GPIO08                                 (1 << 8)
-#define GPIO13                                 (1 << 13)
-#define GPIO14                                 (1 << 14)
-#define GPIO15                                 (1 << 15)
-#define GPIO16                                 (1 << 16)
-#define GPIO17                                 (1 << 17)
-#define GPIO_ALL                               0x03ffff
-
-/* GPIO's for LNB power control */
-#define DM1105_LNB_MASK                                (GPIO_ALL & ~(GPIO14 | GPIO13))
-#define DM1105_LNB_OFF                         GPIO17
-#define DM1105_LNB_13V                         (GPIO16 | GPIO08)
-#define DM1105_LNB_18V                         GPIO08
-
-/* GPIO's for LNB power control for Axess DM05 */
-#define DM05_LNB_MASK                          (GPIO_ALL & ~(GPIO14 | GPIO13))
-#define DM05_LNB_OFF                           GPIO17/* actually 13v */
-#define DM05_LNB_13V                           GPIO17
-#define DM05_LNB_18V                           (GPIO17 | GPIO16)
-
-/* GPIO's for LNB power control for unbranded with I2C on GPIO */
-#define UNBR_LNB_MASK                          (GPIO17 | GPIO16)
-#define UNBR_LNB_OFF                           0
-#define UNBR_LNB_13V                           GPIO17
-#define UNBR_LNB_18V                           (GPIO17 | GPIO16)
-
-static unsigned int card[]  = {[0 ... 3] = UNSET };
-module_param_array(card,  int, NULL, 0444);
-MODULE_PARM_DESC(card, "card type");
-
-static int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
-
-static unsigned int dm1105_devcount;
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct dm1105_board {
-       char    *name;
-       struct  {
-               u32     mask, off, v13, v18;
-       } lnb;
-       u32     gpio_scl, gpio_sda;
-};
-
-struct dm1105_subid {
-       u16     subvendor;
-       u16     subdevice;
-       u32     card;
-};
-
-static const struct dm1105_board dm1105_boards[] = {
-       [DM1105_BOARD_UNKNOWN] = {
-               .name           = "UNKNOWN/GENERIC",
-               .lnb = {
-                       .mask = DM1105_LNB_MASK,
-                       .off = DM1105_LNB_OFF,
-                       .v13 = DM1105_LNB_13V,
-                       .v18 = DM1105_LNB_18V,
-               },
-       },
-       [DM1105_BOARD_DVBWORLD_2002] = {
-               .name           = "DVBWorld PCI 2002",
-               .lnb = {
-                       .mask = DM1105_LNB_MASK,
-                       .off = DM1105_LNB_OFF,
-                       .v13 = DM1105_LNB_13V,
-                       .v18 = DM1105_LNB_18V,
-               },
-       },
-       [DM1105_BOARD_DVBWORLD_2004] = {
-               .name           = "DVBWorld PCI 2004",
-               .lnb = {
-                       .mask = DM1105_LNB_MASK,
-                       .off = DM1105_LNB_OFF,
-                       .v13 = DM1105_LNB_13V,
-                       .v18 = DM1105_LNB_18V,
-               },
-       },
-       [DM1105_BOARD_AXESS_DM05] = {
-               .name           = "Axess/EasyTv DM05",
-               .lnb = {
-                       .mask = DM05_LNB_MASK,
-                       .off = DM05_LNB_OFF,
-                       .v13 = DM05_LNB_13V,
-                       .v18 = DM05_LNB_18V,
-               },
-       },
-       [DM1105_BOARD_UNBRANDED_I2C_ON_GPIO] = {
-               .name           = "Unbranded DM1105 with i2c on GPIOs",
-               .lnb = {
-                       .mask = UNBR_LNB_MASK,
-                       .off = UNBR_LNB_OFF,
-                       .v13 = UNBR_LNB_13V,
-                       .v18 = UNBR_LNB_18V,
-               },
-               .gpio_scl       = GPIO14,
-               .gpio_sda       = GPIO13,
-       },
-};
-
-static const struct dm1105_subid dm1105_subids[] = {
-       {
-               .subvendor = 0x0000,
-               .subdevice = 0x2002,
-               .card      = DM1105_BOARD_DVBWORLD_2002,
-       }, {
-               .subvendor = 0x0001,
-               .subdevice = 0x2002,
-               .card      = DM1105_BOARD_DVBWORLD_2002,
-       }, {
-               .subvendor = 0x0000,
-               .subdevice = 0x2004,
-               .card      = DM1105_BOARD_DVBWORLD_2004,
-       }, {
-               .subvendor = 0x0001,
-               .subdevice = 0x2004,
-               .card      = DM1105_BOARD_DVBWORLD_2004,
-       }, {
-               .subvendor = 0x195d,
-               .subdevice = 0x1105,
-               .card      = DM1105_BOARD_AXESS_DM05,
-       },
-};
-
-static void dm1105_card_list(struct pci_dev *pci)
-{
-       int i;
-
-       if (0 == pci->subsystem_vendor &&
-                       0 == pci->subsystem_device) {
-               printk(KERN_ERR
-                       "dm1105: Your board has no valid PCI Subsystem ID\n"
-                       "dm1105: and thus can't be autodetected\n"
-                       "dm1105: Please pass card=<n> insmod option to\n"
-                       "dm1105: workaround that.  Redirect complaints to\n"
-                       "dm1105: the vendor of the TV card.  Best regards,\n"
-                       "dm1105: -- tux\n");
-       } else {
-               printk(KERN_ERR
-                       "dm1105: Your board isn't known (yet) to the driver.\n"
-                       "dm1105: You can try to pick one of the existing\n"
-                       "dm1105: card configs via card=<n> insmod option.\n"
-                       "dm1105: Updating to the latest version might help\n"
-                       "dm1105: as well.\n");
-       }
-       printk(KERN_ERR "Here is a list of valid choices for the card=<n> "
-                  "insmod option:\n");
-       for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)
-               printk(KERN_ERR "dm1105:    card=%d -> %s\n",
-                               i, dm1105_boards[i].name);
-}
-
-/* infrared remote control */
-struct infrared {
-       struct rc_dev           *dev;
-       char                    input_phys[32];
-       struct work_struct      work;
-       u32                     ir_command;
-};
-
-struct dm1105_dev {
-       /* pci */
-       struct pci_dev *pdev;
-       u8 __iomem *io_mem;
-
-       /* ir */
-       struct infrared ir;
-
-       /* dvb */
-       struct dmx_frontend hw_frontend;
-       struct dmx_frontend mem_frontend;
-       struct dmxdev dmxdev;
-       struct dvb_adapter dvb_adapter;
-       struct dvb_demux demux;
-       struct dvb_frontend *fe;
-       struct dvb_net dvbnet;
-       unsigned int full_ts_users;
-       unsigned int boardnr;
-       int nr;
-
-       /* i2c */
-       struct i2c_adapter i2c_adap;
-       struct i2c_adapter i2c_bb_adap;
-       struct i2c_algo_bit_data i2c_bit;
-
-       /* irq */
-       struct work_struct work;
-       struct workqueue_struct *wq;
-       char wqn[16];
-
-       /* dma */
-       dma_addr_t dma_addr;
-       unsigned char *ts_buf;
-       u32 wrp;
-       u32 nextwrp;
-       u32 buffer_size;
-       unsigned int    PacketErrorCount;
-       unsigned int dmarst;
-       spinlock_t lock;
-};
-
-#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
-
-#define dm_readb(reg)          inb(dm_io_mem(reg))
-#define dm_writeb(reg, value)  outb((value), (dm_io_mem(reg)))
-
-#define dm_readw(reg)          inw(dm_io_mem(reg))
-#define dm_writew(reg, value)  outw((value), (dm_io_mem(reg)))
-
-#define dm_readl(reg)          inl(dm_io_mem(reg))
-#define dm_writel(reg, value)  outl((value), (dm_io_mem(reg)))
-
-#define dm_andorl(reg, mask, value) \
-       outl((inl(dm_io_mem(reg)) & ~(mask)) |\
-               ((value) & (mask)), (dm_io_mem(reg)))
-
-#define dm_setl(reg, bit)      dm_andorl((reg), (bit), (bit))
-#define dm_clearl(reg, bit)    dm_andorl((reg), (bit), 0)
-
-/* The chip has 18 GPIOs. In HOST mode GPIO's used as 15 bit address lines,
- so we can use only 3 GPIO's from GPIO15 to GPIO17.
- Here I don't check whether HOST is enebled as it is not implemented yet.
- */
-static void dm1105_gpio_set(struct dm1105_dev *dev, u32 mask)
-{
-       if (mask & 0xfffc0000)
-               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
-
-       if (mask & 0x0003ffff)
-               dm_setl(DM1105_GPIOVAL, mask & 0x0003ffff);
-
-}
-
-static void dm1105_gpio_clear(struct dm1105_dev *dev, u32 mask)
-{
-       if (mask & 0xfffc0000)
-               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
-
-       if (mask & 0x0003ffff)
-               dm_clearl(DM1105_GPIOVAL, mask & 0x0003ffff);
-
-}
-
-static void dm1105_gpio_andor(struct dm1105_dev *dev, u32 mask, u32 val)
-{
-       if (mask & 0xfffc0000)
-               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
-
-       if (mask & 0x0003ffff)
-               dm_andorl(DM1105_GPIOVAL, mask & 0x0003ffff, val);
-
-}
-
-static u32 dm1105_gpio_get(struct dm1105_dev *dev, u32 mask)
-{
-       if (mask & 0xfffc0000)
-               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
-
-       if (mask & 0x0003ffff)
-               return dm_readl(DM1105_GPIOVAL) & mask & 0x0003ffff;
-
-       return 0;
-}
-
-static void dm1105_gpio_enable(struct dm1105_dev *dev, u32 mask, int asoutput)
-{
-       if (mask & 0xfffc0000)
-               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
-
-       if ((mask & 0x0003ffff) && asoutput)
-               dm_clearl(DM1105_GPIOCTR, mask & 0x0003ffff);
-       else if ((mask & 0x0003ffff) && !asoutput)
-               dm_setl(DM1105_GPIOCTR, mask & 0x0003ffff);
-
-}
-
-static void dm1105_setline(struct dm1105_dev *dev, u32 line, int state)
-{
-       if (state)
-               dm1105_gpio_enable(dev, line, 0);
-       else {
-               dm1105_gpio_enable(dev, line, 1);
-               dm1105_gpio_clear(dev, line);
-       }
-}
-
-static void dm1105_setsda(void *data, int state)
-{
-       struct dm1105_dev *dev = data;
-
-       dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_sda, state);
-}
-
-static void dm1105_setscl(void *data, int state)
-{
-       struct dm1105_dev *dev = data;
-
-       dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_scl, state);
-}
-
-static int dm1105_getsda(void *data)
-{
-       struct dm1105_dev *dev = data;
-
-       return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_sda)
-                                                                       ? 1 : 0;
-}
-
-static int dm1105_getscl(void *data)
-{
-       struct dm1105_dev *dev = data;
-
-       return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_scl)
-                                                                       ? 1 : 0;
-}
-
-static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
-                           struct i2c_msg *msgs, int num)
-{
-       struct dm1105_dev *dev ;
-
-       int addr, rc, i, j, k, len, byte, data;
-       u8 status;
-
-       dev = i2c_adap->algo_data;
-       for (i = 0; i < num; i++) {
-               dm_writeb(DM1105_I2CCTR, 0x00);
-               if (msgs[i].flags & I2C_M_RD) {
-                       /* read bytes */
-                       addr  = msgs[i].addr << 1;
-                       addr |= 1;
-                       dm_writeb(DM1105_I2CDAT, addr);
-                       for (byte = 0; byte < msgs[i].len; byte++)
-                               dm_writeb(DM1105_I2CDAT + byte + 1, 0);
-
-                       dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
-                       for (j = 0; j < 55; j++) {
-                               mdelay(10);
-                               status = dm_readb(DM1105_I2CSTS);
-                               if ((status & 0xc0) == 0x40)
-                                       break;
-                       }
-                       if (j >= 55)
-                               return -1;
-
-                       for (byte = 0; byte < msgs[i].len; byte++) {
-                               rc = dm_readb(DM1105_I2CDAT + byte + 1);
-                               if (rc < 0)
-                                       goto err;
-                               msgs[i].buf[byte] = rc;
-                       }
-               } else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
-                       /* prepaired for cx24116 firmware */
-                       /* Write in small blocks */
-                       len = msgs[i].len - 1;
-                       k = 1;
-                       do {
-                               dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
-                               dm_writeb(DM1105_I2CDAT + 1, 0xf7);
-                               for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
-                                       data = msgs[i].buf[k + byte];
-                                       dm_writeb(DM1105_I2CDAT + byte + 2, data);
-                               }
-                               dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len));
-                               for (j = 0; j < 25; j++) {
-                                       mdelay(10);
-                                       status = dm_readb(DM1105_I2CSTS);
-                                       if ((status & 0xc0) == 0x40)
-                                               break;
-                               }
-
-                               if (j >= 25)
-                                       return -1;
-
-                               k += 48;
-                               len -= 48;
-                       } while (len > 0);
-               } else {
-                       /* write bytes */
-                       dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
-                       for (byte = 0; byte < msgs[i].len; byte++) {
-                               data = msgs[i].buf[byte];
-                               dm_writeb(DM1105_I2CDAT + byte + 1, data);
-                       }
-                       dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
-                       for (j = 0; j < 25; j++) {
-                               mdelay(10);
-                               status = dm_readb(DM1105_I2CSTS);
-                               if ((status & 0xc0) == 0x40)
-                                       break;
-                       }
-
-                       if (j >= 25)
-                               return -1;
-               }
-       }
-       return num;
- err:
-       return rc;
-}
-
-static u32 functionality(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dm1105_algo = {
-       .master_xfer   = dm1105_i2c_xfer,
-       .functionality = functionality,
-};
-
-static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed)
-{
-       return container_of(feed->demux, struct dm1105_dev, demux);
-}
-
-static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe)
-{
-       return container_of(fe->dvb, struct dm1105_dev, dvb_adapter);
-}
-
-static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);
-
-       dm1105_gpio_enable(dev, dm1105_boards[dev->boardnr].lnb.mask, 1);
-       if (voltage == SEC_VOLTAGE_18)
-               dm1105_gpio_andor(dev,
-                               dm1105_boards[dev->boardnr].lnb.mask,
-                               dm1105_boards[dev->boardnr].lnb.v18);
-       else if (voltage == SEC_VOLTAGE_13)
-               dm1105_gpio_andor(dev,
-                               dm1105_boards[dev->boardnr].lnb.mask,
-                               dm1105_boards[dev->boardnr].lnb.v13);
-       else
-               dm1105_gpio_andor(dev,
-                               dm1105_boards[dev->boardnr].lnb.mask,
-                               dm1105_boards[dev->boardnr].lnb.off);
-
-       return 0;
-}
-
-static void dm1105_set_dma_addr(struct dm1105_dev *dev)
-{
-       dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));
-}
-
-static int __devinit dm1105_dma_map(struct dm1105_dev *dev)
-{
-       dev->ts_buf = pci_alloc_consistent(dev->pdev,
-                                       6 * DM1105_DMA_BYTES,
-                                       &dev->dma_addr);
-
-       return !dev->ts_buf;
-}
-
-static void dm1105_dma_unmap(struct dm1105_dev *dev)
-{
-       pci_free_consistent(dev->pdev,
-                       6 * DM1105_DMA_BYTES,
-                       dev->ts_buf,
-                       dev->dma_addr);
-}
-
-static void dm1105_enable_irqs(struct dm1105_dev *dev)
-{
-       dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK);
-       dm_writeb(DM1105_CR, 1);
-}
-
-static void dm1105_disable_irqs(struct dm1105_dev *dev)
-{
-       dm_writeb(DM1105_INTMAK, INTMAK_IRM);
-       dm_writeb(DM1105_CR, 0);
-}
-
-static int dm1105_start_feed(struct dvb_demux_feed *f)
-{
-       struct dm1105_dev *dev = feed_to_dm1105_dev(f);
-
-       if (dev->full_ts_users++ == 0)
-               dm1105_enable_irqs(dev);
-
-       return 0;
-}
-
-static int dm1105_stop_feed(struct dvb_demux_feed *f)
-{
-       struct dm1105_dev *dev = feed_to_dm1105_dev(f);
-
-       if (--dev->full_ts_users == 0)
-               dm1105_disable_irqs(dev);
-
-       return 0;
-}
-
-/* ir work handler */
-static void dm1105_emit_key(struct work_struct *work)
-{
-       struct infrared *ir = container_of(work, struct infrared, work);
-       u32 ircom = ir->ir_command;
-       u8 data;
-
-       if (ir_debug)
-               printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
-
-       data = (ircom >> 8) & 0x7f;
-
-       rc_keydown(ir->dev, data, 0);
-}
-
-/* work handler */
-static void dm1105_dmx_buffer(struct work_struct *work)
-{
-       struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work);
-       unsigned int nbpackets;
-       u32 oldwrp = dev->wrp;
-       u32 nextwrp = dev->nextwrp;
-
-       if (!((dev->ts_buf[oldwrp] == 0x47) &&
-                       (dev->ts_buf[oldwrp + 188] == 0x47) &&
-                       (dev->ts_buf[oldwrp + 188 * 2] == 0x47))) {
-               dev->PacketErrorCount++;
-               /* bad packet found */
-               if ((dev->PacketErrorCount >= 2) &&
-                               (dev->dmarst == 0)) {
-                       dm_writeb(DM1105_RST, 1);
-                       dev->wrp = 0;
-                       dev->PacketErrorCount = 0;
-                       dev->dmarst = 0;
-                       return;
-               }
-       }
-
-       if (nextwrp < oldwrp) {
-               memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp);
-               nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188;
-       } else
-               nbpackets = (nextwrp - oldwrp) / 188;
-
-       dev->wrp = nextwrp;
-       dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets);
-}
-
-static irqreturn_t dm1105_irq(int irq, void *dev_id)
-{
-       struct dm1105_dev *dev = dev_id;
-
-       /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
-       unsigned int intsts = dm_readb(DM1105_INTSTS);
-       dm_writeb(DM1105_INTSTS, intsts);
-
-       switch (intsts) {
-       case INTSTS_TSIRQ:
-       case (INTSTS_TSIRQ | INTSTS_IR):
-               dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR);
-               queue_work(dev->wq, &dev->work);
-               break;
-       case INTSTS_IR:
-               dev->ir.ir_command = dm_readl(DM1105_IRCODE);
-               schedule_work(&dev->ir.work);
-               break;
-       }
-
-       return IRQ_HANDLED;
-}
-
-int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
-{
-       struct rc_dev *dev;
-       int err = -ENOMEM;
-
-       dev = rc_allocate_device();
-       if (!dev)
-               return -ENOMEM;
-
-       snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
-               "pci-%s/ir0", pci_name(dm1105->pdev));
-
-       dev->driver_name = MODULE_NAME;
-       dev->map_name = RC_MAP_DM1105_NEC;
-       dev->driver_type = RC_DRIVER_SCANCODE;
-       dev->input_name = "DVB on-card IR receiver";
-       dev->input_phys = dm1105->ir.input_phys;
-       dev->input_id.bustype = BUS_PCI;
-       dev->input_id.version = 1;
-       if (dm1105->pdev->subsystem_vendor) {
-               dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
-               dev->input_id.product = dm1105->pdev->subsystem_device;
-       } else {
-               dev->input_id.vendor = dm1105->pdev->vendor;
-               dev->input_id.product = dm1105->pdev->device;
-       }
-       dev->dev.parent = &dm1105->pdev->dev;
-
-       INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
-
-       err = rc_register_device(dev);
-       if (err < 0) {
-               rc_free_device(dev);
-               return err;
-       }
-
-       dm1105->ir.dev = dev;
-       return 0;
-}
-
-void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
-{
-       rc_unregister_device(dm1105->ir.dev);
-}
-
-static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
-{
-       dm1105_disable_irqs(dev);
-
-       dm_writeb(DM1105_HOST_CTR, 0);
-
-       /*DATALEN 188,*/
-       dm_writeb(DM1105_DTALENTH, 188);
-       /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/
-       dm_writew(DM1105_TSCTR, 0xc10a);
-
-       /* map DMA and set address */
-       dm1105_dma_map(dev);
-       dm1105_set_dma_addr(dev);
-       /* big buffer */
-       dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES);
-       dm_writeb(DM1105_INTCNT, 47);
-
-       /* IR NEC mode enable */
-       dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK));
-       dm_writeb(DM1105_IRMODE, 0);
-       dm_writew(DM1105_SYSTEMCODE, 0);
-
-       return 0;
-}
-
-static void dm1105_hw_exit(struct dm1105_dev *dev)
-{
-       dm1105_disable_irqs(dev);
-
-       /* IR disable */
-       dm_writeb(DM1105_IRCTR, 0);
-       dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK);
-
-       dm1105_dma_unmap(dev);
-}
-
-static struct stv0299_config sharp_z0194a_config = {
-       .demod_address = 0x68,
-       .inittab = sharp_z0194a_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = sharp_z0194a_set_symbol_rate,
-};
-
-static struct stv0288_config earda_config = {
-       .demod_address = 0x68,
-       .min_delay_ms = 100,
-};
-
-static struct si21xx_config serit_config = {
-       .demod_address = 0x68,
-       .min_delay_ms = 100,
-
-};
-
-static struct cx24116_config serit_sp2633_config = {
-       .demod_address = 0x55,
-};
-
-static struct ds3000_config dvbworld_ds3000_config = {
-       .demod_address = 0x68,
-};
-
-static int __devinit frontend_init(struct dm1105_dev *dev)
-{
-       int ret;
-
-       switch (dev->boardnr) {
-       case DM1105_BOARD_UNBRANDED_I2C_ON_GPIO:
-               dm1105_gpio_enable(dev, GPIO15, 1);
-               dm1105_gpio_clear(dev, GPIO15);
-               msleep(100);
-               dm1105_gpio_set(dev, GPIO15);
-               msleep(200);
-               dev->fe = dvb_attach(
-                       stv0299_attach, &sharp_z0194a_config,
-                       &dev->i2c_bb_adap);
-               if (dev->fe) {
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-                       dvb_attach(dvb_pll_attach, dev->fe, 0x60,
-                                       &dev->i2c_bb_adap, DVB_PLL_OPERA1);
-                       break;
-               }
-
-               dev->fe = dvb_attach(
-                       stv0288_attach, &earda_config,
-                       &dev->i2c_bb_adap);
-               if (dev->fe) {
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-                       dvb_attach(stb6000_attach, dev->fe, 0x61,
-                                       &dev->i2c_bb_adap);
-                       break;
-               }
-
-               dev->fe = dvb_attach(
-                       si21xx_attach, &serit_config,
-                       &dev->i2c_bb_adap);
-               if (dev->fe)
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-               break;
-       case DM1105_BOARD_DVBWORLD_2004:
-               dev->fe = dvb_attach(
-                       cx24116_attach, &serit_sp2633_config,
-                       &dev->i2c_adap);
-               if (dev->fe) {
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-                       break;
-               }
-
-               dev->fe = dvb_attach(
-                       ds3000_attach, &dvbworld_ds3000_config,
-                       &dev->i2c_adap);
-               if (dev->fe)
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-
-               break;
-       case DM1105_BOARD_DVBWORLD_2002:
-       case DM1105_BOARD_AXESS_DM05:
-       default:
-               dev->fe = dvb_attach(
-                       stv0299_attach, &sharp_z0194a_config,
-                       &dev->i2c_adap);
-               if (dev->fe) {
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-                       dvb_attach(dvb_pll_attach, dev->fe, 0x60,
-                                       &dev->i2c_adap, DVB_PLL_OPERA1);
-                       break;
-               }
-
-               dev->fe = dvb_attach(
-                       stv0288_attach, &earda_config,
-                       &dev->i2c_adap);
-               if (dev->fe) {
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-                       dvb_attach(stb6000_attach, dev->fe, 0x61,
-                                       &dev->i2c_adap);
-                       break;
-               }
-
-               dev->fe = dvb_attach(
-                       si21xx_attach, &serit_config,
-                       &dev->i2c_adap);
-               if (dev->fe)
-                       dev->fe->ops.set_voltage = dm1105_set_voltage;
-
-       }
-
-       if (!dev->fe) {
-               dev_err(&dev->pdev->dev, "could not attach frontend\n");
-               return -ENODEV;
-       }
-
-       ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe);
-       if (ret < 0) {
-               if (dev->fe->ops.release)
-                       dev->fe->ops.release(dev->fe);
-               dev->fe = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac)
-{
-       static u8 command[1] = { 0x28 };
-
-       struct i2c_msg msg[] = {
-               {
-                       .addr = IIC_24C01_addr >> 1,
-                       .flags = 0,
-                       .buf = command,
-                       .len = 1
-               }, {
-                       .addr = IIC_24C01_addr >> 1,
-                       .flags = I2C_M_RD,
-                       .buf = mac,
-                       .len = 6
-               },
-       };
-
-       dm1105_i2c_xfer(&dev->i2c_adap, msg , 2);
-       dev_info(&dev->pdev->dev, "MAC %pM\n", mac);
-}
-
-static int __devinit dm1105_probe(struct pci_dev *pdev,
-                                 const struct pci_device_id *ent)
-{
-       struct dm1105_dev *dev;
-       struct dvb_adapter *dvb_adapter;
-       struct dvb_demux *dvbdemux;
-       struct dmx_demux *dmx;
-       int ret = -ENOMEM;
-       int i;
-
-       dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-
-       /* board config */
-       dev->nr = dm1105_devcount;
-       dev->boardnr = UNSET;
-       if (card[dev->nr] < ARRAY_SIZE(dm1105_boards))
-               dev->boardnr = card[dev->nr];
-       for (i = 0; UNSET == dev->boardnr &&
-                               i < ARRAY_SIZE(dm1105_subids); i++)
-               if (pdev->subsystem_vendor ==
-                       dm1105_subids[i].subvendor &&
-                               pdev->subsystem_device ==
-                                       dm1105_subids[i].subdevice)
-                       dev->boardnr = dm1105_subids[i].card;
-
-       if (UNSET == dev->boardnr) {
-               dev->boardnr = DM1105_BOARD_UNKNOWN;
-               dm1105_card_list(pdev);
-       }
-
-       dm1105_devcount++;
-       dev->pdev = pdev;
-       dev->buffer_size = 5 * DM1105_DMA_BYTES;
-       dev->PacketErrorCount = 0;
-       dev->dmarst = 0;
-
-       ret = pci_enable_device(pdev);
-       if (ret < 0)
-               goto err_kfree;
-
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       pci_set_master(pdev);
-
-       ret = pci_request_regions(pdev, DRIVER_NAME);
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
-       if (!dev->io_mem) {
-               ret = -EIO;
-               goto err_pci_release_regions;
-       }
-
-       spin_lock_init(&dev->lock);
-       pci_set_drvdata(pdev, dev);
-
-       ret = dm1105_hw_init(dev);
-       if (ret < 0)
-               goto err_pci_iounmap;
-
-       /* i2c */
-       i2c_set_adapdata(&dev->i2c_adap, dev);
-       strcpy(dev->i2c_adap.name, DRIVER_NAME);
-       dev->i2c_adap.owner = THIS_MODULE;
-       dev->i2c_adap.dev.parent = &pdev->dev;
-       dev->i2c_adap.algo = &dm1105_algo;
-       dev->i2c_adap.algo_data = dev;
-       ret = i2c_add_adapter(&dev->i2c_adap);
-
-       if (ret < 0)
-               goto err_dm1105_hw_exit;
-
-       i2c_set_adapdata(&dev->i2c_bb_adap, dev);
-       strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME);
-       dev->i2c_bb_adap.owner = THIS_MODULE;
-       dev->i2c_bb_adap.dev.parent = &pdev->dev;
-       dev->i2c_bb_adap.algo_data = &dev->i2c_bit;
-       dev->i2c_bit.data = dev;
-       dev->i2c_bit.setsda = dm1105_setsda;
-       dev->i2c_bit.setscl = dm1105_setscl;
-       dev->i2c_bit.getsda = dm1105_getsda;
-       dev->i2c_bit.getscl = dm1105_getscl;
-       dev->i2c_bit.udelay = 10;
-       dev->i2c_bit.timeout = 10;
-
-       /* Raise SCL and SDA */
-       dm1105_setsda(dev, 1);
-       dm1105_setscl(dev, 1);
-
-       ret = i2c_bit_add_bus(&dev->i2c_bb_adap);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       /* dvb */
-       ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,
-                                       THIS_MODULE, &pdev->dev, adapter_nr);
-       if (ret < 0)
-               goto err_i2c_del_adapters;
-
-       dvb_adapter = &dev->dvb_adapter;
-
-       dm1105_read_mac(dev, dvb_adapter->proposed_mac);
-
-       dvbdemux = &dev->demux;
-       dvbdemux->filternum = 256;
-       dvbdemux->feednum = 256;
-       dvbdemux->start_feed = dm1105_start_feed;
-       dvbdemux->stop_feed = dm1105_stop_feed;
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
-                       DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-       ret = dvb_dmx_init(dvbdemux);
-       if (ret < 0)
-               goto err_dvb_unregister_adapter;
-
-       dmx = &dvbdemux->dmx;
-       dev->dmxdev.filternum = 256;
-       dev->dmxdev.demux = dmx;
-       dev->dmxdev.capabilities = 0;
-
-       ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter);
-       if (ret < 0)
-               goto err_dvb_dmx_release;
-
-       dev->hw_frontend.source = DMX_FRONTEND_0;
-
-       ret = dmx->add_frontend(dmx, &dev->hw_frontend);
-       if (ret < 0)
-               goto err_dvb_dmxdev_release;
-
-       dev->mem_frontend.source = DMX_MEMORY_FE;
-
-       ret = dmx->add_frontend(dmx, &dev->mem_frontend);
-       if (ret < 0)
-               goto err_remove_hw_frontend;
-
-       ret = dmx->connect_frontend(dmx, &dev->hw_frontend);
-       if (ret < 0)
-               goto err_remove_mem_frontend;
-
-       ret = dvb_net_init(dvb_adapter, &dev->dvbnet, dmx);
-       if (ret < 0)
-               goto err_disconnect_frontend;
-
-       ret = frontend_init(dev);
-       if (ret < 0)
-               goto err_dvb_net;
-
-       dm1105_ir_init(dev);
-
-       INIT_WORK(&dev->work, dm1105_dmx_buffer);
-       sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
-       dev->wq = create_singlethread_workqueue(dev->wqn);
-       if (!dev->wq)
-               goto err_dvb_net;
-
-       ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,
-                                               DRIVER_NAME, dev);
-       if (ret < 0)
-               goto err_workqueue;
-
-       return 0;
-
-err_workqueue:
-       destroy_workqueue(dev->wq);
-err_dvb_net:
-       dvb_net_release(&dev->dvbnet);
-err_disconnect_frontend:
-       dmx->disconnect_frontend(dmx);
-err_remove_mem_frontend:
-       dmx->remove_frontend(dmx, &dev->mem_frontend);
-err_remove_hw_frontend:
-       dmx->remove_frontend(dmx, &dev->hw_frontend);
-err_dvb_dmxdev_release:
-       dvb_dmxdev_release(&dev->dmxdev);
-err_dvb_dmx_release:
-       dvb_dmx_release(dvbdemux);
-err_dvb_unregister_adapter:
-       dvb_unregister_adapter(dvb_adapter);
-err_i2c_del_adapters:
-       i2c_del_adapter(&dev->i2c_bb_adap);
-err_i2c_del_adapter:
-       i2c_del_adapter(&dev->i2c_adap);
-err_dm1105_hw_exit:
-       dm1105_hw_exit(dev);
-err_pci_iounmap:
-       pci_iounmap(pdev, dev->io_mem);
-err_pci_release_regions:
-       pci_release_regions(pdev);
-err_pci_disable_device:
-       pci_disable_device(pdev);
-err_kfree:
-       pci_set_drvdata(pdev, NULL);
-       kfree(dev);
-       return ret;
-}
-
-static void __devexit dm1105_remove(struct pci_dev *pdev)
-{
-       struct dm1105_dev *dev = pci_get_drvdata(pdev);
-       struct dvb_adapter *dvb_adapter = &dev->dvb_adapter;
-       struct dvb_demux *dvbdemux = &dev->demux;
-       struct dmx_demux *dmx = &dvbdemux->dmx;
-
-       dm1105_ir_exit(dev);
-       dmx->close(dmx);
-       dvb_net_release(&dev->dvbnet);
-       if (dev->fe)
-               dvb_unregister_frontend(dev->fe);
-
-       dmx->disconnect_frontend(dmx);
-       dmx->remove_frontend(dmx, &dev->mem_frontend);
-       dmx->remove_frontend(dmx, &dev->hw_frontend);
-       dvb_dmxdev_release(&dev->dmxdev);
-       dvb_dmx_release(dvbdemux);
-       dvb_unregister_adapter(dvb_adapter);
-       if (&dev->i2c_adap)
-               i2c_del_adapter(&dev->i2c_adap);
-
-       dm1105_hw_exit(dev);
-       synchronize_irq(pdev->irq);
-       free_irq(pdev->irq, dev);
-       pci_iounmap(pdev, dev->io_mem);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
-       dm1105_devcount--;
-       kfree(dev);
-}
-
-static struct pci_device_id dm1105_id_table[] __devinitdata = {
-       {
-               .vendor = PCI_VENDOR_ID_TRIGEM,
-               .device = PCI_DEVICE_ID_DM1105,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       }, {
-               .vendor = PCI_VENDOR_ID_AXESS,
-               .device = PCI_DEVICE_ID_DM05,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       }, {
-               /* empty */
-       },
-};
-
-MODULE_DEVICE_TABLE(pci, dm1105_id_table);
-
-static struct pci_driver dm1105_driver = {
-       .name = DRIVER_NAME,
-       .id_table = dm1105_id_table,
-       .probe = dm1105_probe,
-       .remove = __devexit_p(dm1105_remove),
-};
-
-static int __init dm1105_init(void)
-{
-       return pci_register_driver(&dm1105_driver);
-}
-
-static void __exit dm1105_exit(void)
-{
-       pci_unregister_driver(&dm1105_driver);
-}
-
-module_init(dm1105_init);
-module_exit(dm1105_exit);
-
-MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
-MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
deleted file mode 100644 (file)
index a13a505..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-config MANTIS_CORE
-       tristate "Mantis/Hopper PCI bridge based devices"
-       depends on PCI && I2C && INPUT && RC_CORE
-
-       help
-         Support for PCI cards based on the Mantis and Hopper PCi bridge.
-
-         Say Y if you own such a device and want to use it.
-
-config DVB_MANTIS
-       tristate "MANTIS based cards"
-       depends on MANTIS_CORE && DVB_CORE && PCI && I2C
-       select DVB_MB86A16 if !DVB_FE_CUSTOMISE
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
-       select DVB_TDA665x if !DVB_FE_CUSTOMISE
-       select DVB_TDA10021 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-       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.
-
-config DVB_HOPPER
-       tristate "HOPPER based cards"
-       depends on MANTIS_CORE && DVB_CORE && PCI && I2C
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select DVB_PLL
-       help
-         Support for PCI cards based on the Hopper  PCI bridge.
-         Say Y when you have a Hopper 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
deleted file mode 100644 (file)
index f715051..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-mantis_core-objs :=    mantis_ioc.o    \
-                       mantis_uart.o   \
-                       mantis_dma.o    \
-                       mantis_pci.o    \
-                       mantis_i2c.o    \
-                       mantis_dvb.o    \
-                       mantis_evm.o    \
-                       mantis_hif.o    \
-                       mantis_ca.o     \
-                       mantis_pcmcia.o \
-                       mantis_input.o
-
-mantis-objs    :=      mantis_cards.o  \
-                       mantis_vp1033.o \
-                       mantis_vp1034.o \
-                       mantis_vp1041.o \
-                       mantis_vp2033.o \
-                       mantis_vp2040.o \
-                       mantis_vp3030.o
-
-hopper-objs    :=      hopper_cards.o  \
-                       hopper_vp3028.o
-
-obj-$(CONFIG_MANTIS_CORE)      += mantis_core.o
-obj-$(CONFIG_DVB_MANTIS)       += mantis.o
-obj-$(CONFIG_DVB_HOPPER)       += hopper.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
deleted file mode 100644 (file)
index cc0251e..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-       Hopper PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "hopper_vp3028.h"
-#include "mantis_dma.h"
-#include "mantis_dvb.h"
-#include "mantis_uart.h"
-#include "mantis_ioc.h"
-#include "mantis_pci.h"
-#include "mantis_i2c.h"
-#include "mantis_reg.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
-
-#define DRIVER_NAME    "Hopper"
-
-static char *label[10] = {
-       "DMA",
-       "IRQ-0",
-       "IRQ-1",
-       "OCERR",
-       "PABRT",
-       "RIPRR",
-       "PPERR",
-       "FTRGT",
-       "RISCI",
-       "RACK"
-};
-
-static int devs;
-
-static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
-{
-       u32 stat = 0, mask = 0;
-       u32 rst_stat = 0, rst_mask = 0;
-
-       struct mantis_pci *mantis;
-       struct mantis_ca *ca;
-
-       mantis = (struct mantis_pci *) dev_id;
-       if (unlikely(mantis == NULL)) {
-               dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
-               return IRQ_NONE;
-       }
-       ca = mantis->mantis_ca;
-
-       stat = mmread(MANTIS_INT_STAT);
-       mask = mmread(MANTIS_INT_MASK);
-       if (!(stat & mask))
-               return IRQ_NONE;
-
-       rst_mask  = MANTIS_GPIF_WRACK  |
-                   MANTIS_GPIF_OTHERR |
-                   MANTIS_SBUF_WSTO   |
-                   MANTIS_GPIF_EXTIRQ;
-
-       rst_stat  = mmread(MANTIS_GPIF_STATUS);
-       rst_stat &= rst_mask;
-       mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
-       mantis->mantis_int_stat = stat;
-       mantis->mantis_int_mask = mask;
-       dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
-       if (stat & MANTIS_INT_RISCEN) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
-       }
-       if (stat & MANTIS_INT_IRQ0) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
-               mantis->gpif_status = rst_stat;
-               wake_up(&ca->hif_write_wq);
-               schedule_work(&ca->hif_evm_work);
-       }
-       if (stat & MANTIS_INT_IRQ1) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
-               schedule_work(&mantis->uart_work);
-       }
-       if (stat & MANTIS_INT_OCERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
-       }
-       if (stat & MANTIS_INT_PABORT) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
-       }
-       if (stat & MANTIS_INT_RIPERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
-       }
-       if (stat & MANTIS_INT_PPERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
-       }
-       if (stat & MANTIS_INT_FTRGT) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
-       }
-       if (stat & MANTIS_INT_RISCI) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
-               mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
-               tasklet_schedule(&mantis->tasklet);
-       }
-       if (stat & MANTIS_INT_I2CDONE) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
-               wake_up(&mantis->i2c_wq);
-       }
-       mmwrite(stat, MANTIS_INT_STAT);
-       stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
-                 MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
-                 MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
-                 MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
-                 MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
-                 MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1    |
-                 MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
-                 MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
-                 MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
-                 MANTIS_INT_RISCI);
-
-       if (stat)
-               dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
-
-       dprintk(MANTIS_DEBUG, 0, "\n");
-       return IRQ_HANDLED;
-}
-
-static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-       struct mantis_pci *mantis;
-       struct mantis_hwconfig *config;
-       int err = 0;
-
-       mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
-       if (mantis == NULL) {
-               printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
-               err = -ENOMEM;
-               goto fail0;
-       }
-
-       mantis->num             = devs;
-       mantis->verbose         = verbose;
-       mantis->pdev            = pdev;
-       config                  = (struct mantis_hwconfig *) pci_id->driver_data;
-       config->irq_handler     = &hopper_irq_handler;
-       mantis->hwconfig        = config;
-
-       err = mantis_pci_init(mantis);
-       if (err) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
-               goto fail1;
-       }
-
-       err = mantis_stream_control(mantis, STREAM_TO_HIF);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
-               goto fail1;
-       }
-
-       err = mantis_i2c_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
-               goto fail2;
-       }
-
-       err = mantis_get_mac(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
-               goto fail2;
-       }
-
-       err = mantis_dma_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
-               goto fail3;
-       }
-
-       err = mantis_dvb_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
-               goto fail4;
-       }
-       devs++;
-
-       return err;
-
-fail4:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
-       mantis_dma_exit(mantis);
-
-fail3:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
-       mantis_i2c_exit(mantis);
-
-fail2:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
-       mantis_pci_exit(mantis);
-
-fail1:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
-       kfree(mantis);
-
-fail0:
-       return err;
-}
-
-static void __devexit hopper_pci_remove(struct pci_dev *pdev)
-{
-       struct mantis_pci *mantis = pci_get_drvdata(pdev);
-
-       if (mantis) {
-               mantis_dvb_exit(mantis);
-               mantis_dma_exit(mantis);
-               mantis_i2c_exit(mantis);
-               mantis_pci_exit(mantis);
-               kfree(mantis);
-       }
-       return;
-
-}
-
-static struct pci_device_id hopper_pci_table[] = {
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
-       { }
-};
-
-MODULE_DEVICE_TABLE(pci, hopper_pci_table);
-
-static struct pci_driver hopper_pci_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = hopper_pci_table,
-       .probe          = hopper_pci_probe,
-       .remove         = hopper_pci_remove,
-};
-
-static int __devinit hopper_init(void)
-{
-       return pci_register_driver(&hopper_pci_driver);
-}
-
-static void __devexit hopper_exit(void)
-{
-       return pci_unregister_driver(&hopper_pci_driver);
-}
-
-module_init(hopper_init);
-module_exit(hopper_exit);
-
-MODULE_DESCRIPTION("HOPPER driver");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c
deleted file mode 100644 (file)
index 68a29f8..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-       Hopper VP-3028 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "zl10353.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "hopper_vp3028.h"
-
-struct zl10353_config hopper_vp3028_config = {
-       .demod_address  = 0x0f,
-};
-
-#define MANTIS_MODEL_NAME      "VP-3028"
-#define MANTIS_DEV_TYPE                "DVB-T"
-
-static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter     = &mantis->adapter;
-       struct mantis_hwconfig *config  = mantis->hwconfig;
-       int err = 0;
-
-       mantis_gpio_set_bits(mantis, config->reset, 0);
-       msleep(100);
-       err = mantis_frontend_power(mantis, POWER_ON);
-       msleep(100);
-       mantis_gpio_set_bits(mantis, config->reset, 1);
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               msleep(250);
-               dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
-               fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter);
-
-               if (!fe)
-                       return -1;
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-       dprintk(MANTIS_ERROR, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp3028_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_188,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp3028_frontend_init,
-       .power          = GPIF_A00,
-       .reset          = GPIF_A03,
-};
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.h b/drivers/media/dvb/mantis/hopper_vp3028.h
deleted file mode 100644 (file)
index 5723949..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Hopper VP-3028 driver
-
-       Copyright (C) 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_VP3028_H
-#define __MANTIS_VP3028_H
-
-#include "mantis_common.h"
-
-#define MANTIS_VP_3028_DVB_T   0x0028
-
-extern struct mantis_hwconfig vp3028_config;
-
-#endif /* __MANTIS_VP3028_H */
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c
deleted file mode 100644 (file)
index 3d70469..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_link.h"
-#include "mantis_hif.h"
-#include "mantis_reg.h"
-
-#include "mantis_ca.h"
-
-static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return mantis_hif_read_mem(ca, addr);
-}
-
-static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return mantis_hif_write_mem(ca, addr, data);
-}
-
-static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return mantis_hif_read_iom(ca, addr);
-}
-
-static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return mantis_hif_write_iom(ca, addr, data);
-}
-
-static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
-       udelay(500); /* Wait.. */
-       mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
-       udelay(500);
-       mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
-       msleep(1000);
-       dvb_ca_en50221_camready_irq(&ca->en50221, 0);
-
-       return 0;
-}
-
-static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
-
-       return 0;
-}
-
-static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
-/*     mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */
-
-       return 0;
-}
-
-static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
-{
-       struct mantis_ca *ca = en50221->data;
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
-
-       if (ca->slot_state == MODULE_INSERTED) {
-               dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
-               return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
-       } else {
-               dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
-       }
-
-       return 0;
-}
-
-int mantis_ca_init(struct mantis_pci *mantis)
-{
-       struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter;
-       struct mantis_ca *ca;
-       int ca_flags = 0, result;
-
-       dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
-       ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
-       if (!ca) {
-               dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
-               result = -ENOMEM;
-               goto err;
-       }
-
-       ca->ca_priv             = mantis;
-       mantis->mantis_ca       = ca;
-       ca_flags                = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
-       /* register CA interface */
-       ca->en50221.owner               = THIS_MODULE;
-       ca->en50221.read_attribute_mem  = mantis_ca_read_attr_mem;
-       ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem;
-       ca->en50221.read_cam_control    = mantis_ca_read_cam_ctl;
-       ca->en50221.write_cam_control   = mantis_ca_write_cam_ctl;
-       ca->en50221.slot_reset          = mantis_ca_slot_reset;
-       ca->en50221.slot_shutdown       = mantis_ca_slot_shutdown;
-       ca->en50221.slot_ts_enable      = mantis_ts_control;
-       ca->en50221.poll_slot_status    = mantis_slot_status;
-       ca->en50221.data                = ca;
-
-       mutex_init(&ca->ca_lock);
-
-       init_waitqueue_head(&ca->hif_data_wq);
-       init_waitqueue_head(&ca->hif_opdone_wq);
-       init_waitqueue_head(&ca->hif_write_wq);
-
-       dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
-       result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
-       if (result != 0) {
-               dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
-               goto err;
-       }
-       dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
-       mantis_evmgr_init(ca);
-       return 0;
-err:
-       kfree(ca);
-       return result;
-}
-EXPORT_SYMBOL_GPL(mantis_ca_init);
-
-void mantis_ca_exit(struct mantis_pci *mantis)
-{
-       struct mantis_ca *ca = mantis->mantis_ca;
-
-       dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
-
-       mantis_evmgr_exit(ca);
-       dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
-       if (ca)
-               dvb_ca_en50221_release(&ca->en50221);
-
-       kfree(ca);
-}
-EXPORT_SYMBOL_GPL(mantis_ca_exit);
diff --git a/drivers/media/dvb/mantis/mantis_ca.h b/drivers/media/dvb/mantis/mantis_ca.h
deleted file mode 100644 (file)
index dc63e55..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_CA_H
-#define __MANTIS_CA_H
-
-extern int mantis_ca_init(struct mantis_pci *mantis);
-extern void mantis_ca_exit(struct mantis_pci *mantis);
-
-#endif /* __MANTIS_CA_H */
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
deleted file mode 100644 (file)
index 0207d1f..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-
-#include "mantis_vp1033.h"
-#include "mantis_vp1034.h"
-#include "mantis_vp1041.h"
-#include "mantis_vp2033.h"
-#include "mantis_vp2040.h"
-#include "mantis_vp3030.h"
-
-#include "mantis_dma.h"
-#include "mantis_ca.h"
-#include "mantis_dvb.h"
-#include "mantis_uart.h"
-#include "mantis_ioc.h"
-#include "mantis_pci.h"
-#include "mantis_i2c.h"
-#include "mantis_reg.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
-
-static int devs;
-
-#define DRIVER_NAME    "Mantis"
-
-static char *label[10] = {
-       "DMA",
-       "IRQ-0",
-       "IRQ-1",
-       "OCERR",
-       "PABRT",
-       "RIPRR",
-       "PPERR",
-       "FTRGT",
-       "RISCI",
-       "RACK"
-};
-
-static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
-{
-       u32 stat = 0, mask = 0;
-       u32 rst_stat = 0, rst_mask = 0;
-
-       struct mantis_pci *mantis;
-       struct mantis_ca *ca;
-
-       mantis = (struct mantis_pci *) dev_id;
-       if (unlikely(mantis == NULL)) {
-               dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
-               return IRQ_NONE;
-       }
-       ca = mantis->mantis_ca;
-
-       stat = mmread(MANTIS_INT_STAT);
-       mask = mmread(MANTIS_INT_MASK);
-       if (!(stat & mask))
-               return IRQ_NONE;
-
-       rst_mask  = MANTIS_GPIF_WRACK  |
-                   MANTIS_GPIF_OTHERR |
-                   MANTIS_SBUF_WSTO   |
-                   MANTIS_GPIF_EXTIRQ;
-
-       rst_stat  = mmread(MANTIS_GPIF_STATUS);
-       rst_stat &= rst_mask;
-       mmwrite(rst_stat, MANTIS_GPIF_STATUS);
-
-       mantis->mantis_int_stat = stat;
-       mantis->mantis_int_mask = mask;
-       dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
-       if (stat & MANTIS_INT_RISCEN) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
-       }
-       if (stat & MANTIS_INT_IRQ0) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
-               mantis->gpif_status = rst_stat;
-               wake_up(&ca->hif_write_wq);
-               schedule_work(&ca->hif_evm_work);
-       }
-       if (stat & MANTIS_INT_IRQ1) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
-               schedule_work(&mantis->uart_work);
-       }
-       if (stat & MANTIS_INT_OCERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
-       }
-       if (stat & MANTIS_INT_PABORT) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
-       }
-       if (stat & MANTIS_INT_RIPERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
-       }
-       if (stat & MANTIS_INT_PPERR) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
-       }
-       if (stat & MANTIS_INT_FTRGT) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
-       }
-       if (stat & MANTIS_INT_RISCI) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
-               mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
-               tasklet_schedule(&mantis->tasklet);
-       }
-       if (stat & MANTIS_INT_I2CDONE) {
-               dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
-               wake_up(&mantis->i2c_wq);
-       }
-       mmwrite(stat, MANTIS_INT_STAT);
-       stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
-                 MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
-                 MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
-                 MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
-                 MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
-                 MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1    |
-                 MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
-                 MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
-                 MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
-                 MANTIS_INT_RISCI);
-
-       if (stat)
-               dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
-
-       dprintk(MANTIS_DEBUG, 0, "\n");
-       return IRQ_HANDLED;
-}
-
-static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-       struct mantis_pci *mantis;
-       struct mantis_hwconfig *config;
-       int err = 0;
-
-       mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
-       if (mantis == NULL) {
-               printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
-               err = -ENOMEM;
-               goto fail0;
-       }
-
-       mantis->num             = devs;
-       mantis->verbose         = verbose;
-       mantis->pdev            = pdev;
-       config                  = (struct mantis_hwconfig *) pci_id->driver_data;
-       config->irq_handler     = &mantis_irq_handler;
-       mantis->hwconfig        = config;
-
-       err = mantis_pci_init(mantis);
-       if (err) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
-               goto fail1;
-       }
-
-       err = mantis_stream_control(mantis, STREAM_TO_HIF);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
-               goto fail1;
-       }
-
-       err = mantis_i2c_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
-               goto fail2;
-       }
-
-       err = mantis_get_mac(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
-               goto fail2;
-       }
-
-       err = mantis_dma_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
-               goto fail3;
-       }
-
-       err = mantis_dvb_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
-               goto fail4;
-       }
-       err = mantis_uart_init(mantis);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err);
-               goto fail6;
-       }
-
-       devs++;
-
-       return err;
-
-
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
-       mantis_uart_exit(mantis);
-
-fail6:
-fail4:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
-       mantis_dma_exit(mantis);
-
-fail3:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
-       mantis_i2c_exit(mantis);
-
-fail2:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
-       mantis_pci_exit(mantis);
-
-fail1:
-       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
-       kfree(mantis);
-
-fail0:
-       return err;
-}
-
-static void __devexit mantis_pci_remove(struct pci_dev *pdev)
-{
-       struct mantis_pci *mantis = pci_get_drvdata(pdev);
-
-       if (mantis) {
-
-               mantis_uart_exit(mantis);
-               mantis_dvb_exit(mantis);
-               mantis_dma_exit(mantis);
-               mantis_i2c_exit(mantis);
-               mantis_pci_exit(mantis);
-               kfree(mantis);
-       }
-       return;
-}
-
-static struct pci_device_id mantis_pci_table[] = {
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config),
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config),
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config),
-       MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config),
-       MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config),
-       MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config),
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config),
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config),
-       MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config),
-       MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config),
-       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config),
-       { }
-};
-
-MODULE_DEVICE_TABLE(pci, mantis_pci_table);
-
-static struct pci_driver mantis_pci_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = mantis_pci_table,
-       .probe          = mantis_pci_probe,
-       .remove         = mantis_pci_remove,
-};
-
-static int __devinit mantis_init(void)
-{
-       return pci_register_driver(&mantis_pci_driver);
-}
-
-static void __devexit mantis_exit(void)
-{
-       return pci_unregister_driver(&mantis_pci_driver);
-}
-
-module_init(mantis_init);
-module_exit(mantis_exit);
-
-MODULE_DESCRIPTION("MANTIS driver");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
deleted file mode 100644 (file)
index f2410cf..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#include "mantis_uart.h"
-
-#include "mantis_link.h"
-
-#define MANTIS_ERROR           0
-#define MANTIS_NOTICE          1
-#define MANTIS_INFO            2
-#define MANTIS_DEBUG           3
-#define MANTIS_TMG             9
-
-#define dprintk(y, z, format, arg...) do {                                                             \
-       if (z) {                                                                                        \
-               if      ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y))                     \
-                       printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);      \
-               else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y))                    \
-                       printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);   \
-               else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y))                      \
-                       printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);     \
-               else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y))                     \
-                       printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);    \
-               else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y))                       \
-                       printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);    \
-       } else {                                                                                        \
-               if (mantis->verbose > 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->mmio + (addr)))
-#define mmread(addr)           mread(mantis->mmio + (addr))
-
-#define MANTIS_TS_188          0
-#define MANTIS_TS_204          1
-
-#define TWINHAN_TECHNOLOGIES   0x1822
-#define MANTIS                 0x4e35
-
-#define TECHNISAT              0x1ae4
-#define TERRATEC               0x153b
-
-#define MAKE_ENTRY(__subven, __subdev, __configptr) {                  \
-               .vendor         = TWINHAN_TECHNOLOGIES,                 \
-               .device         = MANTIS,                               \
-               .subvendor      = (__subven),                           \
-               .subdevice      = (__subdev),                           \
-               .driver_data    = (unsigned long) (__configptr)         \
-}
-
-enum mantis_i2c_mode {
-       MANTIS_PAGE_MODE = 0,
-       MANTIS_BYTE_MODE,
-};
-
-struct mantis_pci;
-
-struct mantis_hwconfig {
-       char                    *model_name;
-       char                    *dev_type;
-       u32                     ts_size;
-
-       enum mantis_baud        baud_rate;
-       enum mantis_parity      parity;
-       u32                     bytes;
-
-       irqreturn_t (*irq_handler)(int irq, void *dev_id);
-       int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe);
-
-       u8                      power;
-       u8                      reset;
-
-       enum mantis_i2c_mode    i2c_mode;
-};
-
-struct mantis_pci {
-       unsigned int            verbose;
-
-       /*      PCI stuff               */
-       u16                     vendor_id;
-       u16                     device_id;
-       u16                     subsystem_vendor;
-       u16                     subsystem_device;
-
-       u8                      latency;
-
-       struct pci_dev          *pdev;
-
-       unsigned long           mantis_addr;
-       void __iomem            *mmio;
-
-       u8                      irq;
-       u8                      revision;
-
-       unsigned int            num;
-
-       /*      RISC Core               */
-       u32                     busy_block;
-       u32                     last_block;
-       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;
-       struct mutex            i2c_lock;
-
-       /*      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_hwconfig  *hwconfig;
-
-       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             */
-       u32                     gpio_status;
-
-       u32                     gpif_status;
-
-       struct mantis_ca        *mantis_ca;
-
-       wait_queue_head_t       uart_wq;
-       struct work_struct      uart_work;
-       spinlock_t              uart_lock;
-
-       struct rc_dev           *rc;
-       char                    input_name[80];
-       char                    input_phys[80];
-};
-
-#define MANTIS_HIF_STATUS      (mantis->gpio_status)
-
-#endif /* __MANTIS_COMMON_H */
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c
deleted file mode 100644 (file)
index 684d906..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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"
-#include "mantis_vp1033.h"
-#include "mantis_vp1034.h"
-#include "mantis_vp1041.h"
-#include "mantis_vp2033.h"
-#include "mantis_vp2040.h"
-#include "mantis_vp3030.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
-               },
-       };
-
-       err = i2c_transfer(&mantis->adapter, msg, 2);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_ERROR, 1,
-                       "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
-                       err, data[0], data[1]);
-
-               return err;
-       }
-
-       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
-       };
-
-       err = i2c_transfer(&mantis->adapter, &msg, 1);
-       if (err < 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_mac_address(struct mantis_pci *mantis)
-{
-       int err;
-
-       mantis->mac_address[0] = 0x08;
-       err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
-
-               return err;
-       }
-       dprintk(verbose, MANTIS_ERROR, 0,
-               "    MAC Address=[%pM]\n", mantis->mac_address);
-
-       return 0;
-}
-
-#define MANTIS_MODEL_UNKNOWN   "UNKNOWN"
-#define MANTIS_DEV_UNKNOWN     "UNKNOWN"
-
-struct mantis_hwconfig unknown_device = {
-       .model_name     = MANTIS_MODEL_UNKNOWN,
-       .dev_type       = MANTIS_DEV_UNKNOWN,
-};
-
-static void mantis_load_config(struct mantis_pci *mantis)
-{
-       switch (mantis->subsystem_device) {
-       case MANTIS_VP_1033_DVB_S:      /* VP-1033 */
-               mantis->hwconfig = &vp1033_mantis_config;
-               break;
-       case MANTIS_VP_1034_DVB_S:      /* VP-1034 */
-               mantis->hwconfig = &vp1034_mantis_config;
-               break;
-       case MANTIS_VP_1041_DVB_S2:     /* VP-1041 */
-       case TECHNISAT_SKYSTAR_HD2:
-               mantis->hwconfig = &vp1041_mantis_config;
-               break;
-       case MANTIS_VP_2033_DVB_C:      /* VP-2033 */
-               mantis->hwconfig = &vp2033_mantis_config;
-               break;
-       case MANTIS_VP_2040_DVB_C:      /* VP-2040 */
-       case CINERGY_C: /* VP-2040 clone */
-       case TECHNISAT_CABLESTAR_HD2:
-               mantis->hwconfig = &vp2040_mantis_config;
-               break;
-       case MANTIS_VP_3030_DVB_T:      /* VP-3030 */
-               mantis->hwconfig = &vp3030_mantis_config;
-               break;
-       default:
-               mantis->hwconfig = &unknown_device;
-               break;
-       }
-}
-
-int mantis_core_init(struct mantis_pci *mantis)
-{
-       int err = 0;
-
-       mantis_load_config(mantis);
-       dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
-               mantis->hwconfig->model_name, mantis->hwconfig->dev_type,
-               mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));
-       dprintk(verbose, MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
-               mantis->revision,
-               mantis->subsystem_vendor, mantis->subsystem_device);
-       dprintk(verbose, MANTIS_ERROR, 0,
-               "irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
-               mantis->pdev->irq, mantis->latency,
-               mantis->mantis_addr, mantis->mantis_mmio);
-
-       err = mantis_i2c_init(mantis);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
-               return err;
-       }
-       err = get_mac_address(mantis);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
-               return err;
-       }
-       err = mantis_dma_init(mantis);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
-               return err;
-       }
-       err = mantis_dvb_init(mantis);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
-               return err;
-       }
-       err = mantis_uart_init(mantis);
-       if (err < 0) {
-               dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART 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");
-
-       mantis_uart_exit(mantis);
-       dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");
-
-       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;
-}
-
-/* Turn the given bit on or off. */
-void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
-{
-       u32 cur;
-
-       cur = mmread(MANTIS_GPIF_ADDR);
-       if (value)
-               mantis->gpio_status = cur | (1 << bitpos);
-       else
-               mantis->gpio_status = cur & (~(1 << bitpos));
-
-       mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
-       mmwrite(0x00, MANTIS_GPIF_DOUT);
-       udelay(100);
-}
-
-/* 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
deleted file mode 100644 (file)
index 833ee42..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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);
-
-#endif /* __MANTIS_CORE_H */
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
deleted file mode 100644 (file)
index 566c407..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <asm/page.h>
-#include <linux/vmalloc.h>
-#include <linux/pci.h>
-
-#include <asm/irq.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_dma.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(risc_pos)           (risc_pos = 0)
-#define RISC_INSTR(risc_pos, opcode)   (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode))
-
-#define MANTIS_BUF_SIZE                (64 * 1024)
-#define MANTIS_BLOCK_BYTES      (MANTIS_BUF_SIZE / 4)
-#define MANTIS_DMA_TR_BYTES     (2 * 1024) /* upper limit: 4095 bytes. */
-#define MANTIS_BLOCK_COUNT     (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
-
-#define MANTIS_DMA_TR_UNITS     (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
-/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */
-#define MANTIS_RISC_SIZE       PAGE_SIZE /* RISC program must fit here. */
-
-int mantis_dma_exit(struct mantis_pci *mantis)
-{
-       if (mantis->buf_cpu) {
-               dprintk(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(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;
-}
-EXPORT_SYMBOL_GPL(mantis_dma_exit);
-
-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(MANTIS_ERROR, 1,
-                               "DMA buffer allocation failed");
-
-                       goto err;
-               }
-               dprintk(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(MANTIS_ERROR, 1,
-                               "RISC program allocation failed");
-
-                       mantis_dma_exit(mantis);
-
-                       goto err;
-               }
-               dprintk(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(MANTIS_ERROR, 1, "Out of memory (?) .....");
-       return -ENOMEM;
-}
-
-int mantis_dma_init(struct mantis_pci *mantis)
-{
-       int err = 0;
-
-       dprintk(MANTIS_DEBUG, 1, "Mantis DMA init");
-       if (mantis_alloc_buffers(mantis) < 0) {
-               dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
-
-               /* Stop RISC Engine */
-               mmwrite(0, MANTIS_DMA_CTL);
-
-               goto err;
-       }
-
-       return 0;
-err:
-       return err;
-}
-EXPORT_SYMBOL_GPL(mantis_dma_init);
-
-static inline void mantis_risc_program(struct mantis_pci *mantis)
-{
-       u32 buf_pos = 0;
-       u32 line, step;
-       u32 risc_pos;
-
-       dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
-       RISC_FLUSH(risc_pos);
-
-       dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u",
-               MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES);
-
-       for (line = 0; line < MANTIS_BLOCK_COUNT; line++) {
-               for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) {
-                       dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step);
-                       if (step == 0) {
-                               RISC_INSTR(risc_pos, RISC_WRITE |
-                                          RISC_IRQ     |
-                                          RISC_STATUS(line) |
-                                          MANTIS_DMA_TR_BYTES);
-                       } else {
-                               RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES);
-                       }
-                       RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos);
-                       buf_pos += MANTIS_DMA_TR_BYTES;
-                 }
-       }
-       RISC_INSTR(risc_pos, RISC_JUMP);
-       RISC_INSTR(risc_pos, mantis->risc_dma);
-}
-
-void mantis_dma_start(struct mantis_pci *mantis)
-{
-       dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine");
-
-       mantis_risc_program(mantis);
-       mmwrite(mantis->risc_dma, MANTIS_RISC_START);
-       mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
-
-       mmwrite(0, MANTIS_DMA_CTL);
-       mantis->last_block = mantis->busy_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)
-{
-       dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
-
-       mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR);
-
-       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;
-       struct mantis_hwconfig *config = mantis->hwconfig;
-
-       while (mantis->last_block != mantis->busy_block) {
-               dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
-                       mantis->last_block, mantis->busy_block);
-
-               (config->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_dma.h b/drivers/media/dvb/mantis/mantis_dma.h
deleted file mode 100644 (file)
index 6be00fa..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_DMA_H
-#define __MANTIS_DMA_H
-
-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 void mantis_dma_xfer(unsigned long data);
-
-#endif /* __MANTIS_DMA_H */
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
deleted file mode 100644 (file)
index 5d15c6b..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
-       Mantis PCI bridge driver
-       Copyright (C) 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/kernel.h>
-#include <linux/bitops.h>
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_dma.h"
-#include "mantis_ca.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
-{
-       struct mantis_hwconfig *config = mantis->hwconfig;
-
-       switch (power) {
-       case POWER_ON:
-               dprintk(MANTIS_DEBUG, 1, "Power ON");
-               mantis_gpio_set_bits(mantis, config->power, POWER_ON);
-               msleep(100);
-               mantis_gpio_set_bits(mantis, config->power, POWER_ON);
-               msleep(100);
-               break;
-
-       case POWER_OFF:
-               dprintk(MANTIS_DEBUG, 1, "Power OFF");
-               mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
-               msleep(100);
-               break;
-
-       default:
-               dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
-               return -1;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_frontend_power);
-
-void mantis_frontend_soft_reset(struct mantis_pci *mantis)
-{
-       struct mantis_hwconfig *config = mantis->hwconfig;
-
-       dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
-       mantis_gpio_set_bits(mantis, config->reset, 0);
-       msleep(100);
-       mantis_gpio_set_bits(mantis, config->reset, 0);
-       msleep(100);
-       mantis_gpio_set_bits(mantis, config->reset, 1);
-       msleep(100);
-       mantis_gpio_set_bits(mantis, config->reset, 1);
-       msleep(100);
-
-       return;
-}
-EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
-
-static int mantis_frontend_shutdown(struct mantis_pci *mantis)
-{
-       int err;
-
-       mantis_frontend_soft_reset(mantis);
-       err = mantis_frontend_power(mantis, POWER_OFF);
-       if (err != 0) {
-               dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
-               return 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(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
-       if (!dvbdmx->dmx.frontend) {
-               dprintk(MANTIS_DEBUG, 1, "no frontend ?");
-               return -EINVAL;
-       }
-
-       mantis->feeds++;
-       dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds);
-
-       if (mantis->feeds == 1)  {
-               dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
-               mantis_dma_start(mantis);
-               tasklet_enable(&mantis->tasklet);
-       }
-
-       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(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
-       if (!dvbdmx->dmx.frontend) {
-               dprintk(MANTIS_DEBUG, 1, "no frontend ?");
-               return -EINVAL;
-       }
-
-       mantis->feeds--;
-       if (mantis->feeds == 0) {
-               dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
-               tasklet_disable(&mantis->tasklet);
-               mantis_dma_stop(mantis);
-       }
-
-       return 0;
-}
-
-int __devinit mantis_dvb_init(struct mantis_pci *mantis)
-{
-       struct mantis_hwconfig *config = mantis->hwconfig;
-       int result = -1;
-
-       dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
-
-       result = dvb_register_adapter(&mantis->dvb_adapter,
-                                     "Mantis DVB adapter",
-                                     THIS_MODULE,
-                                     &mantis->pdev->dev,
-                                     adapter_nr);
-
-       if (result < 0) {
-
-               dprintk(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;
-
-       dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
-       result = dvb_dmx_init(&mantis->demux);
-       if (result < 0) {
-               dprintk(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(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
-
-       result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
-       if (result < 0) {
-
-               dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
-               goto err1;
-       }
-
-       mantis->fe_hw.source            = DMX_FRONTEND_0;
-       result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
-       if (result < 0) {
-
-               dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
-               goto err2;
-       }
-
-       mantis->fe_mem.source           = DMX_MEMORY_FE;
-       result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
-       if (result < 0) {
-               dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
-               goto err3;
-       }
-
-       result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
-       if (result < 0) {
-               dprintk(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);
-       tasklet_disable(&mantis->tasklet);
-       if (mantis->hwconfig) {
-               result = config->frontend_init(mantis, mantis->fe);
-               if (result < 0) {
-                       dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
-                       goto err5;
-               } else {
-                       if (mantis->fe == NULL) {
-                               dprintk(MANTIS_ERROR, 1, "FE <NULL>");
-                               goto err5;
-                       }
-
-                       if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
-                               dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
-
-                               if (mantis->fe->ops.release)
-                                       mantis->fe->ops.release(mantis->fe);
-
-                               mantis->fe = NULL;
-                               goto err5;
-                       }
-               }
-       }
-
-       return 0;
-
-       /* Error conditions ..  */
-err5:
-       tasklet_kill(&mantis->tasklet);
-       dvb_net_release(&mantis->dvbnet);
-       if (mantis->fe) {
-               dvb_unregister_frontend(mantis->fe);
-               dvb_frontend_detach(mantis->fe);
-       }
-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;
-}
-EXPORT_SYMBOL_GPL(mantis_dvb_init);
-
-int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
-{
-       int err;
-
-       if (mantis->fe) {
-               /* mantis_ca_exit(mantis); */
-               err = mantis_frontend_shutdown(mantis);
-               if (err != 0)
-                       dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
-               dvb_unregister_frontend(mantis->fe);
-               dvb_frontend_detach(mantis->fe);
-       }
-
-       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);
-
-       dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
-       dvb_unregister_adapter(&mantis->dvb_adapter);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_dvb_exit);
diff --git a/drivers/media/dvb/mantis/mantis_dvb.h b/drivers/media/dvb/mantis/mantis_dvb.h
deleted file mode 100644 (file)
index 464199d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_DVB_H
-#define __MANTIS_DVB_H
-
-enum mantis_power {
-       POWER_OFF       = 0,
-       POWER_ON        = 1
-};
-
-extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power);
-extern void mantis_frontend_soft_reset(struct mantis_pci *mantis);
-
-extern int mantis_dvb_init(struct mantis_pci *mantis);
-extern int mantis_dvb_exit(struct mantis_pci *mantis);
-
-#endif /* __MANTIS_DVB_H */
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c
deleted file mode 100644 (file)
index 71ce528..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_link.h"
-#include "mantis_hif.h"
-#include "mantis_reg.h"
-
-static void mantis_hifevm_work(struct work_struct *work)
-{
-       struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       u32 gpif_stat;
-
-       gpif_stat = mmread(MANTIS_GPIF_STATUS);
-
-       if (gpif_stat & MANTIS_GPIF_DETSTAT) {
-               if (gpif_stat & MANTIS_CARD_PLUGIN) {
-                       dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num);
-                       mmwrite(0xdada0000, MANTIS_CARD_RESET);
-                       mantis_event_cam_plugin(ca);
-                       dvb_ca_en50221_camchange_irq(&ca->en50221,
-                                                    0,
-                                                    DVB_CA_EN50221_CAMCHANGE_INSERTED);
-               }
-       } else {
-               if (gpif_stat & MANTIS_CARD_PLUGOUT) {
-                       dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num);
-                       mmwrite(0xdada0000, MANTIS_CARD_RESET);
-                       mantis_event_cam_unplug(ca);
-                       dvb_ca_en50221_camchange_irq(&ca->en50221,
-                                                    0,
-                                                    DVB_CA_EN50221_CAMCHANGE_REMOVED);
-               }
-       }
-
-       if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num);
-
-       if (mantis->gpif_status & MANTIS_SBUF_WSTO)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num);
-
-       if (mantis->gpif_status & MANTIS_GPIF_OTHERR)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num);
-
-       if (gpif_stat & MANTIS_SBUF_OVFLW)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num);
-
-       if (gpif_stat & MANTIS_GPIF_BRRDY)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num);
-
-       if (gpif_stat & MANTIS_GPIF_INTSTAT)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num);
-
-       if (gpif_stat & MANTIS_SBUF_EMPTY)
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
-
-       if (gpif_stat & MANTIS_SBUF_OPDONE) {
-               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
-               ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
-               ca->hif_event = MANTIS_SBUF_OPDONE;
-               wake_up(&ca->hif_opdone_wq);
-       }
-}
-
-int mantis_evmgr_init(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager");
-       INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work);
-       mantis_pcmcia_init(ca);
-       schedule_work(&ca->hif_evm_work);
-       mantis_hif_init(ca);
-       return 0;
-}
-
-void mantis_evmgr_exit(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
-       flush_work_sync(&ca->hif_evm_work);
-       mantis_hif_exit(ca);
-       mantis_pcmcia_exit(ca);
-}
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c
deleted file mode 100644 (file)
index 10c68df..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-
-#include "mantis_hif.h"
-#include "mantis_link.h" /* temporary due to physical layer stuff */
-
-#include "mantis_reg.h"
-
-
-static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       int rc = 0;
-
-       if (wait_event_timeout(ca->hif_opdone_wq,
-                              ca->hif_event & MANTIS_SBUF_OPDONE,
-                              msecs_to_jiffies(500)) == -ERESTARTSYS) {
-
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
-               rc = -EREMOTEIO;
-       }
-       dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
-       ca->hif_event &= ~MANTIS_SBUF_OPDONE;
-       return rc;
-}
-
-static int mantis_hif_write_wait(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 opdone = 0, timeout = 0;
-       int rc = 0;
-
-       if (wait_event_timeout(ca->hif_write_wq,
-                              mantis->gpif_status & MANTIS_GPIF_WRACK,
-                              msecs_to_jiffies(500)) == -ERESTARTSYS) {
-
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
-               rc = -EREMOTEIO;
-       }
-       dprintk(MANTIS_DEBUG, 1, "Write Acknowledged");
-       mantis->gpif_status &= ~MANTIS_GPIF_WRACK;
-       while (!opdone) {
-               opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE);
-               udelay(500);
-               timeout++;
-               if (timeout > 100) {
-                       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num);
-                       rc = -ETIMEDOUT;
-                       break;
-               }
-       }
-       dprintk(MANTIS_DEBUG, 1, "HIF Write success");
-       return rc;
-}
-
-
-int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 hif_addr = 0, data, count = 4;
-
-       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num);
-       mutex_lock(&ca->ca_lock);
-       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
-       hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
-       hif_addr |=  MANTIS_HIF_STATUS;
-       hif_addr |=  addr;
-
-       mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
-       mmwrite(count, MANTIS_GPIF_BRBYTES);
-       udelay(20);
-       mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
-
-       if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num);
-               mutex_unlock(&ca->ca_lock);
-               return -EREMOTEIO;
-       }
-       data = mmread(MANTIS_GPIF_DIN);
-       mutex_unlock(&ca->ca_lock);
-       dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data);
-       return (data >> 24) & 0xff;
-}
-
-int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
-{
-       struct mantis_slot *slot = ca->slot;
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 hif_addr = 0;
-
-       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
-       mutex_lock(&ca->ca_lock);
-       hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
-       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
-       hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
-       hif_addr |=  MANTIS_HIF_STATUS;
-       hif_addr |=  addr;
-
-       mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */
-       mmwrite(hif_addr, MANTIS_GPIF_ADDR);
-       mmwrite(data, MANTIS_GPIF_DOUT);
-
-       if (mantis_hif_write_wait(ca) != 0) {
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
-               mutex_unlock(&ca->ca_lock);
-               return -EREMOTEIO;
-       }
-       dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr);
-       mutex_unlock(&ca->ca_lock);
-
-       return 0;
-}
-
-int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 data, hif_addr = 0;
-
-       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num);
-       mutex_lock(&ca->ca_lock);
-       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
-       hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
-       hif_addr |=  MANTIS_HIF_STATUS;
-       hif_addr |=  addr;
-
-       mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
-       mmwrite(1, MANTIS_GPIF_BRBYTES);
-       udelay(20);
-       mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
-
-       if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
-               mutex_unlock(&ca->ca_lock);
-               return -EREMOTEIO;
-       }
-       data = mmread(MANTIS_GPIF_DIN);
-       dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data);
-       udelay(50);
-       mutex_unlock(&ca->ca_lock);
-
-       return (u8) data;
-}
-
-int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 hif_addr = 0;
-
-       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
-       mutex_lock(&ca->ca_lock);
-       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
-       hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
-       hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
-       hif_addr |=  MANTIS_HIF_STATUS;
-       hif_addr |=  addr;
-
-       mmwrite(hif_addr, MANTIS_GPIF_ADDR);
-       mmwrite(data, MANTIS_GPIF_DOUT);
-
-       if (mantis_hif_write_wait(ca) != 0) {
-               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
-               mutex_unlock(&ca->ca_lock);
-               return -EREMOTEIO;
-       }
-       dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr);
-       mutex_unlock(&ca->ca_lock);
-       udelay(50);
-
-       return 0;
-}
-
-int mantis_hif_init(struct mantis_ca *ca)
-{
-       struct mantis_slot *slot = ca->slot;
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 irqcfg;
-
-       slot[0].slave_cfg = 0x70773028;
-       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num);
-
-       mutex_lock(&ca->ca_lock);
-       irqcfg = mmread(MANTIS_GPIF_IRQCFG);
-       irqcfg = MANTIS_MASK_BRRDY      |
-                MANTIS_MASK_WRACK      |
-                MANTIS_MASK_EXTIRQ     |
-                MANTIS_MASK_WSTO       |
-                MANTIS_MASK_OTHERR     |
-                MANTIS_MASK_OVFLW;
-
-       mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
-       mutex_unlock(&ca->ca_lock);
-
-       return 0;
-}
-
-void mantis_hif_exit(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-       u32 irqcfg;
-
-       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num);
-       mutex_lock(&ca->ca_lock);
-       irqcfg = mmread(MANTIS_GPIF_IRQCFG);
-       irqcfg &= ~MANTIS_MASK_BRRDY;
-       mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
-       mutex_unlock(&ca->ca_lock);
-}
diff --git a/drivers/media/dvb/mantis/mantis_hif.h b/drivers/media/dvb/mantis/mantis_hif.h
deleted file mode 100644 (file)
index 9094f9e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_HIF_H
-#define __MANTIS_HIF_H
-
-#define MANTIS_HIF_MEMRD               1
-#define MANTIS_HIF_MEMWR               2
-#define MANTIS_HIF_IOMRD               3
-#define MANTIS_HIF_IOMWR               4
-
-#endif /* __MANTIS_HIF_H */
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c
deleted file mode 100644 (file)
index e779451..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/io.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_i2c.h"
-
-#define TRIALS                 10000
-
-static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
-{
-       u32 rxd, i, stat, trials;
-
-       dprintk(MANTIS_INFO, 0, "        %s:  Address=[0x%02x] <R>[ ",
-               __func__, 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(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
-               mmwrite(rxd, MANTIS_I2CDATA_CTL);
-
-               /* wait for xfer completion */
-               for (trials = 0; trials < TRIALS; trials++) {
-                       stat = mmread(MANTIS_INT_STAT);
-                       if (stat & MANTIS_INT_I2CDONE)
-                               break;
-               }
-
-               dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
-
-               /* wait for xfer completion */
-               for (trials = 0; trials < TRIALS; trials++) {
-                       stat = mmread(MANTIS_INT_STAT);
-                       if (stat & MANTIS_INT_I2CRACK)
-                               break;
-               }
-
-               dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
-
-               rxd = mmread(MANTIS_I2CDATA_CTL);
-               msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
-               dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
-       }
-       dprintk(MANTIS_INFO, 0, "]\n");
-
-       return 0;
-}
-
-static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
-{
-       int i;
-       u32 txd = 0, stat, trials;
-
-       dprintk(MANTIS_INFO, 0, "        %s: Address=[0x%02x] <W>[ ",
-               __func__, msg->addr);
-
-       for (i = 0; i < msg->len; i++) {
-               dprintk(MANTIS_INFO, 0, "%02x ", 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(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
-               mmwrite(txd, MANTIS_I2CDATA_CTL);
-
-               /* wait for xfer completion */
-               for (trials = 0; trials < TRIALS; trials++) {
-                       stat = mmread(MANTIS_INT_STAT);
-                       if (stat & MANTIS_INT_I2CDONE)
-                               break;
-               }
-
-               dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
-
-               /* wait for xfer completion */
-               for (trials = 0; trials < TRIALS; trials++) {
-                       stat = mmread(MANTIS_INT_STAT);
-                       if (stat & MANTIS_INT_I2CRACK)
-                               break;
-               }
-
-               dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
-       }
-       dprintk(MANTIS_INFO, 0, "]\n");
-
-       return 0;
-}
-
-static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
-{
-       int ret = 0, i = 0, trials;
-       u32 stat, data, txd;
-       struct mantis_pci *mantis;
-       struct mantis_hwconfig *config;
-
-       mantis = i2c_get_adapdata(adapter);
-       BUG_ON(!mantis);
-       config = mantis->hwconfig;
-       BUG_ON(!config);
-
-       dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
-       mutex_lock(&mantis->i2c_lock);
-
-       while (i < num) {
-               /* Byte MODE */
-               if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
-                   ((i + 1) < num)                     &&
-                   (msgs[i].len < 2)                   &&
-                   (msgs[i + 1].len < 2)               &&
-                   (msgs[i + 1].flags & I2C_M_RD)) {
-
-                       dprintk(MANTIS_DEBUG, 0, "        Byte MODE:\n");
-
-                       /* Read operation */
-                       txd = msgs[i].addr << 25 | (0x1 << 24)
-                                                | (msgs[i].buf[0] << 16)
-                                                | MANTIS_I2C_RATE_3;
-
-                       mmwrite(txd, MANTIS_I2CDATA_CTL);
-                       /* wait for xfer completion */
-                       for (trials = 0; trials < TRIALS; trials++) {
-                               stat = mmread(MANTIS_INT_STAT);
-                               if (stat & MANTIS_INT_I2CDONE)
-                                       break;
-                       }
-
-                       /* check for xfer completion */
-                       if (stat & MANTIS_INT_I2CDONE) {
-                               /* check xfer was acknowledged */
-                               if (stat & MANTIS_INT_I2CRACK) {
-                                       data = mmread(MANTIS_I2CDATA_CTL);
-                                       msgs[i + 1].buf[0] = (data >> 8) & 0xff;
-                                       dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
-                               } else {
-                                       /* I/O error */
-                                       dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
-                                       ret = -EIO;
-                                       break;
-                               }
-                       } else {
-                               /* I/O error */
-                               dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
-                               ret = -EIO;
-                               break;
-                       }
-                       i += 2; /* Write/Read operation in one go */
-               }
-
-               if (i < num) {
-                       if (msgs[i].flags & I2C_M_RD)
-                               ret = mantis_i2c_read(mantis, &msgs[i]);
-                       else
-                               ret = mantis_i2c_write(mantis, &msgs[i]);
-
-                       i++;
-                       if (ret < 0)
-                               goto bail_out;
-               }
-
-       }
-
-       mutex_unlock(&mantis->i2c_lock);
-
-       return num;
-
-bail_out:
-       mutex_unlock(&mantis->i2c_lock);
-       return ret;
-}
-
-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,
-};
-
-int __devinit mantis_i2c_init(struct mantis_pci *mantis)
-{
-       u32 intstat, intmask;
-       struct i2c_adapter *i2c_adapter = &mantis->adapter;
-       struct pci_dev *pdev            = mantis->pdev;
-
-       init_waitqueue_head(&mantis->i2c_wq);
-       mutex_init(&mantis->i2c_lock);
-       strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
-       i2c_set_adapdata(i2c_adapter, mantis);
-
-       i2c_adapter->owner      = THIS_MODULE;
-       i2c_adapter->algo       = &mantis_algo;
-       i2c_adapter->algo_data  = NULL;
-       i2c_adapter->timeout    = 500;
-       i2c_adapter->retries    = 3;
-       i2c_adapter->dev.parent = &pdev->dev;
-
-       mantis->i2c_rc          = i2c_add_adapter(i2c_adapter);
-       if (mantis->i2c_rc < 0)
-               return mantis->i2c_rc;
-
-       dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
-
-       intstat = mmread(MANTIS_INT_STAT);
-       intmask = mmread(MANTIS_INT_MASK);
-       mmwrite(intstat, MANTIS_INT_STAT);
-       dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
-       intmask = mmread(MANTIS_INT_MASK);
-       mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_i2c_init);
-
-int mantis_i2c_exit(struct mantis_pci *mantis)
-{
-       u32 intmask;
-
-       dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
-       intmask = mmread(MANTIS_INT_MASK);
-       mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
-
-       dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
-       return i2c_del_adapter(&mantis->adapter);
-}
-EXPORT_SYMBOL_GPL(mantis_i2c_exit);
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h
deleted file mode 100644 (file)
index 1342df2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_I2C_H
-#define __MANTIS_I2C_H
-
-#define I2C_STOP               (1 <<  0)
-#define I2C_READ               (1 <<  1)
-
-extern int mantis_i2c_init(struct mantis_pci *mantis);
-extern int mantis_i2c_exit(struct mantis_pci *mantis);
-
-#endif /* __MANTIS_I2C_H */
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
deleted file mode 100644 (file)
index db6d54d..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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 <media/rc-core.h>
-#include <linux/pci.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_uart.h"
-
-#define MODULE_NAME "mantis_core"
-#define RC_MAP_MANTIS "rc-mantis"
-
-static struct rc_map_table mantis_ir_table[] = {
-       { 0x29, KEY_POWER       },
-       { 0x28, KEY_FAVORITES   },
-       { 0x30, KEY_TEXT        },
-       { 0x17, KEY_INFO        }, /* Preview */
-       { 0x23, KEY_EPG         },
-       { 0x3b, KEY_F22         }, /* Record List */
-       { 0x3c, KEY_1           },
-       { 0x3e, KEY_2           },
-       { 0x39, KEY_3           },
-       { 0x36, KEY_4           },
-       { 0x22, KEY_5           },
-       { 0x20, KEY_6           },
-       { 0x32, KEY_7           },
-       { 0x26, KEY_8           },
-       { 0x24, KEY_9           },
-       { 0x2a, KEY_0           },
-
-       { 0x33, KEY_CANCEL      },
-       { 0x2c, KEY_BACK        },
-       { 0x15, KEY_CLEAR       },
-       { 0x3f, KEY_TAB         },
-       { 0x10, KEY_ENTER       },
-       { 0x14, KEY_UP          },
-       { 0x0d, KEY_RIGHT       },
-       { 0x0e, KEY_DOWN        },
-       { 0x11, KEY_LEFT        },
-
-       { 0x21, KEY_VOLUMEUP    },
-       { 0x35, KEY_VOLUMEDOWN  },
-       { 0x3d, KEY_CHANNELDOWN },
-       { 0x3a, KEY_CHANNELUP   },
-       { 0x2e, KEY_RECORD      },
-       { 0x2b, KEY_PLAY        },
-       { 0x13, KEY_PAUSE       },
-       { 0x25, KEY_STOP        },
-
-       { 0x1f, KEY_REWIND      },
-       { 0x2d, KEY_FASTFORWARD },
-       { 0x1e, KEY_PREVIOUS    }, /* Replay |< */
-       { 0x1d, KEY_NEXT        }, /* Skip   >| */
-
-       { 0x0b, KEY_CAMERA      }, /* Capture */
-       { 0x0f, KEY_LANGUAGE    }, /* SAP */
-       { 0x18, KEY_MODE        }, /* PIP */
-       { 0x12, KEY_ZOOM        }, /* Full screen */
-       { 0x1c, KEY_SUBTITLE    },
-       { 0x2f, KEY_MUTE        },
-       { 0x16, KEY_F20         }, /* L/R */
-       { 0x38, KEY_F21         }, /* Hibernate */
-
-       { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */
-       { 0x31, KEY_AGAIN       }, /* Recall */
-       { 0x1a, KEY_KPPLUS      }, /* Zoom+ */
-       { 0x19, KEY_KPMINUS     }, /* Zoom- */
-       { 0x27, KEY_RED         },
-       { 0x0C, KEY_GREEN       },
-       { 0x01, KEY_YELLOW      },
-       { 0x00, KEY_BLUE        },
-};
-
-static struct rc_map_list ir_mantis_map = {
-       .map = {
-               .scan = mantis_ir_table,
-               .size = ARRAY_SIZE(mantis_ir_table),
-               .rc_type = RC_TYPE_UNKNOWN,
-               .name = RC_MAP_MANTIS,
-       }
-};
-
-int mantis_input_init(struct mantis_pci *mantis)
-{
-       struct rc_dev *dev;
-       int err;
-
-       err = rc_map_register(&ir_mantis_map);
-       if (err)
-               goto out;
-
-       dev = rc_allocate_device();
-       if (!dev) {
-               dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
-               err = -ENOMEM;
-               goto out_map;
-       }
-
-       sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
-       sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
-
-       dev->input_name         = mantis->input_name;
-       dev->input_phys         = mantis->input_phys;
-       dev->input_id.bustype   = BUS_PCI;
-       dev->input_id.vendor    = mantis->vendor_id;
-       dev->input_id.product   = mantis->device_id;
-       dev->input_id.version   = 1;
-       dev->driver_name        = MODULE_NAME;
-       dev->map_name           = RC_MAP_MANTIS;
-       dev->dev.parent         = &mantis->pdev->dev;
-
-       err = rc_register_device(dev);
-       if (err) {
-               dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
-               goto out_dev;
-       }
-
-       mantis->rc = dev;
-       return 0;
-
-out_dev:
-       rc_free_device(dev);
-out_map:
-       rc_map_unregister(&ir_mantis_map);
-out:
-       return err;
-}
-
-int mantis_exit(struct mantis_pci *mantis)
-{
-       rc_unregister_device(mantis->rc);
-       rc_map_unregister(&ir_mantis_map);
-       return 0;
-}
-
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
deleted file mode 100644 (file)
index 24fcdc6..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <linux/i2c.h>
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_ioc.h"
-
-static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
-{
-       struct i2c_adapter *adapter = &mantis->adapter;
-       int err;
-       u8 buf = reg;
-
-       struct i2c_msg msg[] = {
-               { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
-               { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
-       };
-
-       err = i2c_transfer(adapter, msg, 2);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
-                       err, data[0], data[1]);
-
-               return err;
-       }
-
-       return 0;
-}
-int mantis_get_mac(struct mantis_pci *mantis)
-{
-       int err;
-       u8 mac_addr[6] = {0};
-
-       err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
-       if (err < 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
-
-               return err;
-       }
-
-       dprintk(MANTIS_ERROR, 0, "    MAC Address=[%pM]\n", mac_addr);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_get_mac);
-
-/* Turn the given bit on or off. */
-void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
-{
-       u32 cur;
-
-       dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
-       cur = mmread(MANTIS_GPIF_ADDR);
-       if (value)
-               mantis->gpio_status = cur | (1 << bitpos);
-       else
-               mantis->gpio_status = cur & (~(1 << bitpos));
-
-       dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
-       mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
-       mmwrite(0x00, MANTIS_GPIF_DOUT);
-}
-EXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
-
-int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
-{
-       u32 reg;
-
-       reg = mmread(MANTIS_CONTROL);
-       switch (stream_ctl) {
-       case STREAM_TO_HIF:
-               dprintk(MANTIS_DEBUG, 1, "Set stream to HIF");
-               reg &= 0xff - MANTIS_BYPASS;
-               mmwrite(reg, MANTIS_CONTROL);
-               reg |= MANTIS_BYPASS;
-               mmwrite(reg, MANTIS_CONTROL);
-               break;
-
-       case STREAM_TO_CAM:
-               dprintk(MANTIS_DEBUG, 1, "Set stream to CAM");
-               reg |= MANTIS_BYPASS;
-               mmwrite(reg, MANTIS_CONTROL);
-               reg &= 0xff - MANTIS_BYPASS;
-               mmwrite(reg, MANTIS_CONTROL);
-               break;
-       default:
-               dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl);
-               return -1;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_stream_control);
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h
deleted file mode 100644 (file)
index d56e002..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_IOC_H
-#define __MANTIS_IOC_H
-
-#define GPIF_A00               0x00
-#define GPIF_A01               0x01
-#define GPIF_A02               0x02
-#define GPIF_A03               0x03
-#define GPIF_A04               0x04
-#define GPIF_A05               0x05
-#define GPIF_A06               0x06
-#define GPIF_A07               0x07
-#define GPIF_A08               0x08
-#define GPIF_A09               0x09
-#define GPIF_A10               0x0a
-#define GPIF_A11               0x0b
-
-#define GPIF_A12               0x0c
-#define GPIF_A13               0x0d
-#define GPIF_A14               0x0e
-
-enum mantis_stream_control {
-       STREAM_TO_HIF = 0,
-       STREAM_TO_CAM
-};
-
-extern int mantis_get_mac(struct mantis_pci *mantis);
-extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
-
-extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
-
-#endif /* __MANTIS_IOC_H */
diff --git a/drivers/media/dvb/mantis/mantis_link.h b/drivers/media/dvb/mantis/mantis_link.h
deleted file mode 100644 (file)
index 2a81477..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_LINK_H
-#define __MANTIS_LINK_H
-
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include "dvb_ca_en50221.h"
-
-enum mantis_sbuf_status {
-       MANTIS_SBUF_DATA_AVAIL          = 1,
-       MANTIS_SBUF_DATA_EMPTY          = 2,
-       MANTIS_SBUF_DATA_OVFLW          = 3
-};
-
-struct mantis_slot {
-       u32                             timeout;
-       u32                             slave_cfg;
-       u32                             bar;
-};
-
-/* Physical layer */
-enum mantis_slot_state {
-       MODULE_INSERTED                 = 3,
-       MODULE_XTRACTED                 = 4
-};
-
-struct mantis_ca {
-       struct mantis_slot              slot[4];
-
-       struct work_struct              hif_evm_work;
-
-       u32                             hif_event;
-       wait_queue_head_t               hif_opdone_wq;
-       wait_queue_head_t               hif_brrdyw_wq;
-       wait_queue_head_t               hif_data_wq;
-       wait_queue_head_t               hif_write_wq; /* HIF Write op */
-
-       enum mantis_sbuf_status         sbuf_status;
-
-       enum mantis_slot_state          slot_state;
-
-       void                            *ca_priv;
-
-       struct dvb_ca_en50221           en50221;
-       struct mutex                    ca_lock;
-};
-
-/* CA */
-extern void mantis_event_cam_plugin(struct mantis_ca *ca);
-extern void mantis_event_cam_unplug(struct mantis_ca *ca);
-extern int mantis_pcmcia_init(struct mantis_ca *ca);
-extern void mantis_pcmcia_exit(struct mantis_ca *ca);
-extern int mantis_evmgr_init(struct mantis_ca *ca);
-extern void mantis_evmgr_exit(struct mantis_ca *ca);
-
-/* HIF */
-extern int mantis_hif_init(struct mantis_ca *ca);
-extern void mantis_hif_exit(struct mantis_ca *ca);
-extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr);
-extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data);
-extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr);
-extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data);
-
-#endif /* __MANTIS_LINK_H */
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c
deleted file mode 100644 (file)
index 371558a..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <linux/kmod.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/pci.h>
-
-#include <asm/irq.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_pci.h"
-
-#define DRIVER_NAME            "Mantis Core"
-
-int __devinit mantis_pci_init(struct mantis_pci *mantis)
-{
-       u8 latency;
-       struct mantis_hwconfig *config  = mantis->hwconfig;
-       struct pci_dev *pdev            = mantis->pdev;
-       int err, ret = 0;
-
-       dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
-               config->model_name,
-               config->dev_type,
-               mantis->pdev->bus->number,
-               PCI_SLOT(mantis->pdev->devfn),
-               PCI_FUNC(mantis->pdev->devfn));
-
-       err = pci_enable_device(pdev);
-       if (err != 0) {
-               ret = -ENODEV;
-               dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err);
-               goto fail0;
-       }
-
-       err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (err != 0) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err);
-               ret = -ENOMEM;
-               goto fail1;
-       }
-
-       pci_set_master(pdev);
-
-       if (!request_mem_region(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0),
-                               DRIVER_NAME)) {
-
-               dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !");
-               ret = -ENODEV;
-               goto fail1;
-       }
-
-       mantis->mmio = ioremap(pci_resource_start(pdev, 0),
-                              pci_resource_len(pdev, 0));
-
-       if (!mantis->mmio) {
-               dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !");
-               ret = -ENODEV;
-               goto fail2;
-       }
-
-       pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
-       mantis->latency = latency;
-       mantis->revision = pdev->revision;
-
-       dprintk(MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
-               mantis->revision,
-               mantis->pdev->subsystem_vendor,
-               mantis->pdev->subsystem_device);
-
-       dprintk(MANTIS_ERROR, 0,
-               "irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
-               mantis->pdev->irq,
-               mantis->latency,
-               mantis->mantis_addr,
-               mantis->mmio);
-
-       err = request_irq(pdev->irq,
-                         config->irq_handler,
-                         IRQF_SHARED,
-                         DRIVER_NAME,
-                         mantis);
-
-       if (err != 0) {
-
-               dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err);
-               ret = -ENODEV;
-               goto fail3;
-       }
-
-       pci_set_drvdata(pdev, mantis);
-       return ret;
-
-       /* Error conditions */
-fail3:
-       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret);
-       if (mantis->mmio)
-               iounmap(mantis->mmio);
-
-fail2:
-       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret);
-       release_mem_region(pci_resource_start(pdev, 0),
-                          pci_resource_len(pdev, 0));
-
-fail1:
-       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret);
-       pci_disable_device(pdev);
-
-fail0:
-       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
-       pci_set_drvdata(pdev, NULL);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(mantis_pci_init);
-
-void mantis_pci_exit(struct mantis_pci *mantis)
-{
-       struct pci_dev *pdev = mantis->pdev;
-
-       dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
-       free_irq(pdev->irq, mantis);
-       if (mantis->mmio) {
-               iounmap(mantis->mmio);
-               release_mem_region(pci_resource_start(pdev, 0),
-                                  pci_resource_len(pdev, 0));
-       }
-
-       pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
-}
-EXPORT_SYMBOL_GPL(mantis_pci_exit);
-
-MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/mantis/mantis_pci.h b/drivers/media/dvb/mantis/mantis_pci.h
deleted file mode 100644 (file)
index 65f0045..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_PCI_H
-#define __MANTIS_PCI_H
-
-extern int mantis_pci_init(struct mantis_pci *mantis);
-extern void mantis_pci_exit(struct mantis_pci *mantis);
-
-#endif /* __MANTIS_PCI_H */
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c
deleted file mode 100644 (file)
index 2f188c0..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_link.h" /* temporary due to physical layer stuff */
-#include "mantis_reg.h"
-
-/*
- * If Slot state is already PLUG_IN event and we are called
- * again, definitely it is jitter alone
- */
-void mantis_event_cam_plugin(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       u32 gpif_irqcfg;
-
-       if (ca->slot_state == MODULE_XTRACTED) {
-               dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num);
-               udelay(50);
-               mmwrite(0xda000000, MANTIS_CARD_RESET);
-               gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
-               gpif_irqcfg |= MANTIS_MASK_PLUGOUT;
-               gpif_irqcfg &= ~MANTIS_MASK_PLUGIN;
-               mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
-               udelay(500);
-               ca->slot_state = MODULE_INSERTED;
-       }
-       udelay(100);
-}
-
-/*
- * If Slot state is already UN_PLUG event and we are called
- * again, definitely it is jitter alone
- */
-void mantis_event_cam_unplug(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       u32 gpif_irqcfg;
-
-       if (ca->slot_state == MODULE_INSERTED) {
-               dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num);
-               udelay(50);
-               mmwrite(0x00da0000, MANTIS_CARD_RESET);
-               gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
-               gpif_irqcfg |= MANTIS_MASK_PLUGIN;
-               gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT;
-               mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
-               udelay(500);
-               ca->slot_state = MODULE_XTRACTED;
-       }
-       udelay(100);
-}
-
-int mantis_pcmcia_init(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       u32 gpif_stat, card_stat;
-
-       mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK);
-       gpif_stat = mmread(MANTIS_GPIF_STATUS);
-       card_stat = mmread(MANTIS_GPIF_IRQCFG);
-
-       if (gpif_stat & MANTIS_GPIF_DETSTAT) {
-               dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num);
-               mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG);
-               ca->slot_state = MODULE_INSERTED;
-               dvb_ca_en50221_camchange_irq(&ca->en50221,
-                                            0,
-                                            DVB_CA_EN50221_CAMCHANGE_INSERTED);
-       } else {
-               dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num);
-               mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG);
-               ca->slot_state = MODULE_XTRACTED;
-               dvb_ca_en50221_camchange_irq(&ca->en50221,
-                                            0,
-                                            DVB_CA_EN50221_CAMCHANGE_REMOVED);
-       }
-
-       return 0;
-}
-
-void mantis_pcmcia_exit(struct mantis_ca *ca)
-{
-       struct mantis_pci *mantis = ca->ca_priv;
-
-       mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS);
-       mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK);
-}
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/dvb/mantis/mantis_reg.h
deleted file mode 100644 (file)
index 7761f9d..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_GPIF_RD                 (0xff << 24)
-#define MANTIS_GPIF_WR                 (0xff << 16)
-#define MANTIS_CPU_DO                  (0x01 << 10)
-#define MANTIS_DRV_DO                  (0x01 <<  9)
-#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)
-
-/* DEBUG */
-#define MANTIS_DEBUGREG                        0x0c
-#define MANTIS_DATINV                  (0x0e <<  7)
-#define MANTIS_TOP_DEBUGSEL            (0x07 <<  4)
-#define MANTIS_PCMCIA_DEBUGSEL         (0x0f <<  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)
-
-/* DATA */
-#define MANTIS_CMD_DATA_R1             0x20
-#define MANTIS_CMD_DATA_3              (0xff << 24)
-#define MANTIS_CMD_DATA_2              (0xff << 16)
-#define MANTIS_CMD_DATA_1              (0xff <<  8)
-#define MANTIS_CMD_DATA_0              (0xff <<  0)
-
-#define MANTIS_CMD_DATA_R2             0x24
-#define MANTIS_CMD_DATA_7              (0xff << 24)
-#define MANTIS_CMD_DATA_6              (0xff << 16)
-#define MANTIS_CMD_DATA_5              (0xff <<  8)
-#define MANTIS_CMD_DATA_4              (0xff <<  0)
-
-#define MANTIS_CONTROL                 0x28
-#define MANTIS_DET                     (0x01 <<  7)
-#define MANTIS_DAT_CF_EN               (0x01 <<  6)
-#define MANTIS_ACS                     (0x03 <<  4)
-#define MANTIS_VCCEN                   (0x01 <<  3)
-#define MANTIS_BYPASS                  (0x01 <<  2)
-#define MANTIS_MRST                    (0x01 <<  1)
-#define MANTIS_CRST_INT                        (0x01 <<  0)
-
-#define MANTIS_GPIF_CFGSLA             0x84
-#define MANTIS_GPIF_WAITSMPL           (0x07 << 28)
-#define MANTIS_GPIF_BYTEADDRSUB                (0x01 << 25)
-#define MANTIS_GPIF_WAITPOL            (0x01 << 24)
-#define MANTIS_GPIF_NCDELAY            (0x07 << 20)
-#define MANTIS_GPIF_RW2CSDELAY         (0x07 << 16)
-#define MANTIS_GPIF_SLFTIMEDMODE       (0x01 << 15)
-#define MANTIS_GPIF_SLFTIMEDDELY       (0x7f <<  8)
-#define MANTIS_GPIF_DEVTYPE            (0x07 <<  4)
-#define MANTIS_GPIF_BIGENDIAN          (0x01 <<  3)
-#define MANTIS_GPIF_FETCHCMD           (0x03 <<  1)
-#define MANTIS_GPIF_HWORDDEV           (0x01 <<  0)
-
-#define MANTIS_GPIF_WSTOPER            0x90
-#define MANTIS_GPIF_WSTOPERWREN3       (0x01 << 31)
-#define MANTIS_GPIF_PARBOOTN           (0x01 << 29)
-#define MANTIS_GPIF_WSTOPERSLID3       (0x1f << 24)
-#define MANTIS_GPIF_WSTOPERWREN2       (0x01 << 23)
-#define MANTIS_GPIF_WSTOPERSLID2       (0x1f << 16)
-#define MANTIS_GPIF_WSTOPERWREN1       (0x01 << 15)
-#define MANTIS_GPIF_WSTOPERSLID1       (0x1f <<  8)
-#define MANTIS_GPIF_WSTOPERWREN0       (0x01 <<  7)
-#define MANTIS_GPIF_WSTOPERSLID0       (0x1f <<  0)
-
-#define MANTIS_GPIF_CS2RW              0x94
-#define MANTIS_GPIF_CS2RWWREN3         (0x01 << 31)
-#define MANTIS_GPIF_CS2RWDELY3         (0x3f << 24)
-#define MANTIS_GPIF_CS2RWWREN2         (0x01 << 23)
-#define MANTIS_GPIF_CS2RWDELY2         (0x3f << 16)
-#define MANTIS_GPIF_CS2RWWREN1         (0x01 << 15)
-#define MANTIS_GPIF_CS2RWDELY1         (0x3f <<  8)
-#define MANTIS_GPIF_CS2RWWREN0         (0x01 <<  7)
-#define MANTIS_GPIF_CS2RWDELY0         (0x3f <<  0)
-
-#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_BRADDR             0xa0
-#define MANTIS_GPIF_PCMCIAREG          (0x01           << 27)
-#define MANTIS_GPIF_PCMCIAIOM          (0x01           << 26)
-#define MANTIS_GPIF_BR_ADDR            (0xfffffff      <<  0)
-
-#define MANTIS_GPIF_BRBYTES            0xa4
-#define MANTIS_GPIF_BRCNT              (0xfff          <<  0)
-
-#define MANTIS_PCMCIA_RESET            0xa8
-#define MANTIS_PCMCIA_RSTVAL           (0xff << 0)
-
-#define MANTIS_CARD_RESET              0xac
-
-#define MANTIS_GPIF_ADDR               0xb0
-#define MANTIS_GPIF_HIFRDWRN           (0x01           << 31)
-#define MANTIS_GPIF_PCMCIAREG          (0x01           << 27)
-#define MANTIS_GPIF_PCMCIAIOM          (0x01           << 26)
-#define MANTIS_GPIF_HIFADDR            (0xfffffff      <<  0)
-
-#define MANTIS_GPIF_DOUT               0xb4
-#define MANTIS_GPIF_HIFDOUT            (0xfffffff      <<  0)
-
-#define MANTIS_GPIF_DIN                        0xb8
-#define MANTIS_GPIF_HIFDIN             (0xfffffff      <<  0)
-
-#define MANTIS_GPIF_SPARE              0xbc
-#define MANTIS_GPIF_LOGICRD            (0xffff         << 16)
-#define MANTIS_GPIF_LOGICRW            (0xffff         <<  0)
-
-#endif /* __MANTIS_REG_H */
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c
deleted file mode 100644 (file)
index 18340da..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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/kernel.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_reg.h"
-#include "mantis_uart.h"
-
-struct mantis_uart_params {
-       enum mantis_baud        baud_rate;
-       enum mantis_parity      parity;
-};
-
-static struct {
-       char string[7];
-} rates[5] = {
-       { "9600" },
-       { "19200" },
-       { "38400" },
-       { "57600" },
-       { "115200" }
-};
-
-static struct {
-       char string[5];
-} parity[3] = {
-       { "NONE" },
-       { "ODD" },
-       { "EVEN" }
-};
-
-#define UART_MAX_BUF                   16
-
-int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
-{
-       struct mantis_hwconfig *config = mantis->hwconfig;
-       u32 stat = 0, i;
-
-       /* get data */
-       for (i = 0; i < (config->bytes + 1); i++) {
-
-               stat = mmread(MANTIS_UART_STAT);
-
-               if (stat & MANTIS_UART_RXFIFO_FULL) {
-                       dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
-               }
-               data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
-
-               dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
-
-               if (data[i] & (1 << 7)) {
-                       dprintk(MANTIS_ERROR, 1, "UART framing error");
-                       return -EINVAL;
-               }
-               if (data[i] & (1 << 6)) {
-                       dprintk(MANTIS_ERROR, 1, "UART parity error");
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-static void mantis_uart_work(struct work_struct *work)
-{
-       struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
-       struct mantis_hwconfig *config = mantis->hwconfig;
-       u8 buf[16];
-       int i;
-
-       mantis_uart_read(mantis, buf);
-
-       for (i = 0; i < (config->bytes + 1); i++)
-               dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
-
-       dprintk(MANTIS_DEBUG, 0, "\n");
-}
-
-static int mantis_uart_setup(struct mantis_pci *mantis,
-                            struct mantis_uart_params *params)
-{
-       u32 reg;
-
-       mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
-
-       reg = mmread(MANTIS_UART_BAUD);
-
-       switch (params->baud_rate) {
-       case MANTIS_BAUD_9600:
-               reg |= 0xd8;
-               break;
-       case MANTIS_BAUD_19200:
-               reg |= 0x6c;
-               break;
-       case MANTIS_BAUD_38400:
-               reg |= 0x36;
-               break;
-       case MANTIS_BAUD_57600:
-               reg |= 0x23;
-               break;
-       case MANTIS_BAUD_115200:
-               reg |= 0x11;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       mmwrite(reg, MANTIS_UART_BAUD);
-
-       return 0;
-}
-
-int mantis_uart_init(struct mantis_pci *mantis)
-{
-       struct mantis_hwconfig *config = mantis->hwconfig;
-       struct mantis_uart_params params;
-
-       /* default parity: */
-       params.baud_rate = config->baud_rate;
-       params.parity = config->parity;
-       dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
-               rates[params.baud_rate].string,
-               parity[params.parity].string);
-
-       init_waitqueue_head(&mantis->uart_wq);
-       spin_lock_init(&mantis->uart_lock);
-
-       INIT_WORK(&mantis->uart_work, mantis_uart_work);
-
-       /* disable interrupt */
-       mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
-
-       mantis_uart_setup(mantis, &params);
-
-       /* default 1 byte */
-       mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
-
-       /* flush buffer */
-       mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
-
-       /* enable interrupt */
-       mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
-       mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
-
-       schedule_work(&mantis->uart_work);
-       dprintk(MANTIS_DEBUG, 1, "UART successfully initialized");
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mantis_uart_init);
-
-void mantis_uart_exit(struct mantis_pci *mantis)
-{
-       /* disable interrupt */
-       mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
-       flush_work_sync(&mantis->uart_work);
-}
-EXPORT_SYMBOL_GPL(mantis_uart_exit);
diff --git a/drivers/media/dvb/mantis/mantis_uart.h b/drivers/media/dvb/mantis/mantis_uart.h
deleted file mode 100644 (file)
index ffb62a0..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-       Mantis PCI bridge driver
-
-       Copyright (C) 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_UART_H
-#define __MANTIS_UART_H
-
-#define MANTIS_UART_CTL                        0xe0
-#define MANTIS_UART_RXINT              (1 << 4)
-#define MANTIS_UART_RXFLUSH            (1 << 2)
-
-#define MANTIS_UART_RXD                        0xe8
-#define MANTIS_UART_BAUD               0xec
-
-#define MANTIS_UART_STAT               0xf0
-#define MANTIS_UART_RXFIFO_DATA                (1 << 7)
-#define MANTIS_UART_RXFIFO_EMPTY       (1 << 6)
-#define MANTIS_UART_RXFIFO_FULL                (1 << 3)
-#define MANTIS_UART_FRAME_ERR          (1 << 2)
-#define MANTIS_UART_PARITY_ERR         (1 << 1)
-#define MANTIS_UART_RXTHRESH_INT       (1 << 0)
-
-enum mantis_baud {
-       MANTIS_BAUD_9600        = 0,
-       MANTIS_BAUD_19200,
-       MANTIS_BAUD_38400,
-       MANTIS_BAUD_57600,
-       MANTIS_BAUD_115200
-};
-
-enum mantis_parity {
-       MANTIS_PARITY_NONE      = 0,
-       MANTIS_PARITY_EVEN,
-       MANTIS_PARITY_ODD,
-};
-
-struct mantis_pci;
-
-extern int mantis_uart_init(struct mantis_pci *mantis);
-extern void mantis_uart_exit(struct mantis_pci *mantis);
-
-#endif /* __MANTIS_UART_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c
deleted file mode 100644 (file)
index ad013e9..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
-       Mantis VP-1033 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "stv0299.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp1033.h"
-#include "mantis_reg.h"
-
-u8 lgtdqcs001f_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       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,
-};
-
-#define MANTIS_MODEL_NAME      "VP-1033"
-#define MANTIS_DEV_TYPE                "DVB-S/DSS"
-
-int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mantis_pci *mantis       = fe->dvb->priv;
-       struct i2c_adapter *adapter     = &mantis->adapter;
-
-       u8 buf[4];
-       u32 div;
-
-
-       struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
-
-       div = p->frequency / 250;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] =  div & 0xff;
-       buf[2] =  0x83;
-       buf[3] =  0xc0;
-
-       if (p->frequency < 1531000)
-               buf[3] |= 0x04;
-       else
-               buf[3] &= ~0x04;
-       if (i2c_transfer(adapter, &msg, 1) < 0) {
-               dprintk(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;
-}
-
-struct stv0299_config lgtdqcs001f_config = {
-       .demod_address          = 0x68,
-       .inittab                = lgtdqcs001f_inittab,
-       .mclk                   = 88000000UL,
-       .invert                 = 0,
-       .skip_reinit            = 0,
-       .volt13_op0_op1         = STV0299_VOLT13_OP0,
-       .min_delay_ms           = 100,
-       .set_symbol_rate        = lgtdqcs001f_set_symbol_rate,
-};
-
-static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter     = &mantis->adapter;
-
-       int err = 0;
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               mantis_frontend_soft_reset(mantis);
-               msleep(250);
-
-               dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
-               fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
-
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
-                       dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
-                               lgtdqcs001f_config.demod_address);
-
-                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
-               } else {
-                       return -1;
-               }
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-       mantis->fe = fe;
-       dprintk(MANTIS_ERROR, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp1033_config = {
-       .model_name             = MANTIS_MODEL_NAME,
-       .dev_type               = MANTIS_DEV_TYPE,
-       .ts_size                = MANTIS_TS_204,
-
-       .baud_rate              = MANTIS_BAUD_9600,
-       .parity                 = MANTIS_PARITY_NONE,
-       .bytes                  = 0,
-
-       .frontend_init          = vp1033_frontend_init,
-       .power                  = GPIF_A12,
-       .reset                  = GPIF_A13,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/dvb/mantis/mantis_vp1033.h
deleted file mode 100644 (file)
index 7daaa1b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Mantis VP-1033 driver
-
-       Copyright (C) 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 "mantis_common.h"
-
-#define MANTIS_VP_1033_DVB_S   0x0016
-
-extern struct mantis_hwconfig vp1033_config;
-
-#endif /* __MANTIS_VP1033_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c
deleted file mode 100644 (file)
index 430ae84..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-       Mantis VP-1034 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mb86a16.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp1034.h"
-#include "mantis_reg.h"
-
-struct mb86a16_config vp1034_mb86a16_config = {
-       .demod_address  = 0x08,
-       .set_voltage    = vp1034_set_voltage,
-};
-
-#define MANTIS_MODEL_NAME      "VP-1034"
-#define MANTIS_DEV_TYPE                "DVB-S/DSS"
-
-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:
-               dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
-               mantis_gpio_set_bits(mantis, 13, 1);
-               mantis_gpio_set_bits(mantis, 14, 0);
-               break;
-       case SEC_VOLTAGE_18:
-               dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
-               mantis_gpio_set_bits(mantis, 13, 1);
-               mantis_gpio_set_bits(mantis, 14, 1);
-               break;
-       case SEC_VOLTAGE_OFF:
-               dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
-               break;
-       default:
-               dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage);
-               return -EINVAL;
-       }
-       mmwrite(0x00, MANTIS_GPIF_DOUT);
-
-       return 0;
-}
-
-static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter     = &mantis->adapter;
-
-       int err = 0;
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               mantis_frontend_soft_reset(mantis);
-               msleep(250);
-
-               dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
-               fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter);
-               if (fe) {
-                       dprintk(MANTIS_ERROR, 1,
-                       "found MB86A16 DVB-S/DSS frontend @0x%02x",
-                       vp1034_mb86a16_config.demod_address);
-
-               } else {
-                       return -1;
-               }
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-       mantis->fe = fe;
-       dprintk(MANTIS_ERROR, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp1034_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_204,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp1034_frontend_init,
-       .power          = GPIF_A12,
-       .reset          = GPIF_A13,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/dvb/mantis/mantis_vp1034.h
deleted file mode 100644 (file)
index 323f38e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-       Mantis VP-1034 driver
-
-       Copyright (C) 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 "dvb_frontend.h"
-#include "mantis_common.h"
-
-
-#define MANTIS_VP_1034_DVB_S   0x0014
-
-extern struct mantis_hwconfig 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_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c
deleted file mode 100644 (file)
index 07aa887..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
-       Mantis VP-1041 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp1041.h"
-#include "stb0899_reg.h"
-#include "stb0899_drv.h"
-#include "stb0899_cfg.h"
-#include "stb6100_cfg.h"
-#include "stb6100.h"
-#include "lnbp21.h"
-
-#define MANTIS_MODEL_NAME      "VP-1041"
-#define MANTIS_DEV_TYPE                "DSS/DVB-S/DVB-S2"
-
-static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
-
-       /* 0x0000000b, *//* SYSREG */
-       { STB0899_DEV_ID                , 0x30 },
-       { STB0899_DISCNTRL1             , 0x32 },
-       { STB0899_DISCNTRL2             , 0x80 },
-       { STB0899_DISRX_ST0             , 0x04 },
-       { STB0899_DISRX_ST1             , 0x00 },
-       { STB0899_DISPARITY             , 0x00 },
-       { STB0899_DISSTATUS             , 0x20 },
-       { STB0899_DISF22                , 0x99 },
-       { STB0899_DISF22RX              , 0xa8 },
-       /* SYSREG ? */
-       { STB0899_ACRPRESC              , 0x11 },
-       { STB0899_ACRDIV1               , 0x0a },
-       { STB0899_ACRDIV2               , 0x05 },
-       { STB0899_DACR1                 , 0x00 },
-       { STB0899_DACR2                 , 0x00 },
-       { STB0899_OUTCFG                , 0x00 },
-       { STB0899_MODECFG               , 0x00 },
-       { STB0899_IRQSTATUS_3           , 0xfe },
-       { STB0899_IRQSTATUS_2           , 0x03 },
-       { STB0899_IRQSTATUS_1           , 0x7c },
-       { STB0899_IRQSTATUS_0           , 0xf4 },
-       { STB0899_IRQMSK_3              , 0xf3 },
-       { STB0899_IRQMSK_2              , 0xfc },
-       { STB0899_IRQMSK_1              , 0xff },
-       { STB0899_IRQMSK_0              , 0xff },
-       { STB0899_IRQCFG                , 0x00 },
-       { STB0899_I2CCFG                , 0x88 },
-       { STB0899_I2CRPT                , 0x58 },
-       { STB0899_IOPVALUE5             , 0x00 },
-       { STB0899_IOPVALUE4             , 0x33 },
-       { STB0899_IOPVALUE3             , 0x6d },
-       { STB0899_IOPVALUE2             , 0x90 },
-       { STB0899_IOPVALUE1             , 0x60 },
-       { STB0899_IOPVALUE0             , 0x00 },
-       { STB0899_GPIO00CFG             , 0x82 },
-       { STB0899_GPIO01CFG             , 0x82 },
-       { STB0899_GPIO02CFG             , 0x82 },
-       { STB0899_GPIO03CFG             , 0x82 },
-       { STB0899_GPIO04CFG             , 0x82 },
-       { STB0899_GPIO05CFG             , 0x82 },
-       { STB0899_GPIO06CFG             , 0x82 },
-       { STB0899_GPIO07CFG             , 0x82 },
-       { STB0899_GPIO08CFG             , 0x82 },
-       { STB0899_GPIO09CFG             , 0x82 },
-       { STB0899_GPIO10CFG             , 0x82 },
-       { STB0899_GPIO11CFG             , 0x82 },
-       { STB0899_GPIO12CFG             , 0x82 },
-       { STB0899_GPIO13CFG             , 0x82 },
-       { STB0899_GPIO14CFG             , 0x82 },
-       { STB0899_GPIO15CFG             , 0x82 },
-       { STB0899_GPIO16CFG             , 0x82 },
-       { STB0899_GPIO17CFG             , 0x82 },
-       { STB0899_GPIO18CFG             , 0x82 },
-       { STB0899_GPIO19CFG             , 0x82 },
-       { STB0899_GPIO20CFG             , 0x82 },
-       { STB0899_SDATCFG               , 0xb8 },
-       { STB0899_SCLTCFG               , 0xba },
-       { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
-       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
-       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
-       { STB0899_DIRCLKCFG             , 0x82 },
-       { STB0899_CLKOUT27CFG           , 0x7e },
-       { STB0899_STDBYCFG              , 0x82 },
-       { STB0899_CS0CFG                , 0x82 },
-       { STB0899_CS1CFG                , 0x82 },
-       { STB0899_DISEQCOCFG            , 0x20 },
-       { STB0899_GPIO32CFG             , 0x82 },
-       { STB0899_GPIO33CFG             , 0x82 },
-       { STB0899_GPIO34CFG             , 0x82 },
-       { STB0899_GPIO35CFG             , 0x82 },
-       { STB0899_GPIO36CFG             , 0x82 },
-       { STB0899_GPIO37CFG             , 0x82 },
-       { STB0899_GPIO38CFG             , 0x82 },
-       { STB0899_GPIO39CFG             , 0x82 },
-       { STB0899_NCOARSE               , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-       { STB0899_FILTCTRL              , 0x00 },
-       { STB0899_SYSCTRL               , 0x01 },
-       { STB0899_STOPCLK1              , 0x20 },
-       { STB0899_STOPCLK2              , 0x00 },
-       { STB0899_INTBUFSTATUS          , 0x00 },
-       { STB0899_INTBUFCTRL            , 0x0a },
-       { 0xffff                        , 0xff },
-};
-
-static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
-       { STB0899_DEMOD                 , 0x00 },
-       { STB0899_RCOMPC                , 0xc9 },
-       { STB0899_AGC1CN                , 0x01 },
-       { STB0899_AGC1REF               , 0x10 },
-       { STB0899_RTC                   , 0x23 },
-       { STB0899_TMGCFG                , 0x4e },
-       { STB0899_AGC2REF               , 0x34 },
-       { STB0899_TLSR                  , 0x84 },
-       { STB0899_CFD                   , 0xf7 },
-       { STB0899_ACLC                  , 0x87 },
-       { STB0899_BCLC                  , 0x94 },
-       { STB0899_EQON                  , 0x41 },
-       { STB0899_LDT                   , 0xf1 },
-       { STB0899_LDT2                  , 0xe3 },
-       { STB0899_EQUALREF              , 0xb4 },
-       { STB0899_TMGRAMP               , 0x10 },
-       { STB0899_TMGTHD                , 0x30 },
-       { STB0899_IDCCOMP               , 0xfd },
-       { STB0899_QDCCOMP               , 0xff },
-       { STB0899_POWERI                , 0x0c },
-       { STB0899_POWERQ                , 0x0f },
-       { STB0899_RCOMP                 , 0x6c },
-       { STB0899_AGCIQIN               , 0x80 },
-       { STB0899_AGC2I1                , 0x06 },
-       { STB0899_AGC2I2                , 0x00 },
-       { STB0899_TLIR                  , 0x30 },
-       { STB0899_RTF                   , 0x7f },
-       { STB0899_DSTATUS               , 0x00 },
-       { STB0899_LDI                   , 0xbc },
-       { STB0899_CFRM                  , 0xea },
-       { STB0899_CFRL                  , 0x31 },
-       { STB0899_NIRM                  , 0x2b },
-       { STB0899_NIRL                  , 0x80 },
-       { STB0899_ISYMB                 , 0x1d },
-       { STB0899_QSYMB                 , 0xa6 },
-       { STB0899_SFRH                  , 0x2f },
-       { STB0899_SFRM                  , 0x68 },
-       { STB0899_SFRL                  , 0x40 },
-       { STB0899_SFRUPH                , 0x2f },
-       { STB0899_SFRUPM                , 0x68 },
-       { STB0899_SFRUPL                , 0x40 },
-       { STB0899_EQUAI1                , 0x02 },
-       { STB0899_EQUAQ1                , 0xff },
-       { STB0899_EQUAI2                , 0x04 },
-       { STB0899_EQUAQ2                , 0x05 },
-       { STB0899_EQUAI3                , 0x02 },
-       { STB0899_EQUAQ3                , 0xfd },
-       { STB0899_EQUAI4                , 0x03 },
-       { STB0899_EQUAQ4                , 0x07 },
-       { STB0899_EQUAI5                , 0x08 },
-       { STB0899_EQUAQ5                , 0xf5 },
-       { STB0899_DSTATUS2              , 0x00 },
-       { STB0899_VSTATUS               , 0x00 },
-       { STB0899_VERROR                , 0x86 },
-       { STB0899_IQSWAP                , 0x2a },
-       { STB0899_ECNT1M                , 0x00 },
-       { STB0899_ECNT1L                , 0x00 },
-       { STB0899_ECNT2M                , 0x00 },
-       { STB0899_ECNT2L                , 0x00 },
-       { STB0899_ECNT3M                , 0x0a },
-       { STB0899_ECNT3L                , 0xad },
-       { STB0899_FECAUTO1              , 0x06 },
-       { STB0899_FECM                  , 0x01 },
-       { STB0899_VTH12                 , 0xb0 },
-       { STB0899_VTH23                 , 0x7a },
-       { STB0899_VTH34                 , 0x58 },
-       { STB0899_VTH56                 , 0x38 },
-       { STB0899_VTH67                 , 0x34 },
-       { STB0899_VTH78                 , 0x24 },
-       { STB0899_PRVIT                 , 0xff },
-       { STB0899_VITSYNC               , 0x19 },
-       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-       { STB0899_TSULC                 , 0x42 },
-       { STB0899_RSLLC                 , 0x41 },
-       { STB0899_TSLPL                 , 0x12 },
-       { STB0899_TSCFGH                , 0x0c },
-       { STB0899_TSCFGM                , 0x00 },
-       { STB0899_TSCFGL                , 0x00 },
-       { STB0899_TSOUT                 , 0x69 }, /* 0x0d for CAM */
-       { STB0899_RSSYNCDEL             , 0x00 },
-       { STB0899_TSINHDELH             , 0x02 },
-       { STB0899_TSINHDELM             , 0x00 },
-       { STB0899_TSINHDELL             , 0x00 },
-       { STB0899_TSLLSTKM              , 0x1b },
-       { STB0899_TSLLSTKL              , 0xb3 },
-       { STB0899_TSULSTKM              , 0x00 },
-       { STB0899_TSULSTKL              , 0x00 },
-       { STB0899_PCKLENUL              , 0xbc },
-       { STB0899_PCKLENLL              , 0xcc },
-       { STB0899_RSPCKLEN              , 0xbd },
-       { STB0899_TSSTATUS              , 0x90 },
-       { STB0899_ERRCTRL1              , 0xb6 },
-       { STB0899_ERRCTRL2              , 0x95 },
-       { STB0899_ERRCTRL3              , 0x8d },
-       { STB0899_DMONMSK1              , 0x27 },
-       { STB0899_DMONMSK0              , 0x03 },
-       { STB0899_DEMAPVIT              , 0x5c },
-       { STB0899_PLPARM                , 0x19 },
-       { STB0899_PDELCTRL              , 0x48 },
-       { STB0899_PDELCTRL2             , 0x00 },
-       { STB0899_BBHCTRL1              , 0x00 },
-       { STB0899_BBHCTRL2              , 0x00 },
-       { STB0899_HYSTTHRESH            , 0x77 },
-       { STB0899_MATCSTM               , 0x00 },
-       { STB0899_MATCSTL               , 0x00 },
-       { STB0899_UPLCSTM               , 0x00 },
-       { STB0899_UPLCSTL               , 0x00 },
-       { STB0899_DFLCSTM               , 0x00 },
-       { STB0899_DFLCSTL               , 0x00 },
-       { STB0899_SYNCCST               , 0x00 },
-       { STB0899_SYNCDCSTM             , 0x00 },
-       { STB0899_SYNCDCSTL             , 0x00 },
-       { STB0899_ISI_ENTRY             , 0x00 },
-       { STB0899_ISI_BIT_EN            , 0x00 },
-       { STB0899_MATSTRM               , 0xf0 },
-       { STB0899_MATSTRL               , 0x02 },
-       { STB0899_UPLSTRM               , 0x45 },
-       { STB0899_UPLSTRL               , 0x60 },
-       { STB0899_DFLSTRM               , 0xe3 },
-       { STB0899_DFLSTRL               , 0x00 },
-       { STB0899_SYNCSTR               , 0x47 },
-       { STB0899_SYNCDSTRM             , 0x05 },
-       { STB0899_SYNCDSTRL             , 0x18 },
-       { STB0899_CFGPDELSTATUS1        , 0x19 },
-       { STB0899_CFGPDELSTATUS2        , 0x2b },
-       { STB0899_BBFERRORM             , 0x00 },
-       { STB0899_BBFERRORL             , 0x01 },
-       { STB0899_UPKTERRORM            , 0x00 },
-       { STB0899_UPKTERRORL            , 0x00 },
-       { 0xffff                        , 0xff },
-};
-
-struct stb0899_config vp1041_stb0899_config = {
-       .init_dev               = vp1041_stb0899_s1_init_1,
-       .init_s2_demod          = stb0899_s2_init_2,
-       .init_s1_demod          = vp1041_stb0899_s1_init_3,
-       .init_s2_fec            = stb0899_s2_init_4,
-       .init_tst               = stb0899_s1_init_5,
-
-       .demod_address          = 0x68, /*  0xd0 >> 1 */
-
-       .xtal_freq              = 27000000,
-       .inversion              = IQ_SWAP_ON, /* 1 */
-
-       .lo_clk                 = 76500000,
-       .hi_clk                 = 99000000,
-
-       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
-       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
-       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
-       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
-       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
-       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
-       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
-       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
-       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
-
-       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
-       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
-       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
-       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
-
-       .tuner_get_frequency    = stb6100_get_frequency,
-       .tuner_set_frequency    = stb6100_set_frequency,
-       .tuner_set_bandwidth    = stb6100_set_bandwidth,
-       .tuner_get_bandwidth    = stb6100_get_bandwidth,
-       .tuner_set_rfsiggain    = NULL,
-};
-
-struct stb6100_config vp1041_stb6100_config = {
-       .tuner_address  = 0x60,
-       .refclock       = 27000000,
-};
-
-static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter     = &mantis->adapter;
-
-       int err = 0;
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               mantis_frontend_soft_reset(mantis);
-               msleep(250);
-               mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter);
-               if (mantis->fe) {
-                       dprintk(MANTIS_ERROR, 1,
-                               "found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
-                               vp1041_stb0899_config.demod_address);
-
-                       if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) {
-                               if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0))
-                                       dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
-                       }
-               } else {
-                       return -EREMOTEIO;
-               }
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-
-
-       dprintk(MANTIS_ERROR, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp1041_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_188,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp1041_frontend_init,
-       .power          = GPIF_A12,
-       .reset          = GPIF_A13,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.h b/drivers/media/dvb/mantis/mantis_vp1041.h
deleted file mode 100644 (file)
index 1ae5b3d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-       Mantis VP-1041 driver
-
-       Copyright (C) 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_VP1041_H
-#define __MANTIS_VP1041_H
-
-#include "mantis_common.h"
-
-#define MANTIS_VP_1041_DVB_S2  0x0031
-#define SKYSTAR_HD2_10         0x0001
-#define SKYSTAR_HD2_20         0x0003
-#define CINERGY_S2_PCI_HD      0x1179
-
-extern struct mantis_hwconfig vp1041_config;
-
-#endif /* __MANTIS_VP1041_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c
deleted file mode 100644 (file)
index 1ca6837..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-       Mantis VP-2033 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "tda1002x.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp2033.h"
-
-#define MANTIS_MODEL_NAME      "VP-2033"
-#define MANTIS_DEV_TYPE                "DVB-C"
-
-struct tda1002x_config vp2033_tda1002x_cu1216_config = {
-       .demod_address = 0x18 >> 1,
-       .invert = 1,
-};
-
-struct tda10023_config vp2033_tda10023_cu1216_config = {
-       .demod_address = 0x18 >> 1,
-       .invert = 1,
-};
-
-static u8 read_pwm(struct mantis_pci *mantis)
-{
-       struct i2c_adapter *adapter = &mantis->adapter;
-
-       u8 b = 0xff;
-       u8 pwm;
-       struct i2c_msg msg[] = {
-               {.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
-               {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
-       };
-
-       if ((i2c_transfer(adapter, msg, 2) != 2)
-           || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mantis_pci *mantis = fe->dvb->priv;
-       struct i2c_adapter *adapter = &mantis->adapter;
-
-       u8 buf[6];
-       struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
-       int i;
-
-#define CU1216_IF 36125000
-#define TUNER_MUL 62500
-
-       u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0xce;
-       buf[3] = (p->frequency < 150000000 ? 0x01 :
-                 p->frequency < 445000000 ? 0x02 : 0x04);
-       buf[4] = 0xde;
-       buf[5] = 0x20;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       if (i2c_transfer(adapter, &msg, 1) != 1)
-               return -EIO;
-
-       /* wait for the pll lock */
-       msg.flags = I2C_M_RD;
-       msg.len = 1;
-       for (i = 0; i < 20; i++) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
-                       break;
-
-               msleep(10);
-       }
-
-       /* switch the charge pump to the lower current */
-       msg.flags = 0;
-       msg.len = 2;
-       msg.buf = &buf[2];
-       buf[2] &= ~0x40;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       if (i2c_transfer(adapter, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter = &mantis->adapter;
-
-       int err = 0;
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               mantis_frontend_soft_reset(mantis);
-               msleep(250);
-
-               dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
-               fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
-                                    adapter,
-                                    read_pwm(mantis));
-
-               if (fe) {
-                       dprintk(MANTIS_ERROR, 1,
-                               "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
-                               vp2033_tda1002x_cu1216_config.demod_address);
-               } else {
-                       fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
-                                            adapter,
-                                            read_pwm(mantis));
-
-                       if (fe) {
-                               dprintk(MANTIS_ERROR, 1,
-                                       "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
-                                       vp2033_tda1002x_cu1216_config.demod_address);
-                       }
-               }
-
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
-                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
-               } else {
-                       return -1;
-               }
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-
-       mantis->fe = fe;
-       dprintk(MANTIS_DEBUG, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp2033_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_204,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp2033_frontend_init,
-       .power          = GPIF_A12,
-       .reset          = GPIF_A13,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/dvb/mantis/mantis_vp2033.h
deleted file mode 100644 (file)
index c55242b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Mantis VP-2033 driver
-
-       Copyright (C) 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 "mantis_common.h"
-
-#define MANTIS_VP_2033_DVB_C   0x0008
-
-extern struct mantis_hwconfig vp2033_config;
-
-#endif /* __MANTIS_VP2033_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c
deleted file mode 100644 (file)
index d480741..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-       Mantis VP-2040 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "tda1002x.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp2040.h"
-
-#define MANTIS_MODEL_NAME      "VP-2040"
-#define MANTIS_DEV_TYPE                "DVB-C"
-
-struct tda1002x_config vp2040_tda1002x_cu1216_config = {
-       .demod_address  = 0x18 >> 1,
-       .invert         = 1,
-};
-
-struct tda10023_config vp2040_tda10023_cu1216_config = {
-       .demod_address  = 0x18 >> 1,
-       .invert         = 1,
-};
-
-static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mantis_pci *mantis       = fe->dvb->priv;
-       struct i2c_adapter *adapter     = &mantis->adapter;
-
-       u8 buf[6];
-       struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
-       int i;
-
-#define CU1216_IF 36125000
-#define TUNER_MUL 62500
-
-       u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0xce;
-       buf[3] = (p->frequency < 150000000 ? 0x01 :
-                 p->frequency < 445000000 ? 0x02 : 0x04);
-       buf[4] = 0xde;
-       buf[5] = 0x20;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       if (i2c_transfer(adapter, &msg, 1) != 1)
-               return -EIO;
-
-       /* wait for the pll lock */
-       msg.flags = I2C_M_RD;
-       msg.len = 1;
-       for (i = 0; i < 20; i++) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
-                       break;
-
-               msleep(10);
-       }
-
-       /* switch the charge pump to the lower current */
-       msg.flags = 0;
-       msg.len = 2;
-       msg.buf = &buf[2];
-       buf[2] &= ~0x40;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       if (i2c_transfer(adapter, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-static u8 read_pwm(struct mantis_pci *mantis)
-{
-       struct i2c_adapter *adapter = &mantis->adapter;
-
-       u8 b = 0xff;
-       u8 pwm;
-       struct i2c_msg msg[] = {
-               {.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
-               {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
-       };
-
-       if ((i2c_transfer(adapter, msg, 2) != 2)
-           || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter = &mantis->adapter;
-
-       int err = 0;
-
-       err = mantis_frontend_power(mantis, POWER_ON);
-       if (err == 0) {
-               mantis_frontend_soft_reset(mantis);
-               msleep(250);
-
-               dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
-               fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config,
-                                    adapter,
-                                    read_pwm(mantis));
-
-               if (fe) {
-                       dprintk(MANTIS_ERROR, 1,
-                               "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
-                               vp2040_tda1002x_cu1216_config.demod_address);
-               } else {
-                       fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config,
-                                            adapter,
-                                            read_pwm(mantis));
-
-                       if (fe) {
-                               dprintk(MANTIS_ERROR, 1,
-                                       "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
-                                       vp2040_tda1002x_cu1216_config.demod_address);
-                       }
-               }
-
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
-                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
-               } else {
-                       return -1;
-               }
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-       }
-       mantis->fe = fe;
-       dprintk(MANTIS_DEBUG, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp2040_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_204,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp2040_frontend_init,
-       .power          = GPIF_A12,
-       .reset          = GPIF_A13,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.h b/drivers/media/dvb/mantis/mantis_vp2040.h
deleted file mode 100644 (file)
index d125e21..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-       Mantis VP-2040 driver
-
-       Copyright (C) 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_VP2040_H
-#define __MANTIS_VP2040_H
-
-#include "mantis_common.h"
-
-#define MANTIS_VP_2040_DVB_C   0x0043
-#define CINERGY_C              0x1178
-#define CABLESTAR_HD2          0x0002
-
-extern struct mantis_hwconfig vp2040_config;
-
-#endif /* __MANTIS_VP2040_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.c b/drivers/media/dvb/mantis/mantis_vp3028.c
deleted file mode 100644 (file)
index 4155c83..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-       Mantis VP-3028 driver
-
-       Copyright (C) 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_vp3028.h"
-
-struct zl10353_config mantis_vp3028_config = {
-       .demod_address  = 0x0f,
-};
-
-#define MANTIS_MODEL_NAME      "VP-3028"
-#define MANTIS_DEV_TYPE                "DVB-T"
-
-struct mantis_hwconfig vp3028_mantis_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_188,
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.h b/drivers/media/dvb/mantis/mantis_vp3028.h
deleted file mode 100644 (file)
index b07be6a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-       Mantis VP-3028 driver
-
-       Copyright (C) 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_VP3028_H
-#define __MANTIS_VP3028_H
-
-#include "dvb_frontend.h"
-#include "mantis_common.h"
-#include "zl10353.h"
-
-#define MANTIS_VP_3028_DVB_T   0x0028
-
-extern struct zl10353_config mantis_vp3028_config;
-extern struct mantis_hwconfig vp3028_mantis_config;
-
-#endif /* __MANTIS_VP3028_H */
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
deleted file mode 100644 (file)
index c09308c..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-       Mantis VP-3030 driver
-
-       Copyright (C) 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/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-
-#include "zl10353.h"
-#include "tda665x.h"
-#include "mantis_common.h"
-#include "mantis_ioc.h"
-#include "mantis_dvb.h"
-#include "mantis_vp3030.h"
-
-struct zl10353_config mantis_vp3030_config = {
-       .demod_address          = 0x0f,
-};
-
-struct tda665x_config env57h12d5_config = {
-       .name                   = "ENV57H12D5 (ET-50DT)",
-       .addr                   = 0x60,
-       .frequency_min          =  47000000,
-       .frequency_max          = 862000000,
-       .frequency_offst        =   3616667,
-       .ref_multiplier         = 6, /* 1/6 MHz */
-       .ref_divider            = 100000, /* 1/6 MHz */
-};
-
-#define MANTIS_MODEL_NAME      "VP-3030"
-#define MANTIS_DEV_TYPE                "DVB-T"
-
-
-static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
-{
-       struct i2c_adapter *adapter     = &mantis->adapter;
-       struct mantis_hwconfig *config  = mantis->hwconfig;
-       int err = 0;
-
-       mantis_gpio_set_bits(mantis, config->reset, 0);
-       msleep(100);
-       err = mantis_frontend_power(mantis, POWER_ON);
-       msleep(100);
-       mantis_gpio_set_bits(mantis, config->reset, 1);
-
-       if (err == 0) {
-               msleep(250);
-               dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
-               fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter);
-
-               if (!fe)
-                       return -1;
-
-               dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter);
-       } else {
-               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
-                       adapter->name,
-                       err);
-
-               return -EIO;
-
-       }
-       mantis->fe = fe;
-       dprintk(MANTIS_ERROR, 1, "Done!");
-
-       return 0;
-}
-
-struct mantis_hwconfig vp3030_config = {
-       .model_name     = MANTIS_MODEL_NAME,
-       .dev_type       = MANTIS_DEV_TYPE,
-       .ts_size        = MANTIS_TS_188,
-
-       .baud_rate      = MANTIS_BAUD_9600,
-       .parity         = MANTIS_PARITY_NONE,
-       .bytes          = 0,
-
-       .frontend_init  = vp3030_frontend_init,
-       .power          = GPIF_A12,
-       .reset          = GPIF_A13,
-
-       .i2c_mode       = MANTIS_BYTE_MODE
-};
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/dvb/mantis/mantis_vp3030.h
deleted file mode 100644 (file)
index 5f12c42..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-       Mantis VP-3030 driver
-
-       Copyright (C) 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 "mantis_common.h"
-
-#define MANTIS_VP_3030_DVB_T   0x0024
-
-extern struct mantis_hwconfig vp3030_config;
-
-#endif /* __MANTIS_VP3030_H */
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig
deleted file mode 100644 (file)
index 64c8470..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-config DVB_NGENE
-       tristate "Micronas nGene support"
-       depends on DVB_CORE && PCI && I2C
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_STV6110x if !DVB_FE_CUSTOMISE
-       select DVB_STV090x if !DVB_FE_CUSTOMISE
-       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-       select DVB_DRXK if !DVB_FE_CUSTOMISE
-       select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
-       ---help---
-         Support for Micronas PCI express cards with nGene bridge.
-
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
deleted file mode 100644 (file)
index 6399708..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile for the nGene device driver
-#
-
-ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
-
-obj-$(CONFIG_DVB_NGENE) += ngene.o
-
-ccflags-y += -Idrivers/media/dvb-core/
-ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
-
-# For the staging CI driver cxd2099
-ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
deleted file mode 100644 (file)
index a6cd695..0000000
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * ngene-cards.c: nGene PCIe bridge driver - card specific info
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
- *                         Modifications for new nGene firmware,
- *                         support for EEPROM-copying,
- *                         support for new dual DVB-S2 card prototype
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-
-#include "ngene.h"
-
-/* demods/tuners */
-#include "stv6110x.h"
-#include "stv090x.h"
-#include "lnbh24.h"
-#include "lgdt330x.h"
-#include "mt2131.h"
-#include "tda18271c2dd.h"
-#include "drxk.h"
-#include "drxd.h"
-#include "dvb-pll.h"
-
-
-/****************************************************************************/
-/* Demod/tuner attachment ***************************************************/
-/****************************************************************************/
-
-static int tuner_attach_stv6110(struct ngene_channel *chan)
-{
-       struct i2c_adapter *i2c;
-       struct stv090x_config *feconf = (struct stv090x_config *)
-               chan->dev->card_info->fe_config[chan->number];
-       struct stv6110x_config *tunerconf = (struct stv6110x_config *)
-               chan->dev->card_info->tuner_config[chan->number];
-       struct stv6110x_devctl *ctl;
-
-       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
-       if (chan->number < 2)
-               i2c = &chan->dev->channel[0].i2c_adapter;
-       else
-               i2c = &chan->dev->channel[1].i2c_adapter;
-
-       ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
-       if (ctl == NULL) {
-               printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
-               return -ENODEV;
-       }
-
-       feconf->tuner_init          = ctl->tuner_init;
-       feconf->tuner_sleep         = ctl->tuner_sleep;
-       feconf->tuner_set_mode      = ctl->tuner_set_mode;
-       feconf->tuner_set_frequency = ctl->tuner_set_frequency;
-       feconf->tuner_get_frequency = ctl->tuner_get_frequency;
-       feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-       feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-       feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
-       feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
-       feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
-       feconf->tuner_get_status    = ctl->tuner_get_status;
-
-       return 0;
-}
-
-
-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct ngene_channel *chan = fe->sec_priv;
-       int status;
-
-       if (enable) {
-               down(&chan->dev->pll_mutex);
-               status = chan->gate_ctrl(fe, 1);
-       } else {
-               status = chan->gate_ctrl(fe, 0);
-               up(&chan->dev->pll_mutex);
-       }
-       return status;
-}
-
-static int tuner_attach_tda18271(struct ngene_channel *chan)
-{
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe;
-
-       i2c = &chan->dev->channel[0].i2c_adapter;
-       if (chan->fe->ops.i2c_gate_ctrl)
-               chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
-       fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60);
-       if (chan->fe->ops.i2c_gate_ctrl)
-               chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
-       if (!fe) {
-               printk(KERN_ERR "No TDA18271 found!\n");
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int tuner_attach_probe(struct ngene_channel *chan)
-{
-       if (chan->demod_type == 0)
-               return tuner_attach_stv6110(chan);
-       if (chan->demod_type == 1)
-               return tuner_attach_tda18271(chan);
-       return -EINVAL;
-}
-
-static int demod_attach_stv0900(struct ngene_channel *chan)
-{
-       struct i2c_adapter *i2c;
-       struct stv090x_config *feconf = (struct stv090x_config *)
-               chan->dev->card_info->fe_config[chan->number];
-
-       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
-       /* Note: Both adapters share the same i2c bus, but the demod     */
-       /*       driver requires that each demod has its own i2c adapter */
-       if (chan->number < 2)
-               i2c = &chan->dev->channel[0].i2c_adapter;
-       else
-               i2c = &chan->dev->channel[1].i2c_adapter;
-
-       chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
-                       (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
-                                               : STV090x_DEMODULATOR_1);
-       if (chan->fe == NULL) {
-               printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
-               return -ENODEV;
-       }
-
-       /* store channel info */
-       if (feconf->tuner_i2c_lock)
-               chan->fe->analog_demod_priv = chan;
-
-       if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
-                       0, chan->dev->card_info->lnb[chan->number])) {
-               printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
-               dvb_frontend_detach(chan->fe);
-               chan->fe = NULL;
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
-{
-       struct ngene_channel *chan = fe->analog_demod_priv;
-
-       if (lock)
-               down(&chan->dev->pll_mutex);
-       else
-               up(&chan->dev->pll_mutex);
-}
-
-static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
-{
-       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
-                                  .buf  = val,  .len   = 1 } };
-       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
-}
-
-static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
-                         u16 reg, u8 *val)
-{
-       u8 msg[2] = {reg>>8, reg&0xff};
-       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
-                                  .buf  = msg, .len   = 2},
-                                 {.addr = adr, .flags = I2C_M_RD,
-                                  .buf  = val, .len   = 1} };
-       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
-}
-
-static int port_has_stv0900(struct i2c_adapter *i2c, int port)
-{
-       u8 val;
-       if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0)
-               return 0;
-       return 1;
-}
-
-static int port_has_drxk(struct i2c_adapter *i2c, int port)
-{
-       u8 val;
-
-       if (i2c_read(i2c, 0x29+port, &val) < 0)
-               return 0;
-       return 1;
-}
-
-static int demod_attach_drxk(struct ngene_channel *chan,
-                            struct i2c_adapter *i2c)
-{
-       struct drxk_config config;
-
-       memset(&config, 0, sizeof(config));
-       config.microcode_name = "drxk_a3.mc";
-       config.qam_demod_parameter_count = 4;
-       config.adr = 0x29 + (chan->number ^ 2);
-
-       chan->fe = dvb_attach(drxk_attach, &config, i2c);
-       if (!chan->fe) {
-               printk(KERN_ERR "No DRXK found!\n");
-               return -ENODEV;
-       }
-       chan->fe->sec_priv = chan;
-       chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
-       chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
-       return 0;
-}
-
-static int cineS2_probe(struct ngene_channel *chan)
-{
-       struct i2c_adapter *i2c;
-       struct stv090x_config *fe_conf;
-       u8 buf[3];
-       struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
-       int rc;
-
-       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
-       if (chan->number < 2)
-               i2c = &chan->dev->channel[0].i2c_adapter;
-       else
-               i2c = &chan->dev->channel[1].i2c_adapter;
-
-       if (port_has_stv0900(i2c, chan->number)) {
-               chan->demod_type = 0;
-               fe_conf = chan->dev->card_info->fe_config[chan->number];
-               /* demod found, attach it */
-               rc = demod_attach_stv0900(chan);
-               if (rc < 0 || chan->number < 2)
-                       return rc;
-
-               /* demod #2: reprogram outputs DPN1 & DPN2 */
-               i2c_msg.addr = fe_conf->address;
-               i2c_msg.len = 3;
-               buf[0] = 0xf1;
-               switch (chan->number) {
-               case 2:
-                       buf[1] = 0x5c;
-                       buf[2] = 0xc2;
-                       break;
-               case 3:
-                       buf[1] = 0x61;
-                       buf[2] = 0xcc;
-                       break;
-               default:
-                       return -ENODEV;
-               }
-               rc = i2c_transfer(i2c, &i2c_msg, 1);
-               if (rc != 1) {
-                       printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
-                       return -EIO;
-               }
-       } else if (port_has_drxk(i2c, chan->number^2)) {
-               chan->demod_type = 1;
-               demod_attach_drxk(chan, i2c);
-       } else {
-               printk(KERN_ERR "No demod found on chan %d\n", chan->number);
-               return -ENODEV;
-       }
-       return 0;
-}
-
-
-static struct lgdt330x_config aver_m780 = {
-       .demod_address = 0xb2 >> 1,
-       .demod_chip    = LGDT3303,
-       .serial_mpeg   = 0x00, /* PARALLEL */
-       .clock_polarity_flip = 1,
-};
-
-static struct mt2131_config m780_tunerconfig = {
-       0xc0 >> 1
-};
-
-/* A single func to attach the demo and tuner, rather than
- * use two sep funcs like the current design mandates.
- */
-static int demod_attach_lg330x(struct ngene_channel *chan)
-{
-       chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter);
-       if (chan->fe == NULL) {
-               printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n");
-               return -ENODEV;
-       }
-
-       dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter,
-                  &m780_tunerconfig, 0);
-
-       return (chan->fe) ? 0 : -ENODEV;
-}
-
-static int demod_attach_drxd(struct ngene_channel *chan)
-{
-       struct drxd_config *feconf;
-
-       feconf = chan->dev->card_info->fe_config[chan->number];
-
-       chan->fe = dvb_attach(drxd_attach, feconf, chan,
-                       &chan->i2c_adapter, &chan->dev->pci_dev->dev);
-       if (!chan->fe) {
-               pr_err("No DRXD found!\n");
-               return -ENODEV;
-       }
-
-       if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address,
-                       &chan->i2c_adapter,
-                       feconf->pll_type)) {
-               pr_err("No pll(%d) found!\n", feconf->pll_type);
-               return -ENODEV;
-       }
-       return 0;
-}
-
-/****************************************************************************/
-/* EEPROM TAGS **************************************************************/
-/****************************************************************************/
-
-#define MICNG_EE_START      0x0100
-#define MICNG_EE_END        0x0FF0
-
-#define MICNG_EETAG_END0    0x0000
-#define MICNG_EETAG_END1    0xFFFF
-
-/* 0x0001 - 0x000F reserved for housekeeping */
-/* 0xFFFF - 0xFFFE reserved for housekeeping */
-
-/* Micronas assigned tags
-   EEProm tags for hardware support */
-
-#define MICNG_EETAG_DRXD1_OSCDEVIATION  0x1000  /* 2 Bytes data */
-#define MICNG_EETAG_DRXD2_OSCDEVIATION  0x1001  /* 2 Bytes data */
-
-#define MICNG_EETAG_MT2060_1_1STIF      0x1100  /* 2 Bytes data */
-#define MICNG_EETAG_MT2060_2_1STIF      0x1101  /* 2 Bytes data */
-
-/* Tag range for OEMs */
-
-#define MICNG_EETAG_OEM_FIRST  0xC000
-#define MICNG_EETAG_OEM_LAST   0xFFEF
-
-static int i2c_write_eeprom(struct i2c_adapter *adapter,
-                           u8 adr, u16 reg, u8 data)
-{
-       u8 m[3] = {(reg >> 8), (reg & 0xff), data};
-       struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m,
-                             .len = sizeof(m)};
-
-       if (i2c_transfer(adapter, &msg, 1) != 1) {
-               pr_err(DEVICE_NAME ": Error writing EEPROM!\n");
-               return -EIO;
-       }
-       return 0;
-}
-
-static int i2c_read_eeprom(struct i2c_adapter *adapter,
-                          u8 adr, u16 reg, u8 *data, int len)
-{
-       u8 msg[2] = {(reg >> 8), (reg & 0xff)};
-       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
-                                  .buf = msg, .len = 2 },
-                                 {.addr = adr, .flags = I2C_M_RD,
-                                  .buf = data, .len = len} };
-
-       if (i2c_transfer(adapter, msgs, 2) != 2) {
-               pr_err(DEVICE_NAME ": Error reading EEPROM\n");
-               return -EIO;
-       }
-       return 0;
-}
-
-static int ReadEEProm(struct i2c_adapter *adapter,
-                     u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
-{
-       int status = 0;
-       u16 Addr = MICNG_EE_START, Length, tag = 0;
-       u8  EETag[3];
-
-       while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
-               if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
-                       return -1;
-               tag = (EETag[0] << 8) | EETag[1];
-               if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
-                       return -1;
-               if (tag == Tag)
-                       break;
-               Addr += sizeof(u16) + 1 + EETag[2];
-       }
-       if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
-               pr_err(DEVICE_NAME
-                      ": Reached EOEE @ Tag = %04x Length = %3d\n",
-                      tag, EETag[2]);
-               return -1;
-       }
-       Length = EETag[2];
-       if (Length > MaxLen)
-               Length = (u16) MaxLen;
-       if (Length > 0) {
-               Addr += sizeof(u16) + 1;
-               status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
-               if (!status) {
-                       *pLength = EETag[2];
-                       if (Length < EETag[2])
-                               ; /*status=STATUS_BUFFER_OVERFLOW; */
-               }
-       }
-       return status;
-}
-
-static int WriteEEProm(struct i2c_adapter *adapter,
-                      u16 Tag, u32 Length, u8 *data)
-{
-       int status = 0;
-       u16 Addr = MICNG_EE_START;
-       u8 EETag[3];
-       u16 tag = 0;
-       int retry, i;
-
-       while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
-               if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
-                       return -1;
-               tag = (EETag[0] << 8) | EETag[1];
-               if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
-                       return -1;
-               if (tag == Tag)
-                       break;
-               Addr += sizeof(u16) + 1 + EETag[2];
-       }
-       if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
-               pr_err(DEVICE_NAME
-                      ": Reached EOEE @ Tag = %04x Length = %3d\n",
-                      tag, EETag[2]);
-               return -1;
-       }
-
-       if (Length > EETag[2])
-               return -EINVAL;
-       /* Note: We write the data one byte at a time to avoid
-          issues with page sizes. (which are different for
-          each manufacture and eeprom size)
-        */
-       Addr += sizeof(u16) + 1;
-       for (i = 0; i < Length; i++, Addr++) {
-               status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
-
-               if (status)
-                       break;
-
-               /* Poll for finishing write cycle */
-               retry = 10;
-               while (retry) {
-                       u8 Tmp;
-
-                       msleep(50);
-                       status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
-                       if (status)
-                               break;
-                       if (Tmp != data[i])
-                               pr_err(DEVICE_NAME
-                                      "eeprom write error\n");
-                       retry -= 1;
-               }
-               if (status) {
-                       pr_err(DEVICE_NAME
-                              ": Timeout polling eeprom\n");
-                       break;
-               }
-       }
-       return status;
-}
-
-static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
-{
-       int stat;
-       u8 buf[2];
-       u32 len = 0;
-
-       stat = ReadEEProm(adapter, tag, 2, buf, &len);
-       if (stat)
-               return stat;
-       if (len != 2)
-               return -EINVAL;
-
-       *data = (buf[0] << 8) | buf[1];
-       return 0;
-}
-
-static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
-{
-       int stat;
-       u8 buf[2];
-
-       buf[0] = data >> 8;
-       buf[1] = data & 0xff;
-       stat = WriteEEProm(adapter, tag, 2, buf);
-       if (stat)
-               return stat;
-       return 0;
-}
-
-static s16 osc_deviation(void *priv, s16 deviation, int flag)
-{
-       struct ngene_channel *chan = priv;
-       struct i2c_adapter *adap = &chan->i2c_adapter;
-       u16 data = 0;
-
-       if (flag) {
-               data = (u16) deviation;
-               pr_info(DEVICE_NAME ": write deviation %d\n",
-                      deviation);
-               eeprom_write_ushort(adap, 0x1000 + chan->number, data);
-       } else {
-               if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
-                       data = 0;
-               pr_info(DEVICE_NAME ": read deviation %d\n",
-                      (s16) data);
-       }
-
-       return (s16) data;
-}
-
-/****************************************************************************/
-/* Switch control (I2C gates, etc.) *****************************************/
-/****************************************************************************/
-
-
-static struct stv090x_config fe_cineS2 = {
-       .device         = STV0900,
-       .demod_mode     = STV090x_DUAL,
-       .clk_mode       = STV090x_CLK_EXT,
-
-       .xtal           = 27000000,
-       .address        = 0x68,
-
-       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-
-       .repeater_level = STV090x_RPTLEVEL_16,
-
-       .adc1_range     = STV090x_ADC_1Vpp,
-       .adc2_range     = STV090x_ADC_1Vpp,
-
-       .diseqc_envelope_mode = true,
-
-       .tuner_i2c_lock = cineS2_tuner_i2c_lock,
-};
-
-static struct stv090x_config fe_cineS2_2 = {
-       .device         = STV0900,
-       .demod_mode     = STV090x_DUAL,
-       .clk_mode       = STV090x_CLK_EXT,
-
-       .xtal           = 27000000,
-       .address        = 0x69,
-
-       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
-
-       .repeater_level = STV090x_RPTLEVEL_16,
-
-       .adc1_range     = STV090x_ADC_1Vpp,
-       .adc2_range     = STV090x_ADC_1Vpp,
-
-       .diseqc_envelope_mode = true,
-
-       .tuner_i2c_lock = cineS2_tuner_i2c_lock,
-};
-
-static struct stv6110x_config tuner_cineS2_0 = {
-       .addr   = 0x60,
-       .refclk = 27000000,
-       .clk_div = 1,
-};
-
-static struct stv6110x_config tuner_cineS2_1 = {
-       .addr   = 0x63,
-       .refclk = 27000000,
-       .clk_div = 1,
-};
-
-static struct ngene_info ngene_info_cineS2 = {
-       .type           = NGENE_SIDEWINDER,
-       .name           = "Linux4Media cineS2 DVB-S2 Twin Tuner",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
-       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900},
-       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110},
-       .fe_config      = {&fe_cineS2, &fe_cineS2},
-       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1},
-       .lnb            = {0x0b, 0x08},
-       .tsf            = {3, 3},
-       .fw_version     = 18,
-       .msi_supported  = true,
-};
-
-static struct ngene_info ngene_info_satixS2 = {
-       .type           = NGENE_SIDEWINDER,
-       .name           = "Mystique SaTiX-S2 Dual",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
-       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900},
-       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110},
-       .fe_config      = {&fe_cineS2, &fe_cineS2},
-       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1},
-       .lnb            = {0x0b, 0x08},
-       .tsf            = {3, 3},
-       .fw_version     = 18,
-       .msi_supported  = true,
-};
-
-static struct ngene_info ngene_info_satixS2v2 = {
-       .type           = NGENE_SIDEWINDER,
-       .name           = "Mystique SaTiX-S2 Dual (v2)",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
-                          NGENE_IO_TSOUT},
-       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
-       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
-       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
-       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
-       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
-       .tsf            = {3, 3},
-       .fw_version     = 18,
-       .msi_supported  = true,
-};
-
-static struct ngene_info ngene_info_cineS2v5 = {
-       .type           = NGENE_SIDEWINDER,
-       .name           = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
-                          NGENE_IO_TSOUT},
-       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
-       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
-       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
-       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
-       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
-       .tsf            = {3, 3},
-       .fw_version     = 18,
-       .msi_supported  = true,
-};
-
-
-static struct ngene_info ngene_info_duoFlex = {
-       .type           = NGENE_SIDEWINDER,
-       .name           = "Digital Devices DuoFlex PCIe or miniPCIe",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
-                          NGENE_IO_TSOUT},
-       .demod_attach   = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
-       .tuner_attach   = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe},
-       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
-       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
-       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
-       .tsf            = {3, 3},
-       .fw_version     = 18,
-       .msi_supported  = true,
-};
-
-static struct ngene_info ngene_info_m780 = {
-       .type           = NGENE_APP,
-       .name           = "Aver M780 ATSC/QAM-B",
-
-       /* Channel 0 is analog, which is currently unsupported */
-       .io_type        = { NGENE_IO_NONE, NGENE_IO_TSIN },
-       .demod_attach   = { NULL, demod_attach_lg330x },
-
-       /* Ensure these are NULL else the frame will call them (as funcs) */
-       .tuner_attach   = { 0, 0, 0, 0 },
-       .fe_config      = { NULL, &aver_m780 },
-       .avf            = { 0 },
-
-       /* A custom electrical interface config for the demod to bridge */
-       .tsf            = { 4, 4 },
-       .fw_version     = 15,
-};
-
-static struct drxd_config fe_terratec_dvbt_0 = {
-       .index          = 0,
-       .demod_address  = 0x70,
-       .demod_revision = 0xa2,
-       .demoda_address = 0x00,
-       .pll_address    = 0x60,
-       .pll_type       = DVB_PLL_THOMSON_DTT7520X,
-       .clock          = 20000,
-       .osc_deviation  = osc_deviation,
-};
-
-static struct drxd_config fe_terratec_dvbt_1 = {
-       .index          = 1,
-       .demod_address  = 0x71,
-       .demod_revision = 0xa2,
-       .demoda_address = 0x00,
-       .pll_address    = 0x60,
-       .pll_type       = DVB_PLL_THOMSON_DTT7520X,
-       .clock          = 20000,
-       .osc_deviation  = osc_deviation,
-};
-
-static struct ngene_info ngene_info_terratec = {
-       .type           = NGENE_TERRATEC,
-       .name           = "Terratec Integra/Cinergy2400i Dual DVB-T",
-       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
-       .demod_attach   = {demod_attach_drxd, demod_attach_drxd},
-       .fe_config      = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
-       .i2c_access     = 1,
-};
-
-/****************************************************************************/
-
-
-
-/****************************************************************************/
-/* PCI Subsystem ID *********************************************************/
-/****************************************************************************/
-
-#define NGENE_ID(_subvend, _subdev, _driverdata) { \
-       .vendor = NGENE_VID, .device = NGENE_PID, \
-       .subvendor = _subvend, .subdevice = _subdev, \
-       .driver_data = (unsigned long) &_driverdata }
-
-/****************************************************************************/
-
-static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
-       NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
-       NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
-       NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
-       NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
-       NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
-       NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex),
-       NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
-       NGENE_ID(0x1461, 0x062e, ngene_info_m780),
-       NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
-       {0}
-};
-MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
-
-/****************************************************************************/
-/* Init/Exit ****************************************************************/
-/****************************************************************************/
-
-static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
-                                            enum pci_channel_state state)
-{
-       printk(KERN_ERR DEVICE_NAME ": PCI error\n");
-       if (state == pci_channel_io_perm_failure)
-               return PCI_ERS_RESULT_DISCONNECT;
-       if (state == pci_channel_io_frozen)
-               return PCI_ERS_RESULT_NEED_RESET;
-       return PCI_ERS_RESULT_CAN_RECOVER;
-}
-
-static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
-{
-       printk(KERN_INFO DEVICE_NAME ": link reset\n");
-       return 0;
-}
-
-static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
-{
-       printk(KERN_INFO DEVICE_NAME ": slot reset\n");
-       return 0;
-}
-
-static void ngene_resume(struct pci_dev *dev)
-{
-       printk(KERN_INFO DEVICE_NAME ": resume\n");
-}
-
-static struct pci_error_handlers ngene_errors = {
-       .error_detected = ngene_error_detected,
-       .link_reset = ngene_link_reset,
-       .slot_reset = ngene_slot_reset,
-       .resume = ngene_resume,
-};
-
-static struct pci_driver ngene_pci_driver = {
-       .name        = "ngene",
-       .id_table    = ngene_id_tbl,
-       .probe       = ngene_probe,
-       .remove      = __devexit_p(ngene_remove),
-       .err_handler = &ngene_errors,
-       .shutdown    = ngene_shutdown,
-};
-
-static __init int module_init_ngene(void)
-{
-       printk(KERN_INFO
-              "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
-       return pci_register_driver(&ngene_pci_driver);
-}
-
-static __exit void module_exit_ngene(void)
-{
-       pci_unregister_driver(&ngene_pci_driver);
-}
-
-module_init(module_init_ngene);
-module_exit(module_exit_ngene);
-
-MODULE_DESCRIPTION("nGene");
-MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
deleted file mode 100644 (file)
index c8e0d5b..0000000
+++ /dev/null
@@ -1,1707 +0,0 @@
-/*
- * ngene.c: nGene PCIe bridge driver
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
- *                         Modifications for new nGene firmware,
- *                         support for EEPROM-copying,
- *                         support for new dual DVB-S2 card prototype
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/poll.h>
-#include <linux/io.h>
-#include <asm/div64.h>
-#include <linux/pci.h>
-#include <linux/timer.h>
-#include <linux/byteorder/generic.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-
-#include "ngene.h"
-
-static int one_adapter;
-module_param(one_adapter, int, 0444);
-MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
-
-static int shutdown_workaround;
-module_param(shutdown_workaround, int, 0644);
-MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets.");
-
-static int debug;
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "Print debugging information.");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk        if (debug) printk
-
-#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
-#define ngwritel(dat, adr)         writel((dat), (char *)(dev->iomem + (adr)))
-#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
-#define ngreadl(adr)               readl(dev->iomem + (adr))
-#define ngreadb(adr)               readb(dev->iomem + (adr))
-#define ngcpyto(adr, src, count)   memcpy_toio((char *) \
-                                  (dev->iomem + (adr)), (src), (count))
-#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \
-                                  (dev->iomem + (adr)), (count))
-
-/****************************************************************************/
-/* nGene interrupt handler **************************************************/
-/****************************************************************************/
-
-static void event_tasklet(unsigned long data)
-{
-       struct ngene *dev = (struct ngene *)data;
-
-       while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) {
-               struct EVENT_BUFFER Event =
-                       dev->EventQueue[dev->EventQueueReadIndex];
-               dev->EventQueueReadIndex =
-                       (dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1);
-
-               if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify))
-                       dev->TxEventNotify(dev, Event.TimeStamp);
-               if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify))
-                       dev->RxEventNotify(dev, Event.TimeStamp,
-                                          Event.RXCharacter);
-       }
-}
-
-static void demux_tasklet(unsigned long data)
-{
-       struct ngene_channel *chan = (struct ngene_channel *)data;
-       struct SBufferHeader *Cur = chan->nextBuffer;
-
-       spin_lock_irq(&chan->state_lock);
-
-       while (Cur->ngeneBuffer.SR.Flags & 0x80) {
-               if (chan->mode & NGENE_IO_TSOUT) {
-                       u32 Flags = chan->DataFormatFlags;
-                       if (Cur->ngeneBuffer.SR.Flags & 0x20)
-                               Flags |= BEF_OVERFLOW;
-                       if (chan->pBufferExchange) {
-                               if (!chan->pBufferExchange(chan,
-                                                          Cur->Buffer1,
-                                                          chan->Capture1Length,
-                                                          Cur->ngeneBuffer.SR.
-                                                          Clock, Flags)) {
-                                       /*
-                                          We didn't get data
-                                          Clear in service flag to make sure we
-                                          get called on next interrupt again.
-                                          leave fill/empty (0x80) flag alone
-                                          to avoid hardware running out of
-                                          buffers during startup, we hold only
-                                          in run state ( the source may be late
-                                          delivering data )
-                                       */
-
-                                       if (chan->HWState == HWSTATE_RUN) {
-                                               Cur->ngeneBuffer.SR.Flags &=
-                                                       ~0x40;
-                                               break;
-                                               /* Stop processing stream */
-                                       }
-                               } else {
-                                       /* We got a valid buffer,
-                                          so switch to run state */
-                                       chan->HWState = HWSTATE_RUN;
-                               }
-                       } else {
-                               printk(KERN_ERR DEVICE_NAME ": OOPS\n");
-                               if (chan->HWState == HWSTATE_RUN) {
-                                       Cur->ngeneBuffer.SR.Flags &= ~0x40;
-                                       break;  /* Stop processing stream */
-                               }
-                       }
-                       if (chan->AudioDTOUpdated) {
-                               printk(KERN_INFO DEVICE_NAME
-                                      ": Update AudioDTO = %d\n",
-                                      chan->AudioDTOValue);
-                               Cur->ngeneBuffer.SR.DTOUpdate =
-                                       chan->AudioDTOValue;
-                               chan->AudioDTOUpdated = 0;
-                       }
-               } else {
-                       if (chan->HWState == HWSTATE_RUN) {
-                               u32 Flags = chan->DataFormatFlags;
-                               IBufferExchange *exch1 = chan->pBufferExchange;
-                               IBufferExchange *exch2 = chan->pBufferExchange2;
-                               if (Cur->ngeneBuffer.SR.Flags & 0x01)
-                                       Flags |= BEF_EVEN_FIELD;
-                               if (Cur->ngeneBuffer.SR.Flags & 0x20)
-                                       Flags |= BEF_OVERFLOW;
-                               spin_unlock_irq(&chan->state_lock);
-                               if (exch1)
-                                       exch1(chan, Cur->Buffer1,
-                                               chan->Capture1Length,
-                                               Cur->ngeneBuffer.SR.Clock,
-                                               Flags);
-                               if (exch2)
-                                       exch2(chan, Cur->Buffer2,
-                                               chan->Capture2Length,
-                                               Cur->ngeneBuffer.SR.Clock,
-                                               Flags);
-                               spin_lock_irq(&chan->state_lock);
-                       } else if (chan->HWState != HWSTATE_STOP)
-                               chan->HWState = HWSTATE_RUN;
-               }
-               Cur->ngeneBuffer.SR.Flags = 0x00;
-               Cur = Cur->Next;
-       }
-       chan->nextBuffer = Cur;
-
-       spin_unlock_irq(&chan->state_lock);
-}
-
-static irqreturn_t irq_handler(int irq, void *dev_id)
-{
-       struct ngene *dev = (struct ngene *)dev_id;
-       u32 icounts = 0;
-       irqreturn_t rc = IRQ_NONE;
-       u32 i = MAX_STREAM;
-       u8 *tmpCmdDoneByte;
-
-       if (dev->BootFirmware) {
-               icounts = ngreadl(NGENE_INT_COUNTS);
-               if (icounts != dev->icounts) {
-                       ngwritel(0, FORCE_NMI);
-                       dev->cmd_done = 1;
-                       wake_up(&dev->cmd_wq);
-                       dev->icounts = icounts;
-                       rc = IRQ_HANDLED;
-               }
-               return rc;
-       }
-
-       ngwritel(0, FORCE_NMI);
-
-       spin_lock(&dev->cmd_lock);
-       tmpCmdDoneByte = dev->CmdDoneByte;
-       if (tmpCmdDoneByte &&
-           (*tmpCmdDoneByte ||
-           (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) {
-               dev->CmdDoneByte = NULL;
-               dev->cmd_done = 1;
-               wake_up(&dev->cmd_wq);
-               rc = IRQ_HANDLED;
-       }
-       spin_unlock(&dev->cmd_lock);
-
-       if (dev->EventBuffer->EventStatus & 0x80) {
-               u8 nextWriteIndex =
-                       (dev->EventQueueWriteIndex + 1) &
-                       (EVENT_QUEUE_SIZE - 1);
-               if (nextWriteIndex != dev->EventQueueReadIndex) {
-                       dev->EventQueue[dev->EventQueueWriteIndex] =
-                               *(dev->EventBuffer);
-                       dev->EventQueueWriteIndex = nextWriteIndex;
-               } else {
-                       printk(KERN_ERR DEVICE_NAME ": event overflow\n");
-                       dev->EventQueueOverflowCount += 1;
-                       dev->EventQueueOverflowFlag = 1;
-               }
-               dev->EventBuffer->EventStatus &= ~0x80;
-               tasklet_schedule(&dev->event_tasklet);
-               rc = IRQ_HANDLED;
-       }
-
-       while (i > 0) {
-               i--;
-               spin_lock(&dev->channel[i].state_lock);
-               /* if (dev->channel[i].State>=KSSTATE_RUN) { */
-               if (dev->channel[i].nextBuffer) {
-                       if ((dev->channel[i].nextBuffer->
-                            ngeneBuffer.SR.Flags & 0xC0) == 0x80) {
-                               dev->channel[i].nextBuffer->
-                                       ngeneBuffer.SR.Flags |= 0x40;
-                               tasklet_schedule(
-                                       &dev->channel[i].demux_tasklet);
-                               rc = IRQ_HANDLED;
-                       }
-               }
-               spin_unlock(&dev->channel[i].state_lock);
-       }
-
-       /* Request might have been processed by a previous call. */
-       return IRQ_HANDLED;
-}
-
-/****************************************************************************/
-/* nGene command interface **************************************************/
-/****************************************************************************/
-
-static void dump_command_io(struct ngene *dev)
-{
-       u8 buf[8], *b;
-
-       ngcpyfrom(buf, HOST_TO_NGENE, 8);
-       printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf);
-
-       ngcpyfrom(buf, NGENE_TO_HOST, 8);
-       printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf);
-
-       b = dev->hosttongene;
-       printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b);
-
-       b = dev->ngenetohost;
-       printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b);
-}
-
-static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
-{
-       int ret;
-       u8 *tmpCmdDoneByte;
-
-       dev->cmd_done = 0;
-
-       if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) {
-               dev->BootFirmware = 1;
-               dev->icounts = ngreadl(NGENE_INT_COUNTS);
-               ngwritel(0, NGENE_COMMAND);
-               ngwritel(0, NGENE_COMMAND_HI);
-               ngwritel(0, NGENE_STATUS);
-               ngwritel(0, NGENE_STATUS_HI);
-               ngwritel(0, NGENE_EVENT);
-               ngwritel(0, NGENE_EVENT_HI);
-       } else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) {
-               u64 fwio = dev->PAFWInterfaceBuffer;
-
-               ngwritel(fwio & 0xffffffff, NGENE_COMMAND);
-               ngwritel(fwio >> 32, NGENE_COMMAND_HI);
-               ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS);
-               ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI);
-               ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT);
-               ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI);
-       }
-
-       memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2);
-
-       if (dev->BootFirmware)
-               ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2);
-
-       spin_lock_irq(&dev->cmd_lock);
-       tmpCmdDoneByte = dev->ngenetohost + com->out_len;
-       if (!com->out_len)
-               tmpCmdDoneByte++;
-       *tmpCmdDoneByte = 0;
-       dev->ngenetohost[0] = 0;
-       dev->ngenetohost[1] = 0;
-       dev->CmdDoneByte = tmpCmdDoneByte;
-       spin_unlock_irq(&dev->cmd_lock);
-
-       /* Notify 8051. */
-       ngwritel(1, FORCE_INT);
-
-       ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ);
-       if (!ret) {
-               /*ngwritel(0, FORCE_NMI);*/
-
-               printk(KERN_ERR DEVICE_NAME
-                      ": Command timeout cmd=%02x prev=%02x\n",
-                      com->cmd.hdr.Opcode, dev->prev_cmd);
-               dump_command_io(dev);
-               return -1;
-       }
-       if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH)
-               dev->BootFirmware = 0;
-
-       dev->prev_cmd = com->cmd.hdr.Opcode;
-
-       if (!com->out_len)
-               return 0;
-
-       memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len);
-
-       return 0;
-}
-
-int ngene_command(struct ngene *dev, struct ngene_command *com)
-{
-       int result;
-
-       down(&dev->cmd_mutex);
-       result = ngene_command_mutex(dev, com);
-       up(&dev->cmd_mutex);
-       return result;
-}
-
-
-static int ngene_command_load_firmware(struct ngene *dev,
-                                      u8 *ngene_fw, u32 size)
-{
-#define FIRSTCHUNK (1024)
-       u32 cleft;
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE;
-       com.cmd.hdr.Length = 0;
-       com.in_len = 0;
-       com.out_len = 0;
-
-       ngene_command(dev, &com);
-
-       cleft = (size + 3) & ~3;
-       if (cleft > FIRSTCHUNK) {
-               ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK,
-                       cleft - FIRSTCHUNK);
-               cleft = FIRSTCHUNK;
-       }
-       ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft);
-
-       memset(&com, 0, sizeof(struct ngene_command));
-       com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH;
-       com.cmd.hdr.Length = 4;
-       com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA;
-       com.cmd.FWLoadFinish.Length = (unsigned short)cleft;
-       com.in_len = 4;
-       com.out_len = 0;
-
-       return ngene_command(dev, &com);
-}
-
-
-static int ngene_command_config_buf(struct ngene *dev, u8 config)
-{
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER;
-       com.cmd.hdr.Length = 1;
-       com.cmd.ConfigureBuffers.config = config;
-       com.in_len = 1;
-       com.out_len = 0;
-
-       if (ngene_command(dev, &com) < 0)
-               return -EIO;
-       return 0;
-}
-
-static int ngene_command_config_free_buf(struct ngene *dev, u8 *config)
-{
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER;
-       com.cmd.hdr.Length = 6;
-       memcpy(&com.cmd.ConfigureBuffers.config, config, 6);
-       com.in_len = 6;
-       com.out_len = 0;
-
-       if (ngene_command(dev, &com) < 0)
-               return -EIO;
-
-       return 0;
-}
-
-int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
-{
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN;
-       com.cmd.hdr.Length = 1;
-       com.cmd.SetGpioPin.select = select | (level << 7);
-       com.in_len = 1;
-       com.out_len = 0;
-
-       return ngene_command(dev, &com);
-}
-
-
-/*
- 02000640 is sample on rising edge.
- 02000740 is sample on falling edge.
- 02000040 is ignore "valid" signal
-
- 0: FD_CTL1 Bit 7,6 must be 0,1
-    7   disable(fw controlled)
-    6   0-AUX,1-TS
-    5   0-par,1-ser
-    4   0-lsb/1-msb
-    3,2 reserved
-    1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both
- 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge
- 2: FD_STA is read-only. 0-sync
- 3: FD_INSYNC is number of 47s to trigger "in sync".
- 4: FD_OUTSYNC is number of 47s to trigger "out of sync".
- 5: FD_MAXBYTE1 is low-order of bytes per packet.
- 6: FD_MAXBYTE2 is high-order of bytes per packet.
- 7: Top byte is unused.
-*/
-
-/****************************************************************************/
-
-static u8 TSFeatureDecoderSetup[8 * 5] = {
-       0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,
-       0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */
-       0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */
-       0x72, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */
-       0x40, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* LGDT3303 */
-};
-
-/* Set NGENE I2S Config to 16 bit packed */
-static u8 I2SConfiguration[] = {
-       0x00, 0x10, 0x00, 0x00,
-       0x80, 0x10, 0x00, 0x00,
-};
-
-static u8 SPDIFConfiguration[10] = {
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Set NGENE I2S Config to transport stream compatible mode */
-
-static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 };
-
-static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 };
-
-static u8 ITUDecoderSetup[4][16] = {
-       {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20,  /* SDTV */
-        0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00},
-       {0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,
-        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
-       {0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00,  /* HDTV 1080i50 */
-        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
-       {0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,  /* HDTV 1080i60 */
-        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
-};
-
-/*
- * 50 48 60 gleich
- * 27p50 9f 00 22 80 42 69 18 ...
- * 27p60 93 00 22 80 82 69 1c ...
- */
-
-/* Maxbyte to 1144 (for raw data) */
-static u8 ITUFeatureDecoderSetup[8] = {
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00
-};
-
-void FillTSBuffer(void *Buffer, int Length, u32 Flags)
-{
-       u32 *ptr = Buffer;
-
-       memset(Buffer, TS_FILLER, Length);
-       while (Length > 0) {
-               if (Flags & DF_SWAP32)
-                       *ptr = 0x471FFF10;
-               else
-                       *ptr = 0x10FF1F47;
-               ptr += (188 / 4);
-               Length -= 188;
-       }
-}
-
-
-static void flush_buffers(struct ngene_channel *chan)
-{
-       u8 val;
-
-       do {
-               msleep(1);
-               spin_lock_irq(&chan->state_lock);
-               val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80;
-               spin_unlock_irq(&chan->state_lock);
-       } while (val);
-}
-
-static void clear_buffers(struct ngene_channel *chan)
-{
-       struct SBufferHeader *Cur = chan->nextBuffer;
-
-       do {
-               memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR));
-               if (chan->mode & NGENE_IO_TSOUT)
-                       FillTSBuffer(Cur->Buffer1,
-                                    chan->Capture1Length,
-                                    chan->DataFormatFlags);
-               Cur = Cur->Next;
-       } while (Cur != chan->nextBuffer);
-
-       if (chan->mode & NGENE_IO_TSOUT) {
-               chan->nextBuffer->ngeneBuffer.SR.DTOUpdate =
-                       chan->AudioDTOValue;
-               chan->AudioDTOUpdated = 0;
-
-               Cur = chan->TSIdleBuffer.Head;
-
-               do {
-                       memset(&Cur->ngeneBuffer.SR, 0,
-                              sizeof(Cur->ngeneBuffer.SR));
-                       FillTSBuffer(Cur->Buffer1,
-                                    chan->Capture1Length,
-                                    chan->DataFormatFlags);
-                       Cur = Cur->Next;
-               } while (Cur != chan->TSIdleBuffer.Head);
-       }
-}
-
-static int ngene_command_stream_control(struct ngene *dev, u8 stream,
-                                       u8 control, u8 mode, u8 flags)
-{
-       struct ngene_channel *chan = &dev->channel[stream];
-       struct ngene_command com;
-       u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300);
-       u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500);
-       u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
-       u16 BsSDO = 0x9B00;
-
-       down(&dev->stream_mutex);
-       memset(&com, 0, sizeof(com));
-       com.cmd.hdr.Opcode = CMD_CONTROL;
-       com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
-       com.cmd.StreamControl.Stream = stream | (control ? 8 : 0);
-       if (chan->mode & NGENE_IO_TSOUT)
-               com.cmd.StreamControl.Stream |= 0x07;
-       com.cmd.StreamControl.Control = control |
-               (flags & SFLAG_ORDER_LUMA_CHROMA);
-       com.cmd.StreamControl.Mode = mode;
-       com.in_len = sizeof(struct FW_STREAM_CONTROL);
-       com.out_len = 0;
-
-       dprintk(KERN_INFO DEVICE_NAME
-               ": Stream=%02x, Control=%02x, Mode=%02x\n",
-               com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control,
-               com.cmd.StreamControl.Mode);
-
-       chan->Mode = mode;
-
-       if (!(control & 0x80)) {
-               spin_lock_irq(&chan->state_lock);
-               if (chan->State == KSSTATE_RUN) {
-                       chan->State = KSSTATE_ACQUIRE;
-                       chan->HWState = HWSTATE_STOP;
-                       spin_unlock_irq(&chan->state_lock);
-                       if (ngene_command(dev, &com) < 0) {
-                               up(&dev->stream_mutex);
-                               return -1;
-                       }
-                       /* clear_buffers(chan); */
-                       flush_buffers(chan);
-                       up(&dev->stream_mutex);
-                       return 0;
-               }
-               spin_unlock_irq(&chan->state_lock);
-               up(&dev->stream_mutex);
-               return 0;
-       }
-
-       if (mode & SMODE_AUDIO_CAPTURE) {
-               com.cmd.StreamControl.CaptureBlockCount =
-                       chan->Capture1Length / AUDIO_BLOCK_SIZE;
-               com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
-       } else if (mode & SMODE_TRANSPORT_STREAM) {
-               com.cmd.StreamControl.CaptureBlockCount =
-                       chan->Capture1Length / TS_BLOCK_SIZE;
-               com.cmd.StreamControl.MaxLinesPerField =
-                       chan->Capture1Length / TS_BLOCK_SIZE;
-               com.cmd.StreamControl.Buffer_Address =
-                       chan->TSRingBuffer.PAHead;
-               if (chan->mode & NGENE_IO_TSOUT) {
-                       com.cmd.StreamControl.BytesPerVBILine =
-                               chan->Capture1Length / TS_BLOCK_SIZE;
-                       com.cmd.StreamControl.Stream |= 0x07;
-               }
-       } else {
-               com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine;
-               com.cmd.StreamControl.MaxLinesPerField = chan->nLines;
-               com.cmd.StreamControl.MinLinesPerField = 100;
-               com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
-
-               if (mode & SMODE_VBI_CAPTURE) {
-                       com.cmd.StreamControl.MaxVBILinesPerField =
-                               chan->nVBILines;
-                       com.cmd.StreamControl.MinVBILinesPerField = 0;
-                       com.cmd.StreamControl.BytesPerVBILine =
-                               chan->nBytesPerVBILine;
-               }
-               if (flags & SFLAG_COLORBAR)
-                       com.cmd.StreamControl.Stream |= 0x04;
-       }
-
-       spin_lock_irq(&chan->state_lock);
-       if (mode & SMODE_AUDIO_CAPTURE) {
-               chan->nextBuffer = chan->RingBuffer.Head;
-               if (mode & SMODE_AUDIO_SPDIF) {
-                       com.cmd.StreamControl.SetupDataLen =
-                               sizeof(SPDIFConfiguration);
-                       com.cmd.StreamControl.SetupDataAddr = BsSPI;
-                       memcpy(com.cmd.StreamControl.SetupData,
-                              SPDIFConfiguration, sizeof(SPDIFConfiguration));
-               } else {
-                       com.cmd.StreamControl.SetupDataLen = 4;
-                       com.cmd.StreamControl.SetupDataAddr = BsSDI;
-                       memcpy(com.cmd.StreamControl.SetupData,
-                              I2SConfiguration +
-                              4 * dev->card_info->i2s[stream], 4);
-               }
-       } else if (mode & SMODE_TRANSPORT_STREAM) {
-               chan->nextBuffer = chan->TSRingBuffer.Head;
-               if (stream >= STREAM_AUDIOIN1) {
-                       if (chan->mode & NGENE_IO_TSOUT) {
-                               com.cmd.StreamControl.SetupDataLen =
-                                       sizeof(TS_I2SOutConfiguration);
-                               com.cmd.StreamControl.SetupDataAddr = BsSDO;
-                               memcpy(com.cmd.StreamControl.SetupData,
-                                      TS_I2SOutConfiguration,
-                                      sizeof(TS_I2SOutConfiguration));
-                       } else {
-                               com.cmd.StreamControl.SetupDataLen =
-                                       sizeof(TS_I2SConfiguration);
-                               com.cmd.StreamControl.SetupDataAddr = BsSDI;
-                               memcpy(com.cmd.StreamControl.SetupData,
-                                      TS_I2SConfiguration,
-                                      sizeof(TS_I2SConfiguration));
-                       }
-               } else {
-                       com.cmd.StreamControl.SetupDataLen = 8;
-                       com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10;
-                       memcpy(com.cmd.StreamControl.SetupData,
-                              TSFeatureDecoderSetup +
-                              8 * dev->card_info->tsf[stream], 8);
-               }
-       } else {
-               chan->nextBuffer = chan->RingBuffer.Head;
-               com.cmd.StreamControl.SetupDataLen =
-                       16 + sizeof(ITUFeatureDecoderSetup);
-               com.cmd.StreamControl.SetupDataAddr = BsUVI;
-               memcpy(com.cmd.StreamControl.SetupData,
-                      ITUDecoderSetup[chan->itumode], 16);
-               memcpy(com.cmd.StreamControl.SetupData + 16,
-                      ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup));
-       }
-       clear_buffers(chan);
-       chan->State = KSSTATE_RUN;
-       if (mode & SMODE_TRANSPORT_STREAM)
-               chan->HWState = HWSTATE_RUN;
-       else
-               chan->HWState = HWSTATE_STARTUP;
-       spin_unlock_irq(&chan->state_lock);
-
-       if (ngene_command(dev, &com) < 0) {
-               up(&dev->stream_mutex);
-               return -1;
-       }
-       up(&dev->stream_mutex);
-       return 0;
-}
-
-void set_transfer(struct ngene_channel *chan, int state)
-{
-       u8 control = 0, mode = 0, flags = 0;
-       struct ngene *dev = chan->dev;
-       int ret;
-
-       /*
-       printk(KERN_INFO DEVICE_NAME ": st %d\n", state);
-       msleep(100);
-       */
-
-       if (state) {
-               if (chan->running) {
-                       printk(KERN_INFO DEVICE_NAME ": already running\n");
-                       return;
-               }
-       } else {
-               if (!chan->running) {
-                       printk(KERN_INFO DEVICE_NAME ": already stopped\n");
-                       return;
-               }
-       }
-
-       if (dev->card_info->switch_ctrl)
-               dev->card_info->switch_ctrl(chan, 1, state ^ 1);
-
-       if (state) {
-               spin_lock_irq(&chan->state_lock);
-
-               /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
-                         ngreadl(0x9310)); */
-               dvb_ringbuffer_flush(&dev->tsout_rbuf);
-               control = 0x80;
-               if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
-                       chan->Capture1Length = 512 * 188;
-                       mode = SMODE_TRANSPORT_STREAM;
-               }
-               if (chan->mode & NGENE_IO_TSOUT) {
-                       chan->pBufferExchange = tsout_exchange;
-                       /* 0x66666666 = 50MHz *2^33 /250MHz */
-                       chan->AudioDTOValue = 0x80000000;
-                       chan->AudioDTOUpdated = 1;
-               }
-               if (chan->mode & NGENE_IO_TSIN)
-                       chan->pBufferExchange = tsin_exchange;
-               spin_unlock_irq(&chan->state_lock);
-       } else
-               ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
-                          ngreadl(0x9310)); */
-
-       ret = ngene_command_stream_control(dev, chan->number,
-                                          control, mode, flags);
-       if (!ret)
-               chan->running = state;
-       else
-               printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n",
-                      state);
-       if (!state) {
-               spin_lock_irq(&chan->state_lock);
-               chan->pBufferExchange = NULL;
-               dvb_ringbuffer_flush(&dev->tsout_rbuf);
-               spin_unlock_irq(&chan->state_lock);
-       }
-}
-
-
-/****************************************************************************/
-/* nGene hardware init and release functions ********************************/
-/****************************************************************************/
-
-static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb)
-{
-       struct SBufferHeader *Cur = rb->Head;
-       u32 j;
-
-       if (!Cur)
-               return;
-
-       for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) {
-               if (Cur->Buffer1)
-                       pci_free_consistent(dev->pci_dev,
-                                           rb->Buffer1Length,
-                                           Cur->Buffer1,
-                                           Cur->scList1->Address);
-
-               if (Cur->Buffer2)
-                       pci_free_consistent(dev->pci_dev,
-                                           rb->Buffer2Length,
-                                           Cur->Buffer2,
-                                           Cur->scList2->Address);
-       }
-
-       if (rb->SCListMem)
-               pci_free_consistent(dev->pci_dev, rb->SCListMemSize,
-                                   rb->SCListMem, rb->PASCListMem);
-
-       pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead);
-}
-
-static void free_idlebuffer(struct ngene *dev,
-                    struct SRingBufferDescriptor *rb,
-                    struct SRingBufferDescriptor *tb)
-{
-       int j;
-       struct SBufferHeader *Cur = tb->Head;
-
-       if (!rb->Head)
-               return;
-       free_ringbuffer(dev, rb);
-       for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) {
-               Cur->Buffer2 = NULL;
-               Cur->scList2 = NULL;
-               Cur->ngeneBuffer.Address_of_first_entry_2 = 0;
-               Cur->ngeneBuffer.Number_of_entries_2 = 0;
-       }
-}
-
-static void free_common_buffers(struct ngene *dev)
-{
-       u32 i;
-       struct ngene_channel *chan;
-
-       for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
-               chan = &dev->channel[i];
-               free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer);
-               free_ringbuffer(dev, &chan->RingBuffer);
-               free_ringbuffer(dev, &chan->TSRingBuffer);
-       }
-
-       if (dev->OverflowBuffer)
-               pci_free_consistent(dev->pci_dev,
-                                   OVERFLOW_BUFFER_SIZE,
-                                   dev->OverflowBuffer, dev->PAOverflowBuffer);
-
-       if (dev->FWInterfaceBuffer)
-               pci_free_consistent(dev->pci_dev,
-                                   4096,
-                                   dev->FWInterfaceBuffer,
-                                   dev->PAFWInterfaceBuffer);
-}
-
-/****************************************************************************/
-/* Ring buffer handling *****************************************************/
-/****************************************************************************/
-
-static int create_ring_buffer(struct pci_dev *pci_dev,
-                      struct SRingBufferDescriptor *descr, u32 NumBuffers)
-{
-       dma_addr_t tmp;
-       struct SBufferHeader *Head;
-       u32 i;
-       u32 MemSize = SIZEOF_SBufferHeader * NumBuffers;
-       u64 PARingBufferHead;
-       u64 PARingBufferCur;
-       u64 PARingBufferNext;
-       struct SBufferHeader *Cur, *Next;
-
-       descr->Head = NULL;
-       descr->MemSize = 0;
-       descr->PAHead = 0;
-       descr->NumBuffers = 0;
-
-       if (MemSize < 4096)
-               MemSize = 4096;
-
-       Head = pci_alloc_consistent(pci_dev, MemSize, &tmp);
-       PARingBufferHead = tmp;
-
-       if (!Head)
-               return -ENOMEM;
-
-       memset(Head, 0, MemSize);
-
-       PARingBufferCur = PARingBufferHead;
-       Cur = Head;
-
-       for (i = 0; i < NumBuffers - 1; i++) {
-               Next = (struct SBufferHeader *)
-                       (((u8 *) Cur) + SIZEOF_SBufferHeader);
-               PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader;
-               Cur->Next = Next;
-               Cur->ngeneBuffer.Next = PARingBufferNext;
-               Cur = Next;
-               PARingBufferCur = PARingBufferNext;
-       }
-       /* Last Buffer points back to first one */
-       Cur->Next = Head;
-       Cur->ngeneBuffer.Next = PARingBufferHead;
-
-       descr->Head       = Head;
-       descr->MemSize    = MemSize;
-       descr->PAHead     = PARingBufferHead;
-       descr->NumBuffers = NumBuffers;
-
-       return 0;
-}
-
-static int AllocateRingBuffers(struct pci_dev *pci_dev,
-                              dma_addr_t of,
-                              struct SRingBufferDescriptor *pRingBuffer,
-                              u32 Buffer1Length, u32 Buffer2Length)
-{
-       dma_addr_t tmp;
-       u32 i, j;
-       int status = 0;
-       u32 SCListMemSize = pRingBuffer->NumBuffers
-               * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) :
-                   NUM_SCATTER_GATHER_ENTRIES)
-               * sizeof(struct HW_SCATTER_GATHER_ELEMENT);
-
-       u64 PASCListMem;
-       struct HW_SCATTER_GATHER_ELEMENT *SCListEntry;
-       u64 PASCListEntry;
-       struct SBufferHeader *Cur;
-       void *SCListMem;
-
-       if (SCListMemSize < 4096)
-               SCListMemSize = 4096;
-
-       SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp);
-
-       PASCListMem = tmp;
-       if (SCListMem == NULL)
-               return -ENOMEM;
-
-       memset(SCListMem, 0, SCListMemSize);
-
-       pRingBuffer->SCListMem = SCListMem;
-       pRingBuffer->PASCListMem = PASCListMem;
-       pRingBuffer->SCListMemSize = SCListMemSize;
-       pRingBuffer->Buffer1Length = Buffer1Length;
-       pRingBuffer->Buffer2Length = Buffer2Length;
-
-       SCListEntry = SCListMem;
-       PASCListEntry = PASCListMem;
-       Cur = pRingBuffer->Head;
-
-       for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) {
-               u64 PABuffer;
-
-               void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length,
-                                                   &tmp);
-               PABuffer = tmp;
-
-               if (Buffer == NULL)
-                       return -ENOMEM;
-
-               Cur->Buffer1 = Buffer;
-
-               SCListEntry->Address = PABuffer;
-               SCListEntry->Length  = Buffer1Length;
-
-               Cur->scList1 = SCListEntry;
-               Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry;
-               Cur->ngeneBuffer.Number_of_entries_1 =
-                       NUM_SCATTER_GATHER_ENTRIES;
-
-               SCListEntry += 1;
-               PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
-
-#if NUM_SCATTER_GATHER_ENTRIES > 1
-               for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) {
-                       SCListEntry->Address = of;
-                       SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
-                       SCListEntry += 1;
-                       PASCListEntry +=
-                               sizeof(struct HW_SCATTER_GATHER_ELEMENT);
-               }
-#endif
-
-               if (!Buffer2Length)
-                       continue;
-
-               Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp);
-               PABuffer = tmp;
-
-               if (Buffer == NULL)
-                       return -ENOMEM;
-
-               Cur->Buffer2 = Buffer;
-
-               SCListEntry->Address = PABuffer;
-               SCListEntry->Length  = Buffer2Length;
-
-               Cur->scList2 = SCListEntry;
-               Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry;
-               Cur->ngeneBuffer.Number_of_entries_2 =
-                       NUM_SCATTER_GATHER_ENTRIES;
-
-               SCListEntry   += 1;
-               PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
-
-#if NUM_SCATTER_GATHER_ENTRIES > 1
-               for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) {
-                       SCListEntry->Address = of;
-                       SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
-                       SCListEntry += 1;
-                       PASCListEntry +=
-                               sizeof(struct HW_SCATTER_GATHER_ELEMENT);
-               }
-#endif
-
-       }
-
-       return status;
-}
-
-static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
-                           struct SRingBufferDescriptor *pRingBuffer)
-{
-       int status = 0;
-
-       /* Copy pointer to scatter gather list in TSRingbuffer
-          structure for buffer 2
-          Load number of buffer
-       */
-       u32 n = pRingBuffer->NumBuffers;
-
-       /* Point to first buffer entry */
-       struct SBufferHeader *Cur = pRingBuffer->Head;
-       int i;
-       /* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */
-       for (i = 0; i < n; i++) {
-               Cur->Buffer2 = pIdleBuffer->Head->Buffer1;
-               Cur->scList2 = pIdleBuffer->Head->scList1;
-               Cur->ngeneBuffer.Address_of_first_entry_2 =
-                       pIdleBuffer->Head->ngeneBuffer.
-                       Address_of_first_entry_1;
-               Cur->ngeneBuffer.Number_of_entries_2 =
-                       pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1;
-               Cur = Cur->Next;
-       }
-       return status;
-}
-
-static u32 RingBufferSizes[MAX_STREAM] = {
-       RING_SIZE_VIDEO,
-       RING_SIZE_VIDEO,
-       RING_SIZE_AUDIO,
-       RING_SIZE_AUDIO,
-       RING_SIZE_AUDIO,
-};
-
-static u32 Buffer1Sizes[MAX_STREAM] = {
-       MAX_VIDEO_BUFFER_SIZE,
-       MAX_VIDEO_BUFFER_SIZE,
-       MAX_AUDIO_BUFFER_SIZE,
-       MAX_AUDIO_BUFFER_SIZE,
-       MAX_AUDIO_BUFFER_SIZE
-};
-
-static u32 Buffer2Sizes[MAX_STREAM] = {
-       MAX_VBI_BUFFER_SIZE,
-       MAX_VBI_BUFFER_SIZE,
-       0,
-       0,
-       0
-};
-
-
-static int AllocCommonBuffers(struct ngene *dev)
-{
-       int status = 0, i;
-
-       dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096,
-                                                    &dev->PAFWInterfaceBuffer);
-       if (!dev->FWInterfaceBuffer)
-               return -ENOMEM;
-       dev->hosttongene = dev->FWInterfaceBuffer;
-       dev->ngenetohost = dev->FWInterfaceBuffer + 256;
-       dev->EventBuffer = dev->FWInterfaceBuffer + 512;
-
-       dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev,
-                                                  OVERFLOW_BUFFER_SIZE,
-                                                  &dev->PAOverflowBuffer);
-       if (!dev->OverflowBuffer)
-               return -ENOMEM;
-       memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE);
-
-       for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
-               int type = dev->card_info->io_type[i];
-
-               dev->channel[i].State = KSSTATE_STOP;
-
-               if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) {
-                       status = create_ring_buffer(dev->pci_dev,
-                                                   &dev->channel[i].RingBuffer,
-                                                   RingBufferSizes[i]);
-                       if (status < 0)
-                               break;
-
-                       if (type & (NGENE_IO_TV | NGENE_IO_AIN)) {
-                               status = AllocateRingBuffers(dev->pci_dev,
-                                                            dev->
-                                                            PAOverflowBuffer,
-                                                            &dev->channel[i].
-                                                            RingBuffer,
-                                                            Buffer1Sizes[i],
-                                                            Buffer2Sizes[i]);
-                               if (status < 0)
-                                       break;
-                       } else if (type & NGENE_IO_HDTV) {
-                               status = AllocateRingBuffers(dev->pci_dev,
-                                                            dev->
-                                                            PAOverflowBuffer,
-                                                            &dev->channel[i].
-                                                            RingBuffer,
-                                                          MAX_HDTV_BUFFER_SIZE,
-                                                            0);
-                               if (status < 0)
-                                       break;
-                       }
-               }
-
-               if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
-
-                       status = create_ring_buffer(dev->pci_dev,
-                                                   &dev->channel[i].
-                                                   TSRingBuffer, RING_SIZE_TS);
-                       if (status < 0)
-                               break;
-
-                       status = AllocateRingBuffers(dev->pci_dev,
-                                                    dev->PAOverflowBuffer,
-                                                    &dev->channel[i].
-                                                    TSRingBuffer,
-                                                    MAX_TS_BUFFER_SIZE, 0);
-                       if (status)
-                               break;
-               }
-
-               if (type & NGENE_IO_TSOUT) {
-                       status = create_ring_buffer(dev->pci_dev,
-                                                   &dev->channel[i].
-                                                   TSIdleBuffer, 1);
-                       if (status < 0)
-                               break;
-                       status = AllocateRingBuffers(dev->pci_dev,
-                                                    dev->PAOverflowBuffer,
-                                                    &dev->channel[i].
-                                                    TSIdleBuffer,
-                                                    MAX_TS_BUFFER_SIZE, 0);
-                       if (status)
-                               break;
-                       FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer,
-                                        &dev->channel[i].TSRingBuffer);
-               }
-       }
-       return status;
-}
-
-static void ngene_release_buffers(struct ngene *dev)
-{
-       if (dev->iomem)
-               iounmap(dev->iomem);
-       free_common_buffers(dev);
-       vfree(dev->tsout_buf);
-       vfree(dev->tsin_buf);
-       vfree(dev->ain_buf);
-       vfree(dev->vin_buf);
-       vfree(dev);
-}
-
-static int ngene_get_buffers(struct ngene *dev)
-{
-       if (AllocCommonBuffers(dev))
-               return -ENOMEM;
-       if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) {
-               dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE);
-               if (!dev->tsout_buf)
-                       return -ENOMEM;
-               dvb_ringbuffer_init(&dev->tsout_rbuf,
-                                   dev->tsout_buf, TSOUT_BUF_SIZE);
-       }
-       if (dev->card_info->io_type[2]&NGENE_IO_TSIN) {
-               dev->tsin_buf = vmalloc(TSIN_BUF_SIZE);
-               if (!dev->tsin_buf)
-                       return -ENOMEM;
-               dvb_ringbuffer_init(&dev->tsin_rbuf,
-                                   dev->tsin_buf, TSIN_BUF_SIZE);
-       }
-       if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
-               dev->ain_buf = vmalloc(AIN_BUF_SIZE);
-               if (!dev->ain_buf)
-                       return -ENOMEM;
-               dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE);
-       }
-       if (dev->card_info->io_type[0] & NGENE_IO_HDTV) {
-               dev->vin_buf = vmalloc(VIN_BUF_SIZE);
-               if (!dev->vin_buf)
-                       return -ENOMEM;
-               dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE);
-       }
-       dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0),
-                            pci_resource_len(dev->pci_dev, 0));
-       if (!dev->iomem)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static void ngene_init(struct ngene *dev)
-{
-       int i;
-
-       tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev);
-
-       memset_io(dev->iomem + 0xc000, 0x00, 0x220);
-       memset_io(dev->iomem + 0xc400, 0x00, 0x100);
-
-       for (i = 0; i < MAX_STREAM; i++) {
-               dev->channel[i].dev = dev;
-               dev->channel[i].number = i;
-       }
-
-       dev->fw_interface_version = 0;
-
-       ngwritel(0, NGENE_INT_ENABLE);
-
-       dev->icounts = ngreadl(NGENE_INT_COUNTS);
-
-       dev->device_version = ngreadl(DEV_VER) & 0x0f;
-       printk(KERN_INFO DEVICE_NAME ": Device version %d\n",
-              dev->device_version);
-}
-
-static int ngene_load_firm(struct ngene *dev)
-{
-       u32 size;
-       const struct firmware *fw = NULL;
-       u8 *ngene_fw;
-       char *fw_name;
-       int err, version;
-
-       version = dev->card_info->fw_version;
-
-       switch (version) {
-       default:
-       case 15:
-               version = 15;
-               size = 23466;
-               fw_name = "ngene_15.fw";
-               dev->cmd_timeout_workaround = true;
-               break;
-       case 16:
-               size = 23498;
-               fw_name = "ngene_16.fw";
-               dev->cmd_timeout_workaround = true;
-               break;
-       case 17:
-               size = 24446;
-               fw_name = "ngene_17.fw";
-               dev->cmd_timeout_workaround = true;
-               break;
-       case 18:
-               size = 0;
-               fw_name = "ngene_18.fw";
-               break;
-       }
-
-       if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
-               printk(KERN_ERR DEVICE_NAME
-                       ": Could not load firmware file %s.\n", fw_name);
-               printk(KERN_INFO DEVICE_NAME
-                       ": Copy %s to your hotplug directory!\n", fw_name);
-               return -1;
-       }
-       if (size == 0)
-               size = fw->size;
-       if (size != fw->size) {
-               printk(KERN_ERR DEVICE_NAME
-                       ": Firmware %s has invalid size!", fw_name);
-               err = -1;
-       } else {
-               printk(KERN_INFO DEVICE_NAME
-                       ": Loading firmware file %s.\n", fw_name);
-               ngene_fw = (u8 *) fw->data;
-               err = ngene_command_load_firmware(dev, ngene_fw, size);
-       }
-
-       release_firmware(fw);
-
-       return err;
-}
-
-static void ngene_stop(struct ngene *dev)
-{
-       down(&dev->cmd_mutex);
-       i2c_del_adapter(&(dev->channel[0].i2c_adapter));
-       i2c_del_adapter(&(dev->channel[1].i2c_adapter));
-       ngwritel(0, NGENE_INT_ENABLE);
-       ngwritel(0, NGENE_COMMAND);
-       ngwritel(0, NGENE_COMMAND_HI);
-       ngwritel(0, NGENE_STATUS);
-       ngwritel(0, NGENE_STATUS_HI);
-       ngwritel(0, NGENE_EVENT);
-       ngwritel(0, NGENE_EVENT_HI);
-       free_irq(dev->pci_dev->irq, dev);
-#ifdef CONFIG_PCI_MSI
-       if (dev->msi_enabled)
-               pci_disable_msi(dev->pci_dev);
-#endif
-}
-
-static int ngene_buffer_config(struct ngene *dev)
-{
-       int stat;
-
-       if (dev->card_info->fw_version >= 17) {
-               u8 tsin12_config[6]   = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 };
-               u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 };
-               u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 };
-               u8 *bconf = tsin12_config;
-
-               if (dev->card_info->io_type[2]&NGENE_IO_TSIN &&
-                   dev->card_info->io_type[3]&NGENE_IO_TSIN) {
-                       bconf = tsin1234_config;
-                       if (dev->card_info->io_type[4]&NGENE_IO_TSOUT &&
-                           dev->ci.en)
-                               bconf = tsio1235_config;
-               }
-               stat = ngene_command_config_free_buf(dev, bconf);
-       } else {
-               int bconf = BUFFER_CONFIG_4422;
-
-               if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
-                       bconf = BUFFER_CONFIG_3333;
-               stat = ngene_command_config_buf(dev, bconf);
-       }
-       return stat;
-}
-
-
-static int ngene_start(struct ngene *dev)
-{
-       int stat;
-       int i;
-
-       pci_set_master(dev->pci_dev);
-       ngene_init(dev);
-
-       stat = request_irq(dev->pci_dev->irq, irq_handler,
-                          IRQF_SHARED, "nGene",
-                          (void *)dev);
-       if (stat < 0)
-               return stat;
-
-       init_waitqueue_head(&dev->cmd_wq);
-       init_waitqueue_head(&dev->tx_wq);
-       init_waitqueue_head(&dev->rx_wq);
-       sema_init(&dev->cmd_mutex, 1);
-       sema_init(&dev->stream_mutex, 1);
-       sema_init(&dev->pll_mutex, 1);
-       sema_init(&dev->i2c_switch_mutex, 1);
-       spin_lock_init(&dev->cmd_lock);
-       for (i = 0; i < MAX_STREAM; i++)
-               spin_lock_init(&dev->channel[i].state_lock);
-       ngwritel(1, TIMESTAMPS);
-
-       ngwritel(1, NGENE_INT_ENABLE);
-
-       stat = ngene_load_firm(dev);
-       if (stat < 0)
-               goto fail;
-
-#ifdef CONFIG_PCI_MSI
-       /* enable MSI if kernel and card support it */
-       if (pci_msi_enabled() && dev->card_info->msi_supported) {
-               unsigned long flags;
-
-               ngwritel(0, NGENE_INT_ENABLE);
-               free_irq(dev->pci_dev->irq, dev);
-               stat = pci_enable_msi(dev->pci_dev);
-               if (stat) {
-                       printk(KERN_INFO DEVICE_NAME
-                               ": MSI not available\n");
-                       flags = IRQF_SHARED;
-               } else {
-                       flags = 0;
-                       dev->msi_enabled = true;
-               }
-               stat = request_irq(dev->pci_dev->irq, irq_handler,
-                                       flags, "nGene", dev);
-               if (stat < 0)
-                       goto fail2;
-               ngwritel(1, NGENE_INT_ENABLE);
-       }
-#endif
-
-       stat = ngene_i2c_init(dev, 0);
-       if (stat < 0)
-               goto fail;
-
-       stat = ngene_i2c_init(dev, 1);
-       if (stat < 0)
-               goto fail;
-
-       return 0;
-
-fail:
-       ngwritel(0, NGENE_INT_ENABLE);
-       free_irq(dev->pci_dev->irq, dev);
-#ifdef CONFIG_PCI_MSI
-fail2:
-       if (dev->msi_enabled)
-               pci_disable_msi(dev->pci_dev);
-#endif
-       return stat;
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static void release_channel(struct ngene_channel *chan)
-{
-       struct dvb_demux *dvbdemux = &chan->demux;
-       struct ngene *dev = chan->dev;
-
-       if (chan->running)
-               set_transfer(chan, 0);
-
-       tasklet_kill(&chan->demux_tasklet);
-
-       if (chan->ci_dev) {
-               dvb_unregister_device(chan->ci_dev);
-               chan->ci_dev = NULL;
-       }
-
-       if (chan->fe2)
-               dvb_unregister_frontend(chan->fe2);
-
-       if (chan->fe) {
-               dvb_unregister_frontend(chan->fe);
-               dvb_frontend_detach(chan->fe);
-               chan->fe = NULL;
-       }
-
-       if (chan->has_demux) {
-               dvb_net_release(&chan->dvbnet);
-               dvbdemux->dmx.close(&dvbdemux->dmx);
-               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
-                                             &chan->hw_frontend);
-               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
-                                             &chan->mem_frontend);
-               dvb_dmxdev_release(&chan->dmxdev);
-               dvb_dmx_release(&chan->demux);
-               chan->has_demux = false;
-       }
-
-       if (chan->has_adapter) {
-               dvb_unregister_adapter(&dev->adapter[chan->number]);
-               chan->has_adapter = false;
-       }
-}
-
-static int init_channel(struct ngene_channel *chan)
-{
-       int ret = 0, nr = chan->number;
-       struct dvb_adapter *adapter = NULL;
-       struct dvb_demux *dvbdemux = &chan->demux;
-       struct ngene *dev = chan->dev;
-       struct ngene_info *ni = dev->card_info;
-       int io = ni->io_type[nr];
-
-       tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan);
-       chan->users = 0;
-       chan->type = io;
-       chan->mode = chan->type;        /* for now only one mode */
-
-       if (io & NGENE_IO_TSIN) {
-               chan->fe = NULL;
-               if (ni->demod_attach[nr]) {
-                       ret = ni->demod_attach[nr](chan);
-                       if (ret < 0)
-                               goto err;
-               }
-               if (chan->fe && ni->tuner_attach[nr]) {
-                       ret = ni->tuner_attach[nr](chan);
-                       if (ret < 0)
-                               goto err;
-               }
-       }
-
-       if (!dev->ci.en && (io & NGENE_IO_TSOUT))
-               return 0;
-
-       if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
-               if (nr >= STREAM_AUDIOIN1)
-                       chan->DataFormatFlags = DF_SWAP32;
-
-               if (nr == 0 || !one_adapter || dev->first_adapter == NULL) {
-                       adapter = &dev->adapter[nr];
-                       ret = dvb_register_adapter(adapter, "nGene",
-                                                  THIS_MODULE,
-                                                  &chan->dev->pci_dev->dev,
-                                                  adapter_nr);
-                       if (ret < 0)
-                               goto err;
-                       if (dev->first_adapter == NULL)
-                               dev->first_adapter = adapter;
-                       chan->has_adapter = true;
-               } else
-                       adapter = dev->first_adapter;
-       }
-
-       if (dev->ci.en && (io & NGENE_IO_TSOUT)) {
-               dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
-               set_transfer(chan, 1);
-               chan->dev->channel[2].DataFormatFlags = DF_SWAP32;
-               set_transfer(&chan->dev->channel[2], 1);
-               dvb_register_device(adapter, &chan->ci_dev,
-                                   &ngene_dvbdev_ci, (void *) chan,
-                                   DVB_DEVICE_SEC);
-               if (!chan->ci_dev)
-                       goto err;
-       }
-
-       if (chan->fe) {
-               if (dvb_register_frontend(adapter, chan->fe) < 0)
-                       goto err;
-               chan->has_demux = true;
-       }
-       if (chan->fe2) {
-               if (dvb_register_frontend(adapter, chan->fe2) < 0)
-                       goto err;
-               chan->fe2->tuner_priv = chan->fe->tuner_priv;
-               memcpy(&chan->fe2->ops.tuner_ops,
-                      &chan->fe->ops.tuner_ops,
-                      sizeof(struct dvb_tuner_ops));
-       }
-
-       if (chan->has_demux) {
-               ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
-                                             ngene_start_feed,
-                                             ngene_stop_feed, chan);
-               ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
-                                                &chan->hw_frontend,
-                                                &chan->mem_frontend, adapter);
-               ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx);
-       }
-
-       return ret;
-
-err:
-       if (chan->fe) {
-               dvb_frontend_detach(chan->fe);
-               chan->fe = NULL;
-       }
-       release_channel(chan);
-       return 0;
-}
-
-static int init_channels(struct ngene *dev)
-{
-       int i, j;
-
-       for (i = 0; i < MAX_STREAM; i++) {
-               dev->channel[i].number = i;
-               if (init_channel(&dev->channel[i]) < 0) {
-                       for (j = i - 1; j >= 0; j--)
-                               release_channel(&dev->channel[j]);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static struct cxd2099_cfg cxd_cfg = {
-       .bitrate = 62000,
-       .adr = 0x40,
-       .polarity = 0,
-       .clock_mode = 0,
-};
-
-static void cxd_attach(struct ngene *dev)
-{
-       struct ngene_ci *ci = &dev->ci;
-
-       ci->en = cxd2099_attach(&cxd_cfg, dev, &dev->channel[0].i2c_adapter);
-       ci->dev = dev;
-       return;
-}
-
-static void cxd_detach(struct ngene *dev)
-{
-       struct ngene_ci *ci = &dev->ci;
-
-       dvb_ca_en50221_release(ci->en);
-       kfree(ci->en);
-       ci->en = 0;
-}
-
-/***********************************/
-/* workaround for shutdown failure */
-/***********************************/
-
-static void ngene_unlink(struct ngene *dev)
-{
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_MEM_WRITE;
-       com.cmd.hdr.Length = 3;
-       com.cmd.MemoryWrite.address = 0x910c;
-       com.cmd.MemoryWrite.data = 0xff;
-       com.in_len = 3;
-       com.out_len = 1;
-
-       down(&dev->cmd_mutex);
-       ngwritel(0, NGENE_INT_ENABLE);
-       ngene_command_mutex(dev, &com);
-       up(&dev->cmd_mutex);
-}
-
-void ngene_shutdown(struct pci_dev *pdev)
-{
-       struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
-
-       if (!dev || !shutdown_workaround)
-               return;
-
-       printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n");
-       ngene_unlink(dev);
-       pci_disable_device(pdev);
-}
-
-/****************************************************************************/
-/* device probe/remove calls ************************************************/
-/****************************************************************************/
-
-void __devexit ngene_remove(struct pci_dev *pdev)
-{
-       struct ngene *dev = pci_get_drvdata(pdev);
-       int i;
-
-       tasklet_kill(&dev->event_tasklet);
-       for (i = MAX_STREAM - 1; i >= 0; i--)
-               release_channel(&dev->channel[i]);
-       if (dev->ci.en)
-               cxd_detach(dev);
-       ngene_stop(dev);
-       ngene_release_buffers(dev);
-       pci_set_drvdata(pdev, NULL);
-       pci_disable_device(pdev);
-}
-
-int __devinit ngene_probe(struct pci_dev *pci_dev,
-                         const struct pci_device_id *id)
-{
-       struct ngene *dev;
-       int stat = 0;
-
-       if (pci_enable_device(pci_dev) < 0)
-               return -ENODEV;
-
-       dev = vzalloc(sizeof(struct ngene));
-       if (dev == NULL) {
-               stat = -ENOMEM;
-               goto fail0;
-       }
-
-       dev->pci_dev = pci_dev;
-       dev->card_info = (struct ngene_info *)id->driver_data;
-       printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name);
-
-       pci_set_drvdata(pci_dev, dev);
-
-       /* Alloc buffers and start nGene */
-       stat = ngene_get_buffers(dev);
-       if (stat < 0)
-               goto fail1;
-       stat = ngene_start(dev);
-       if (stat < 0)
-               goto fail1;
-
-       cxd_attach(dev);
-
-       stat = ngene_buffer_config(dev);
-       if (stat < 0)
-               goto fail1;
-
-
-       dev->i2c_current_bus = -1;
-
-       /* Register DVB adapters and devices for both channels */
-       if (init_channels(dev) < 0)
-               goto fail2;
-
-       return 0;
-
-fail2:
-       ngene_stop(dev);
-fail1:
-       ngene_release_buffers(dev);
-fail0:
-       pci_disable_device(pci_dev);
-       pci_set_drvdata(pci_dev, NULL);
-       return stat;
-}
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
deleted file mode 100644 (file)
index fcb16a6..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * ngene-dvb.c: nGene PCIe bridge driver - DVB functions
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
- *                         Modifications for new nGene firmware,
- *                         support for EEPROM-copying,
- *                         support for new dual DVB-S2 card prototype
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/io.h>
-#include <asm/div64.h>
-#include <linux/pci.h>
-#include <linux/timer.h>
-#include <linux/byteorder/generic.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-
-#include "ngene.h"
-
-
-/****************************************************************************/
-/* COMMAND API interface ****************************************************/
-/****************************************************************************/
-
-static ssize_t ts_write(struct file *file, const char *buf,
-                       size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct ngene_channel *chan = dvbdev->priv;
-       struct ngene *dev = chan->dev;
-
-       if (wait_event_interruptible(dev->tsout_rbuf.queue,
-                                    dvb_ringbuffer_free
-                                    (&dev->tsout_rbuf) >= count) < 0)
-               return 0;
-
-       dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
-
-       return count;
-}
-
-static ssize_t ts_read(struct file *file, char *buf,
-                      size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct ngene_channel *chan = dvbdev->priv;
-       struct ngene *dev = chan->dev;
-       int left, avail;
-
-       left = count;
-       while (left) {
-               if (wait_event_interruptible(
-                           dev->tsin_rbuf.queue,
-                           dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
-                       return -EAGAIN;
-               avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
-               if (avail > left)
-                       avail = left;
-               dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
-               left -= avail;
-               buf += avail;
-       }
-       return count;
-}
-
-static const struct file_operations ci_fops = {
-       .owner   = THIS_MODULE,
-       .read    = ts_read,
-       .write   = ts_write,
-       .open    = dvb_generic_open,
-       .release = dvb_generic_release,
-};
-
-struct dvb_device ngene_dvbdev_ci = {
-       .priv    = 0,
-       .readers = -1,
-       .writers = -1,
-       .users   = -1,
-       .fops    = &ci_fops,
-};
-
-
-/****************************************************************************/
-/* DVB functions and API interface ******************************************/
-/****************************************************************************/
-
-static void swap_buffer(u32 *p, u32 len)
-{
-       while (len) {
-               *p = swab32(*p);
-               p++;
-               len -= 4;
-       }
-}
-
-/* start of filler packet */
-static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER };
-
-/* #define DEBUG_CI_XFER */
-#ifdef DEBUG_CI_XFER
-static u32 ok;
-static u32 overflow;
-static u32 stripped;
-#endif
-
-void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
-{
-       struct ngene_channel *chan = priv;
-       struct ngene *dev = chan->dev;
-
-
-       if (flags & DF_SWAP32)
-               swap_buffer(buf, len);
-
-       if (dev->ci.en && chan->number == 2) {
-               while (len >= 188) {
-                       if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) {
-                               if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) {
-                                       dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188);
-                                       wake_up(&dev->tsin_rbuf.queue);
-#ifdef DEBUG_CI_XFER
-                                       ok++;
-#endif
-                               }
-#ifdef DEBUG_CI_XFER
-                               else
-                                       overflow++;
-#endif
-                       }
-#ifdef DEBUG_CI_XFER
-                       else
-                               stripped++;
-
-                       if (ok % 100 == 0 && overflow)
-                               printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped);
-#endif
-                       buf += 188;
-                       len -= 188;
-               }
-               return NULL;
-       }
-
-       if (chan->users > 0)
-               dvb_dmx_swfilter(&chan->demux, buf, len);
-
-       return NULL;
-}
-
-void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
-{
-       struct ngene_channel *chan = priv;
-       struct ngene *dev = chan->dev;
-       u32 alen;
-
-       alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
-       alen -= alen % 188;
-
-       if (alen < len)
-               FillTSBuffer(buf + alen, len - alen, flags);
-       else
-               alen = len;
-       dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
-       if (flags & DF_SWAP32)
-               swap_buffer((u32 *)buf, alen);
-       wake_up_interruptible(&dev->tsout_rbuf.queue);
-       return buf;
-}
-
-
-
-int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct ngene_channel *chan = dvbdmx->priv;
-
-       if (chan->users == 0) {
-               if (!chan->dev->cmd_timeout_workaround || !chan->running)
-                       set_transfer(chan, 1);
-       }
-
-       return ++chan->users;
-}
-
-int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct ngene_channel *chan = dvbdmx->priv;
-
-       if (--chan->users)
-               return chan->users;
-
-       if (!chan->dev->cmd_timeout_workaround)
-               set_transfer(chan, 0);
-
-       return 0;
-}
-
-int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
-                           int (*start_feed)(struct dvb_demux_feed *),
-                           int (*stop_feed)(struct dvb_demux_feed *),
-                           void *priv)
-{
-       dvbdemux->priv = priv;
-
-       dvbdemux->filternum = 256;
-       dvbdemux->feednum = 256;
-       dvbdemux->start_feed = start_feed;
-       dvbdemux->stop_feed = stop_feed;
-       dvbdemux->write_to_decoder = NULL;
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
-                                     DMX_SECTION_FILTERING |
-                                     DMX_MEMORY_BASED_FILTERING);
-       return dvb_dmx_init(dvbdemux);
-}
-
-int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
-                              struct dvb_demux *dvbdemux,
-                              struct dmx_frontend *hw_frontend,
-                              struct dmx_frontend *mem_frontend,
-                              struct dvb_adapter *dvb_adapter)
-{
-       int ret;
-
-       dmxdev->filternum = 256;
-       dmxdev->demux = &dvbdemux->dmx;
-       dmxdev->capabilities = 0;
-       ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
-       if (ret < 0)
-               return ret;
-
-       hw_frontend->source = DMX_FRONTEND_0;
-       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
-       mem_frontend->source = DMX_MEMORY_FE;
-       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
-       return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
-}
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c
deleted file mode 100644 (file)
index d28554f..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * ngene-i2c.c: nGene PCIe bridge driver i2c functions
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
- *                         Modifications for new nGene firmware,
- *                         support for EEPROM-copying,
- *                         support for new dual DVB-S2 card prototype
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-/* FIXME - some of these can probably be removed */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/io.h>
-#include <asm/div64.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/timer.h>
-#include <linux/byteorder/generic.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-
-#include "ngene.h"
-
-/* Firmware command for i2c operations */
-static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
-                          u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
-{
-       struct ngene_command com;
-
-       com.cmd.hdr.Opcode = CMD_I2C_READ;
-       com.cmd.hdr.Length = outlen + 3;
-       com.cmd.I2CRead.Device = adr << 1;
-       memcpy(com.cmd.I2CRead.Data, out, outlen);
-       com.cmd.I2CRead.Data[outlen] = inlen;
-       com.cmd.I2CRead.Data[outlen + 1] = 0;
-       com.in_len = outlen + 3;
-       com.out_len = inlen + 1;
-
-       if (ngene_command(dev, &com) < 0)
-               return -EIO;
-
-       if ((com.cmd.raw8[0] >> 1) != adr)
-               return -EIO;
-
-       if (flag)
-               memcpy(in, com.cmd.raw8, inlen + 1);
-       else
-               memcpy(in, com.cmd.raw8 + 1, inlen);
-       return 0;
-}
-
-static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
-                                  u8 *out, u8 outlen)
-{
-       struct ngene_command com;
-
-
-       com.cmd.hdr.Opcode = CMD_I2C_WRITE;
-       com.cmd.hdr.Length = outlen + 1;
-       com.cmd.I2CRead.Device = adr << 1;
-       memcpy(com.cmd.I2CRead.Data, out, outlen);
-       com.in_len = outlen + 1;
-       com.out_len = 1;
-
-       if (ngene_command(dev, &com) < 0)
-               return -EIO;
-
-       if (com.cmd.raw8[0] == 1)
-               return -EIO;
-
-       return 0;
-}
-
-static void ngene_i2c_set_bus(struct ngene *dev, int bus)
-{
-       if (!(dev->card_info->i2c_access & 2))
-               return;
-       if (dev->i2c_current_bus == bus)
-               return;
-
-       switch (bus) {
-       case 0:
-               ngene_command_gpio_set(dev, 3, 0);
-               ngene_command_gpio_set(dev, 2, 1);
-               break;
-
-       case 1:
-               ngene_command_gpio_set(dev, 2, 0);
-               ngene_command_gpio_set(dev, 3, 1);
-               break;
-       }
-       dev->i2c_current_bus = bus;
-}
-
-static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
-                                struct i2c_msg msg[], int num)
-{
-       struct ngene_channel *chan =
-               (struct ngene_channel *)i2c_get_adapdata(adapter);
-       struct ngene *dev = chan->dev;
-
-       down(&dev->i2c_switch_mutex);
-       ngene_i2c_set_bus(dev, chan->number);
-
-       if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
-               if (!ngene_command_i2c_read(dev, msg[0].addr,
-                                           msg[0].buf, msg[0].len,
-                                           msg[1].buf, msg[1].len, 0))
-                       goto done;
-
-       if (num == 1 && !(msg[0].flags & I2C_M_RD))
-               if (!ngene_command_i2c_write(dev, msg[0].addr,
-                                            msg[0].buf, msg[0].len))
-                       goto done;
-       if (num == 1 && (msg[0].flags & I2C_M_RD))
-               if (!ngene_command_i2c_read(dev, msg[0].addr, NULL, 0,
-                                           msg[0].buf, msg[0].len, 0))
-                       goto done;
-
-       up(&dev->i2c_switch_mutex);
-       return -EIO;
-
-done:
-       up(&dev->i2c_switch_mutex);
-       return num;
-}
-
-
-static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm ngene_i2c_algo = {
-       .master_xfer = ngene_i2c_master_xfer,
-       .functionality = ngene_i2c_functionality,
-};
-
-int ngene_i2c_init(struct ngene *dev, int dev_nr)
-{
-       struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
-
-       i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
-
-       strcpy(adap->name, "nGene");
-
-       adap->algo = &ngene_i2c_algo;
-       adap->algo_data = (void *)&(dev->channel[dev_nr]);
-       adap->dev.parent = &dev->pci_dev->dev;
-
-       return i2c_add_adapter(adap);
-}
-
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
deleted file mode 100644 (file)
index 5443dc0..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * ngene.h: nGene PCIe bridge driver
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 only, as published by the Free Software Foundation.
- *
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef _NGENE_H_
-#define _NGENE_H_
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <asm/dma.h>
-#include <linux/scatterlist.h>
-
-#include <linux/dvb/frontend.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_net.h"
-#include "cxd2099.h"
-
-#define DEVICE_NAME "ngene"
-
-#define NGENE_VID       0x18c3
-#define NGENE_PID       0x0720
-
-#ifndef VIDEO_CAP_VC1
-#define VIDEO_CAP_AVC   128
-#define VIDEO_CAP_H264  128
-#define VIDEO_CAP_VC1   256
-#define VIDEO_CAP_WMV9  256
-#define VIDEO_CAP_MPEG4 512
-#endif
-
-enum STREAM {
-       STREAM_VIDEOIN1 = 0,        /* ITU656 or TS Input */
-       STREAM_VIDEOIN2,
-       STREAM_AUDIOIN1,            /* I2S or SPI Input */
-       STREAM_AUDIOIN2,
-       STREAM_AUDIOOUT,
-       MAX_STREAM
-};
-
-enum SMODE_BITS {
-       SMODE_AUDIO_SPDIF = 0x20,
-       SMODE_AVSYNC = 0x10,
-       SMODE_TRANSPORT_STREAM = 0x08,
-       SMODE_AUDIO_CAPTURE = 0x04,
-       SMODE_VBI_CAPTURE = 0x02,
-       SMODE_VIDEO_CAPTURE = 0x01
-};
-
-enum STREAM_FLAG_BITS {
-       SFLAG_CHROMA_FORMAT_2COMP  = 0x01, /* Chroma Format : 2's complement */
-       SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */
-       SFLAG_ORDER_LUMA_CHROMA    = 0x02, /* Byte order: Y,Cb,Y,Cr */
-       SFLAG_ORDER_CHROMA_LUMA    = 0x00, /* Byte order: Cb,Y,Cr,Y */
-       SFLAG_COLORBAR             = 0x04, /* Select colorbar */
-};
-
-#define PROGRAM_ROM     0x0000
-#define PROGRAM_SRAM    0x1000
-#define PERIPHERALS0    0x8000
-#define PERIPHERALS1    0x9000
-#define SHARED_BUFFER   0xC000
-
-#define HOST_TO_NGENE    (SHARED_BUFFER+0x0000)
-#define NGENE_TO_HOST    (SHARED_BUFFER+0x0100)
-#define NGENE_COMMAND    (SHARED_BUFFER+0x0200)
-#define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204)
-#define NGENE_STATUS     (SHARED_BUFFER+0x0208)
-#define NGENE_STATUS_HI  (SHARED_BUFFER+0x020C)
-#define NGENE_EVENT      (SHARED_BUFFER+0x0210)
-#define NGENE_EVENT_HI   (SHARED_BUFFER+0x0214)
-#define VARIABLES        (SHARED_BUFFER+0x0210)
-
-#define NGENE_INT_COUNTS       (SHARED_BUFFER+0x0260)
-#define NGENE_INT_ENABLE       (SHARED_BUFFER+0x0264)
-#define NGENE_VBI_LINE_COUNT   (SHARED_BUFFER+0x0268)
-
-#define BUFFER_GP_XMIT  (SHARED_BUFFER+0x0800)
-#define BUFFER_GP_RECV  (SHARED_BUFFER+0x0900)
-#define EEPROM_AREA     (SHARED_BUFFER+0x0A00)
-
-#define SG_V_IN_1       (SHARED_BUFFER+0x0A80)
-#define SG_VBI_1        (SHARED_BUFFER+0x0B00)
-#define SG_A_IN_1       (SHARED_BUFFER+0x0B80)
-#define SG_V_IN_2       (SHARED_BUFFER+0x0C00)
-#define SG_VBI_2        (SHARED_BUFFER+0x0C80)
-#define SG_A_IN_2       (SHARED_BUFFER+0x0D00)
-#define SG_V_OUT        (SHARED_BUFFER+0x0D80)
-#define SG_A_OUT2       (SHARED_BUFFER+0x0E00)
-
-#define DATA_A_IN_1     (SHARED_BUFFER+0x0E80)
-#define DATA_A_IN_2     (SHARED_BUFFER+0x0F00)
-#define DATA_A_OUT      (SHARED_BUFFER+0x0F80)
-#define DATA_V_IN_1     (SHARED_BUFFER+0x1000)
-#define DATA_V_IN_2     (SHARED_BUFFER+0x2000)
-#define DATA_V_OUT      (SHARED_BUFFER+0x3000)
-
-#define DATA_FIFO_AREA  (SHARED_BUFFER+0x1000)
-
-#define TIMESTAMPS      0xA000
-#define SCRATCHPAD      0xA080
-#define FORCE_INT       0xA088
-#define FORCE_NMI       0xA090
-#define INT_STATUS      0xA0A0
-
-#define DEV_VER         0x9004
-
-#define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF)
-
-struct SG_ADDR {
-       u64 start;
-       u64 curr;
-       u16 curr_ptr;
-       u16 elements;
-       u32 pad[3];
-} __attribute__ ((__packed__));
-
-struct SHARED_MEMORY {
-       /* C000 */
-       u32 HostToNgene[64];
-
-       /* C100 */
-       u32 NgeneToHost[64];
-
-       /* C200 */
-       u64 NgeneCommand;
-       u64 NgeneStatus;
-       u64 NgeneEvent;
-
-       /* C210 */
-       u8 pad1[0xc260 - 0xc218];
-
-       /* C260 */
-       u32 IntCounts;
-       u32 IntEnable;
-
-       /* C268 */
-       u8 pad2[0xd000 - 0xc268];
-
-} __attribute__ ((__packed__));
-
-struct BUFFER_STREAM_RESULTS {
-       u32 Clock;           /* Stream time in 100ns units */
-       u16 RemainingLines;  /* Remaining lines in this field.
-                               0 for complete field */
-       u8  FieldCount;      /* Video field number */
-       u8  Flags;           /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow,
-                               Bit 0 = FieldID */
-       u16 BlockCount;      /* Audio block count (unused) */
-       u8  Reserved[2];
-       u32 DTOUpdate;
-} __attribute__ ((__packed__));
-
-struct HW_SCATTER_GATHER_ELEMENT {
-       u64 Address;
-       u32 Length;
-       u32 Reserved;
-} __attribute__ ((__packed__));
-
-struct BUFFER_HEADER {
-       u64    Next;
-       struct BUFFER_STREAM_RESULTS SR;
-
-       u32    Number_of_entries_1;
-       u32    Reserved5;
-       u64    Address_of_first_entry_1;
-
-       u32    Number_of_entries_2;
-       u32    Reserved7;
-       u64    Address_of_first_entry_2;
-} __attribute__ ((__packed__));
-
-struct EVENT_BUFFER {
-       u32    TimeStamp;
-       u8     GPIOStatus;
-       u8     UARTStatus;
-       u8     RXCharacter;
-       u8     EventStatus;
-       u32    Reserved[2];
-} __attribute__ ((__packed__));
-
-/* Firmware commands. */
-
-enum OPCODES {
-       CMD_NOP = 0,
-       CMD_FWLOAD_PREPARE  = 0x01,
-       CMD_FWLOAD_FINISH   = 0x02,
-       CMD_I2C_READ        = 0x03,
-       CMD_I2C_WRITE       = 0x04,
-
-       CMD_I2C_WRITE_NOSTOP = 0x05,
-       CMD_I2C_CONTINUE_WRITE = 0x06,
-       CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07,
-
-       CMD_DEBUG_OUTPUT    = 0x09,
-
-       CMD_CONTROL         = 0x10,
-       CMD_CONFIGURE_BUFFER = 0x11,
-       CMD_CONFIGURE_FREE_BUFFER = 0x12,
-
-       CMD_SPI_READ        = 0x13,
-       CMD_SPI_WRITE       = 0x14,
-
-       CMD_MEM_READ        = 0x20,
-       CMD_MEM_WRITE       = 0x21,
-       CMD_SFR_READ        = 0x22,
-       CMD_SFR_WRITE       = 0x23,
-       CMD_IRAM_READ       = 0x24,
-       CMD_IRAM_WRITE      = 0x25,
-       CMD_SET_GPIO_PIN    = 0x26,
-       CMD_SET_GPIO_INT    = 0x27,
-       CMD_CONFIGURE_UART  = 0x28,
-       CMD_WRITE_UART      = 0x29,
-       MAX_CMD
-};
-
-enum RESPONSES {
-       OK = 0,
-       ERROR = 1
-};
-
-struct FW_HEADER {
-       u8 Opcode;
-       u8 Length;
-} __attribute__ ((__packed__));
-
-struct FW_I2C_WRITE {
-       struct FW_HEADER hdr;
-       u8 Device;
-       u8 Data[250];
-} __attribute__ ((__packed__));
-
-struct FW_I2C_CONTINUE_WRITE {
-       struct FW_HEADER hdr;
-       u8 Data[250];
-} __attribute__ ((__packed__));
-
-struct FW_I2C_READ {
-       struct FW_HEADER hdr;
-       u8 Device;
-       u8 Data[252];    /* followed by two bytes of read data count */
-} __attribute__ ((__packed__));
-
-struct FW_SPI_WRITE {
-       struct FW_HEADER hdr;
-       u8 ModeSelect;
-       u8 Data[250];
-} __attribute__ ((__packed__));
-
-struct FW_SPI_READ {
-       struct FW_HEADER hdr;
-       u8 ModeSelect;
-       u8 Data[252];    /* followed by two bytes of read data count */
-} __attribute__ ((__packed__));
-
-struct FW_FWLOAD_PREPARE {
-       struct FW_HEADER hdr;
-} __attribute__ ((__packed__));
-
-struct FW_FWLOAD_FINISH {
-       struct FW_HEADER hdr;
-       u16 Address;     /* address of final block */
-       u16 Length;
-} __attribute__ ((__packed__));
-
-/*
- * Meaning of FW_STREAM_CONTROL::Mode bits:
- *  Bit 7: Loopback PEXin to PEXout using TVOut channel
- *  Bit 6: AVLOOP
- *  Bit 5: Audio select; 0=I2S, 1=SPDIF
- *  Bit 4: AVSYNC
- *  Bit 3: Enable transport stream
- *  Bit 2: Enable audio capture
- *  Bit 1: Enable ITU-Video VBI capture
- *  Bit 0: Enable ITU-Video capture
- *
- * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL)
- *  Bit 7: continuous capture
- *  Bit 6: capture one field
- *  Bit 5: capture one frame
- *  Bit 4: unused
- *  Bit 3: starting field; 0=odd, 1=even
- *  Bit 2: sample size; 0=8-bit, 1=10-bit
- *  Bit 1: data format; 0=UYVY, 1=YUY2
- *  Bit 0: resets buffer pointers
-*/
-
-enum FSC_MODE_BITS {
-       SMODE_LOOPBACK          = 0x80,
-       SMODE_AVLOOP            = 0x40,
-       _SMODE_AUDIO_SPDIF      = 0x20,
-       _SMODE_AVSYNC           = 0x10,
-       _SMODE_TRANSPORT_STREAM = 0x08,
-       _SMODE_AUDIO_CAPTURE    = 0x04,
-       _SMODE_VBI_CAPTURE      = 0x02,
-       _SMODE_VIDEO_CAPTURE    = 0x01
-};
-
-
-/* Meaning of FW_STREAM_CONTROL::Stream bits:
- * Bit 3: Audio sample count:  0 = relative, 1 = absolute
- * Bit 2: color bar select; 1=color bars, 0=CV3 decoder
- * Bits 1-0: stream select, UVI1, UVI2, TVOUT
- */
-
-struct FW_STREAM_CONTROL {
-       struct FW_HEADER hdr;
-       u8     Stream;             /* Stream number (UVI1, UVI2, TVOUT) */
-       u8     Control;            /* Value written to UVI1_CTL */
-       u8     Mode;               /* Controls clock source */
-       u8     SetupDataLen;       /* Length of setup data, MSB=1 write
-                                     backwards */
-       u16    CaptureBlockCount;  /* Blocks (a 256 Bytes) to capture per buffer
-                                     for TS and Audio */
-       u64    Buffer_Address;     /* Address of first buffer header */
-       u16    BytesPerVideoLine;
-       u16    MaxLinesPerField;
-       u16    MinLinesPerField;
-       u16    Reserved_1;
-       u16    BytesPerVBILine;
-       u16    MaxVBILinesPerField;
-       u16    MinVBILinesPerField;
-       u16    SetupDataAddr;      /* ngene relative address of setup data */
-       u8     SetupData[32];      /* setup data */
-} __attribute__((__packed__));
-
-#define AUDIO_BLOCK_SIZE    256
-#define TS_BLOCK_SIZE       256
-
-struct FW_MEM_READ {
-       struct FW_HEADER hdr;
-       u16   address;
-} __attribute__ ((__packed__));
-
-struct FW_MEM_WRITE {
-       struct FW_HEADER hdr;
-       u16   address;
-       u8    data;
-} __attribute__ ((__packed__));
-
-struct FW_SFR_IRAM_READ {
-       struct FW_HEADER hdr;
-       u8    address;
-} __attribute__ ((__packed__));
-
-struct FW_SFR_IRAM_WRITE {
-       struct FW_HEADER hdr;
-       u8    address;
-       u8    data;
-} __attribute__ ((__packed__));
-
-struct FW_SET_GPIO_PIN {
-       struct FW_HEADER hdr;
-       u8    select;
-} __attribute__ ((__packed__));
-
-struct FW_SET_GPIO_INT {
-       struct FW_HEADER hdr;
-       u8    select;
-} __attribute__ ((__packed__));
-
-struct FW_SET_DEBUGMODE {
-       struct FW_HEADER hdr;
-       u8   debug_flags;
-} __attribute__ ((__packed__));
-
-struct FW_CONFIGURE_BUFFERS {
-       struct FW_HEADER hdr;
-       u8   config;
-} __attribute__ ((__packed__));
-
-enum _BUFFER_CONFIGS {
-       /* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2  (standard usage) */
-       BUFFER_CONFIG_4422 = 0,
-       /* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2  (4x TS input usage) */
-       BUFFER_CONFIG_3333 = 1,
-       /* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut  (HDTV decoder usage) */
-       BUFFER_CONFIG_8022 = 2,
-       BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */
-};
-
-struct FW_CONFIGURE_FREE_BUFFERS {
-       struct FW_HEADER hdr;
-       u8   UVI1_BufferLength;
-       u8   UVI2_BufferLength;
-       u8   TVO_BufferLength;
-       u8   AUD1_BufferLength;
-       u8   AUD2_BufferLength;
-       u8   TVA_BufferLength;
-} __attribute__ ((__packed__));
-
-struct FW_CONFIGURE_UART {
-       struct FW_HEADER hdr;
-       u8 UartControl;
-} __attribute__ ((__packed__));
-
-enum _UART_CONFIG {
-       _UART_BAUDRATE_19200 = 0,
-       _UART_BAUDRATE_9600  = 1,
-       _UART_BAUDRATE_4800  = 2,
-       _UART_BAUDRATE_2400  = 3,
-       _UART_RX_ENABLE      = 0x40,
-       _UART_TX_ENABLE      = 0x80,
-};
-
-struct FW_WRITE_UART {
-       struct FW_HEADER hdr;
-       u8 Data[252];
-} __attribute__ ((__packed__));
-
-
-struct ngene_command {
-       u32 in_len;
-       u32 out_len;
-       union {
-               u32                              raw[64];
-               u8                               raw8[256];
-               struct FW_HEADER                 hdr;
-               struct FW_I2C_WRITE              I2CWrite;
-               struct FW_I2C_CONTINUE_WRITE     I2CContinueWrite;
-               struct FW_I2C_READ               I2CRead;
-               struct FW_STREAM_CONTROL         StreamControl;
-               struct FW_FWLOAD_PREPARE         FWLoadPrepare;
-               struct FW_FWLOAD_FINISH          FWLoadFinish;
-               struct FW_MEM_READ               MemoryRead;
-               struct FW_MEM_WRITE              MemoryWrite;
-               struct FW_SFR_IRAM_READ          SfrIramRead;
-               struct FW_SFR_IRAM_WRITE         SfrIramWrite;
-               struct FW_SPI_WRITE              SPIWrite;
-               struct FW_SPI_READ               SPIRead;
-               struct FW_SET_GPIO_PIN           SetGpioPin;
-               struct FW_SET_GPIO_INT           SetGpioInt;
-               struct FW_SET_DEBUGMODE          SetDebugMode;
-               struct FW_CONFIGURE_BUFFERS      ConfigureBuffers;
-               struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers;
-               struct FW_CONFIGURE_UART         ConfigureUart;
-               struct FW_WRITE_UART             WriteUart;
-       } cmd;
-} __attribute__ ((__packed__));
-
-#define NGENE_INTERFACE_VERSION 0x103
-#define MAX_VIDEO_BUFFER_SIZE   (417792) /* 288*1440 rounded up to next page */
-#define MAX_AUDIO_BUFFER_SIZE     (8192) /* Gives room for about 23msec@48KHz */
-#define MAX_VBI_BUFFER_SIZE      (28672) /* 1144*18 rounded up to next page */
-#define MAX_TS_BUFFER_SIZE       (98304) /* 512*188 rounded up to next page */
-#define MAX_HDTV_BUFFER_SIZE   (2080768) /* 541*1920*2 rounded up to next page
-                                           Max: (1920x1080i60) */
-
-#define OVERFLOW_BUFFER_SIZE    (8192)
-
-#define RING_SIZE_VIDEO     4
-#define RING_SIZE_AUDIO     8
-#define RING_SIZE_TS        8
-
-#define NUM_SCATTER_GATHER_ENTRIES  8
-
-#define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \
-                       RING_SIZE_VIDEO * 2) + \
-                       (MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \
-                       (MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \
-                       (RING_SIZE_VIDEO * PAGE_SIZE * 2) + \
-                       (RING_SIZE_AUDIO * PAGE_SIZE * 2) + \
-                       (RING_SIZE_TS    * PAGE_SIZE * 4) + \
-                        8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE)
-
-#define EVENT_QUEUE_SIZE    16
-
-/* Gathers the current state of a single channel. */
-
-struct SBufferHeader {
-       struct BUFFER_HEADER   ngeneBuffer; /* Physical descriptor */
-       struct SBufferHeader  *Next;
-       void                  *Buffer1;
-       struct HW_SCATTER_GATHER_ELEMENT *scList1;
-       void                  *Buffer2;
-       struct HW_SCATTER_GATHER_ELEMENT *scList2;
-};
-
-/* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */
-#define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63)
-
-enum HWSTATE {
-       HWSTATE_STOP,
-       HWSTATE_STARTUP,
-       HWSTATE_RUN,
-       HWSTATE_PAUSE,
-};
-
-enum KSSTATE {
-       KSSTATE_STOP,
-       KSSTATE_ACQUIRE,
-       KSSTATE_PAUSE,
-       KSSTATE_RUN,
-};
-
-struct SRingBufferDescriptor {
-       struct SBufferHeader *Head; /* Points to first buffer in ring buffer
-                                      structure*/
-       u64   PAHead;         /* Physical address of first buffer */
-       u32   MemSize;        /* Memory size of allocated ring buffers
-                                (needed for freeing) */
-       u32   NumBuffers;     /* Number of buffers in the ring */
-       u32   Buffer1Length;  /* Allocated length of Buffer 1 */
-       u32   Buffer2Length;  /* Allocated length of Buffer 2 */
-       void *SCListMem;      /* Memory to hold scatter gather lists for this
-                                ring */
-       u64   PASCListMem;    /* Physical address  .. */
-       u32   SCListMemSize;  /* Size of this memory */
-};
-
-enum STREAMMODEFLAGS {
-       StreamMode_NONE   = 0, /* Stream not used */
-       StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */
-       StreamMode_TSIN   = 2, /* Transport stream input (all) */
-       StreamMode_HDTV   = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60
-                                 (only stream 0) */
-       StreamMode_TSOUT  = 8, /* Transport stream output (only stream 3) */
-};
-
-
-enum BufferExchangeFlags {
-       BEF_EVEN_FIELD   = 0x00000001,
-       BEF_CONTINUATION = 0x00000002,
-       BEF_MORE_DATA    = 0x00000004,
-       BEF_OVERFLOW     = 0x00000008,
-       DF_SWAP32        = 0x00010000,
-};
-
-typedef void *(IBufferExchange)(void *, void *, u32, u32, u32);
-
-struct MICI_STREAMINFO {
-       IBufferExchange    *pExchange;
-       IBufferExchange    *pExchangeVBI;     /* Secondary (VBI, ancillary) */
-       u8  Stream;
-       u8  Flags;
-       u8  Mode;
-       u8  Reserved;
-       u16 nLinesVideo;
-       u16 nBytesPerLineVideo;
-       u16 nLinesVBI;
-       u16 nBytesPerLineVBI;
-       u32 CaptureLength;    /* Used for audio and transport stream */
-};
-
-/****************************************************************************/
-/* STRUCTS ******************************************************************/
-/****************************************************************************/
-
-/* sound hardware definition */
-#define MIXER_ADDR_TVTUNER      0
-#define MIXER_ADDR_LAST         0
-
-struct ngene_channel;
-
-/*struct sound chip*/
-
-struct mychip {
-       struct ngene_channel *chan;
-       struct snd_card *card;
-       struct pci_dev *pci;
-       struct snd_pcm_substream *substream;
-       struct snd_pcm *pcm;
-       unsigned long port;
-       int irq;
-       spinlock_t mixer_lock;
-       spinlock_t lock;
-       int mixer_volume[MIXER_ADDR_LAST + 1][2];
-       int capture_source[MIXER_ADDR_LAST + 1][2];
-};
-
-#ifdef NGENE_V4L
-struct ngene_overlay {
-       int                    tvnorm;
-       struct v4l2_rect       w;
-       enum v4l2_field        field;
-       struct v4l2_clip       *clips;
-       int                    nclips;
-       int                    setup_ok;
-};
-
-struct ngene_tvnorm {
-       int   v4l2_id;
-       char  *name;
-       u16   swidth, sheight; /* scaled standard width, height */
-       int   tuner_norm;
-       int   soundstd;
-};
-
-struct ngene_vopen {
-       struct ngene_channel      *ch;
-       enum v4l2_priority         prio;
-       int                        width;
-       int                        height;
-       int                        depth;
-       struct videobuf_queue      vbuf_q;
-       struct videobuf_queue      vbi;
-       int                        fourcc;
-       int                        picxcount;
-       int                        resources;
-       enum v4l2_buf_type         type;
-       const struct ngene_format *fmt;
-
-       const struct ngene_format *ovfmt;
-       struct ngene_overlay       ov;
-};
-#endif
-
-struct ngene_channel {
-       struct device         device;
-       struct i2c_adapter    i2c_adapter;
-
-       struct ngene         *dev;
-       int                   number;
-       int                   type;
-       int                   mode;
-       bool                  has_adapter;
-       bool                  has_demux;
-       int                   demod_type;
-       int (*gate_ctrl)(struct dvb_frontend *, int);
-
-       struct dvb_frontend  *fe;
-       struct dvb_frontend  *fe2;
-       struct dmxdev         dmxdev;
-       struct dvb_demux      demux;
-       struct dvb_net        dvbnet;
-       struct dmx_frontend   hw_frontend;
-       struct dmx_frontend   mem_frontend;
-       int                   users;
-       struct video_device  *v4l_dev;
-       struct dvb_device    *ci_dev;
-       struct tasklet_struct demux_tasklet;
-
-       struct SBufferHeader *nextBuffer;
-       enum KSSTATE          State;
-       enum HWSTATE          HWState;
-       u8                    Stream;
-       u8                    Flags;
-       u8                    Mode;
-       IBufferExchange      *pBufferExchange;
-       IBufferExchange      *pBufferExchange2;
-
-       spinlock_t            state_lock;
-       u16                   nLines;
-       u16                   nBytesPerLine;
-       u16                   nVBILines;
-       u16                   nBytesPerVBILine;
-       u16                   itumode;
-       u32                   Capture1Length;
-       u32                   Capture2Length;
-       struct SRingBufferDescriptor RingBuffer;
-       struct SRingBufferDescriptor TSRingBuffer;
-       struct SRingBufferDescriptor TSIdleBuffer;
-
-       u32                   DataFormatFlags;
-
-       int                   AudioDTOUpdated;
-       u32                   AudioDTOValue;
-
-       int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t);
-       u8 lnbh;
-
-       /* stuff from analog driver */
-
-       int minor;
-       struct mychip        *mychip;
-       struct snd_card      *soundcard;
-       u8                   *evenbuffer;
-       u8                    dma_on;
-       int                   soundstreamon;
-       int                   audiomute;
-       int                   soundbuffisallocated;
-       int                   sndbuffflag;
-       int                   tun_rdy;
-       int                   dec_rdy;
-       int                   tun_dec_rdy;
-       int                   lastbufferflag;
-
-       struct ngene_tvnorm  *tvnorms;
-       int                   tvnorm_num;
-       int                   tvnorm;
-
-#ifdef NGENE_V4L
-       int                   videousers;
-       struct v4l2_prio_state prio;
-       struct ngene_vopen    init;
-       int                   resources;
-       struct v4l2_framebuffer fbuf;
-       struct ngene_buffer  *screen;     /* overlay             */
-       struct list_head      capture;    /* video capture queue */
-       spinlock_t s_lock;
-       struct semaphore reslock;
-#endif
-
-       int running;
-};
-
-
-struct ngene_ci {
-       struct device         device;
-       struct i2c_adapter    i2c_adapter;
-
-       struct ngene         *dev;
-       struct dvb_ca_en50221 *en;
-};
-
-struct ngene;
-
-typedef void (rx_cb_t)(struct ngene *, u32, u8);
-typedef void (tx_cb_t)(struct ngene *, u32);
-
-struct ngene {
-       int                   nr;
-       struct pci_dev       *pci_dev;
-       unsigned char        *iomem;
-
-       /*struct i2c_adapter  i2c_adapter;*/
-
-       u32                   device_version;
-       u32                   fw_interface_version;
-       u32                   icounts;
-       bool                  msi_enabled;
-       bool                  cmd_timeout_workaround;
-
-       u8                   *CmdDoneByte;
-       int                   BootFirmware;
-       void                 *OverflowBuffer;
-       dma_addr_t            PAOverflowBuffer;
-       void                 *FWInterfaceBuffer;
-       dma_addr_t            PAFWInterfaceBuffer;
-       u8                   *ngenetohost;
-       u8                   *hosttongene;
-
-       struct EVENT_BUFFER   EventQueue[EVENT_QUEUE_SIZE];
-       int                   EventQueueOverflowCount;
-       int                   EventQueueOverflowFlag;
-       struct tasklet_struct event_tasklet;
-       struct EVENT_BUFFER  *EventBuffer;
-       int                   EventQueueWriteIndex;
-       int                   EventQueueReadIndex;
-
-       wait_queue_head_t     cmd_wq;
-       int                   cmd_done;
-       struct semaphore      cmd_mutex;
-       struct semaphore      stream_mutex;
-       struct semaphore      pll_mutex;
-       struct semaphore      i2c_switch_mutex;
-       int                   i2c_current_channel;
-       int                   i2c_current_bus;
-       spinlock_t            cmd_lock;
-
-       struct dvb_adapter    adapter[MAX_STREAM];
-       struct dvb_adapter    *first_adapter; /* "one_adapter" modprobe opt */
-       struct ngene_channel  channel[MAX_STREAM];
-
-       struct ngene_info    *card_info;
-
-       tx_cb_t              *TxEventNotify;
-       rx_cb_t              *RxEventNotify;
-       int                   tx_busy;
-       wait_queue_head_t     tx_wq;
-       wait_queue_head_t     rx_wq;
-#define UART_RBUF_LEN 4096
-       u8                    uart_rbuf[UART_RBUF_LEN];
-       int                   uart_rp, uart_wp;
-
-#define TS_FILLER  0x6f
-
-       u8                   *tsout_buf;
-#define TSOUT_BUF_SIZE (512*188*8)
-       struct dvb_ringbuffer tsout_rbuf;
-
-       u8                   *tsin_buf;
-#define TSIN_BUF_SIZE (512*188*8)
-       struct dvb_ringbuffer tsin_rbuf;
-
-       u8                   *ain_buf;
-#define AIN_BUF_SIZE (128*1024)
-       struct dvb_ringbuffer ain_rbuf;
-
-
-       u8                   *vin_buf;
-#define VIN_BUF_SIZE (4*1920*1080)
-       struct dvb_ringbuffer vin_rbuf;
-
-       unsigned long         exp_val;
-       int prev_cmd;
-
-       struct ngene_ci       ci;
-};
-
-struct ngene_info {
-       int   type;
-#define NGENE_APP        0
-#define NGENE_TERRATEC   1
-#define NGENE_SIDEWINDER 2
-#define NGENE_RACER      3
-#define NGENE_VIPER      4
-#define NGENE_PYTHON     5
-#define NGENE_VBOX_V1   6
-#define NGENE_VBOX_V2   7
-
-       int   fw_version;
-       bool  msi_supported;
-       char *name;
-
-       int   io_type[MAX_STREAM];
-#define NGENE_IO_NONE    0
-#define NGENE_IO_TV      1
-#define NGENE_IO_HDTV    2
-#define NGENE_IO_TSIN    4
-#define NGENE_IO_TSOUT   8
-#define NGENE_IO_AIN     16
-
-       void *fe_config[4];
-       void *tuner_config[4];
-
-       int (*demod_attach[4])(struct ngene_channel *);
-       int (*tuner_attach[4])(struct ngene_channel *);
-
-       u8    avf[4];
-       u8    msp[4];
-       u8    demoda[4];
-       u8    lnb[4];
-       int   i2c_access;
-       u8    ntsc;
-       u8    tsf[4];
-       u8    i2s[4];
-
-       int (*gate_ctrl)(struct dvb_frontend *, int);
-       int (*switch_ctrl)(struct ngene_channel *, int, int);
-};
-
-#ifdef NGENE_V4L
-struct ngene_format {
-       char *name;
-       int   fourcc;          /* video4linux 2      */
-       int   btformat;        /* BT848_COLOR_FMT_*  */
-       int   format;
-       int   btswap;          /* BT848_COLOR_CTL_*  */
-       int   depth;           /* bit/pixel          */
-       int   flags;
-       int   hshift, vshift;  /* for planar modes   */
-       int   palette;
-};
-
-#define RESOURCE_OVERLAY       1
-#define RESOURCE_VIDEO         2
-#define RESOURCE_VBI           4
-
-struct ngene_buffer {
-       /* common v4l buffer stuff -- must be first */
-       struct videobuf_buffer     vb;
-
-       /* ngene specific */
-       const struct ngene_format *fmt;
-       int                        tvnorm;
-       int                        btformat;
-       int                        btswap;
-};
-#endif
-
-
-/* Provided by ngene-core.c */
-int __devinit ngene_probe(struct pci_dev *pci_dev,
-                         const struct pci_device_id *id);
-void __devexit ngene_remove(struct pci_dev *pdev);
-void ngene_shutdown(struct pci_dev *pdev);
-int ngene_command(struct ngene *dev, struct ngene_command *com);
-int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level);
-void set_transfer(struct ngene_channel *chan, int state);
-void FillTSBuffer(void *Buffer, int Length, u32 Flags);
-
-/* Provided by ngene-i2c.c */
-int ngene_i2c_init(struct ngene *dev, int dev_nr);
-
-/* Provided by ngene-dvb.c */
-extern struct dvb_device ngene_dvbdev_ci;
-void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
-void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
-int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed);
-int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
-int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
-                           int (*start_feed)(struct dvb_demux_feed *),
-                           int (*stop_feed)(struct dvb_demux_feed *),
-                           void *priv);
-int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
-                              struct dvb_demux *dvbdemux,
-                              struct dmx_frontend *hw_frontend,
-                              struct dmx_frontend *mem_frontend,
-                              struct dvb_adapter *dvb_adapter);
-
-#endif
-
-/*  LocalWords:  Endif
- */
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
deleted file mode 100644 (file)
index 7d8e6e8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-config DVB_PLUTO2
-       tristate "Pluto2 cards"
-       depends on DVB_CORE && PCI && I2C
-       select I2C_ALGOBIT
-       select DVB_TDA1004X
-       help
-         Support for PCI cards based on the Pluto2 FPGA like the Satelco
-         Easywatch Mobile Terrestrial DVB-T Receiver.
-
-         Since these cards have no MPEG decoder onboard, they transmit
-         only compressed MPEG data over the PCI bus, so you need
-         an external software decoder to watch TV on your computer.
-
-         Say Y or M if you own such a device and want to use it.
-
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile
deleted file mode 100644 (file)
index 524bf84..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
deleted file mode 100644 (file)
index f148b19..0000000
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
- *
- * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
- *
- * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
- *     by Dany Salman <salmandany@yahoo.fr>
- *     Copyright (c) 2004 TDF
- *
- * 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/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
-#include "tda1004x.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define DRIVER_NAME            "pluto2"
-
-#define REG_PIDn(n)            ((n) << 2)      /* PID n pattern registers */
-#define REG_PCAR               0x0020          /* PC address register */
-#define REG_TSCR               0x0024          /* TS ctrl & status */
-#define REG_MISC               0x0028          /* miscellaneous */
-#define REG_MMAC               0x002c          /* MSB MAC address */
-#define REG_IMAC               0x0030          /* ISB MAC address */
-#define REG_LMAC               0x0034          /* LSB MAC address */
-#define REG_SPID               0x0038          /* SPI data */
-#define REG_SLCS               0x003c          /* serial links ctrl/status */
-
-#define PID0_NOFIL             (0x0001 << 16)
-#define PIDn_ENP               (0x0001 << 15)
-#define PID0_END               (0x0001 << 14)
-#define PID0_AFIL              (0x0001 << 13)
-#define PIDn_PID               (0x1fff <<  0)
-
-#define TSCR_NBPACKETS         (0x00ff << 24)
-#define TSCR_DEM               (0x0001 << 17)
-#define TSCR_DE                        (0x0001 << 16)
-#define TSCR_RSTN              (0x0001 << 15)
-#define TSCR_MSKO              (0x0001 << 14)
-#define TSCR_MSKA              (0x0001 << 13)
-#define TSCR_MSKL              (0x0001 << 12)
-#define TSCR_OVR               (0x0001 << 11)
-#define TSCR_AFUL              (0x0001 << 10)
-#define TSCR_LOCK              (0x0001 <<  9)
-#define TSCR_IACK              (0x0001 <<  8)
-#define TSCR_ADEF              (0x007f <<  0)
-
-#define MISC_DVR               (0x0fff <<  4)
-#define MISC_ALED              (0x0001 <<  3)
-#define MISC_FRST              (0x0001 <<  2)
-#define MISC_LED1              (0x0001 <<  1)
-#define MISC_LED0              (0x0001 <<  0)
-
-#define SPID_SPIDR             (0x00ff <<  0)
-
-#define SLCS_SCL               (0x0001 <<  7)
-#define SLCS_SDA               (0x0001 <<  6)
-#define SLCS_CSN               (0x0001 <<  2)
-#define SLCS_OVR               (0x0001 <<  1)
-#define SLCS_SWC               (0x0001 <<  0)
-
-#define TS_DMA_PACKETS         (8)
-#define TS_DMA_BYTES           (188 * TS_DMA_PACKETS)
-
-#define I2C_ADDR_TDA10046      0x10
-#define I2C_ADDR_TUA6034       0xc2
-#define NHWFILTERS             8
-
-struct pluto {
-       /* pci */
-       struct pci_dev *pdev;
-       u8 __iomem *io_mem;
-
-       /* dvb */
-       struct dmx_frontend hw_frontend;
-       struct dmx_frontend mem_frontend;
-       struct dmxdev dmxdev;
-       struct dvb_adapter dvb_adapter;
-       struct dvb_demux demux;
-       struct dvb_frontend *fe;
-       struct dvb_net dvbnet;
-       unsigned int full_ts_users;
-       unsigned int users;
-
-       /* i2c */
-       struct i2c_algo_bit_data i2c_bit;
-       struct i2c_adapter i2c_adap;
-       unsigned int i2cbug;
-
-       /* irq */
-       unsigned int overflow;
-       unsigned int dead;
-
-       /* dma */
-       dma_addr_t dma_addr;
-       u8 dma_buf[TS_DMA_BYTES];
-       u8 dummy[4096];
-};
-
-static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
-{
-       return container_of(feed->demux, struct pluto, demux);
-}
-
-static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
-{
-       return container_of(fe->dvb, struct pluto, dvb_adapter);
-}
-
-static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
-{
-       return readl(&pluto->io_mem[reg]);
-}
-
-static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
-{
-       writel(val, &pluto->io_mem[reg]);
-}
-
-static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
-{
-       u32 val = readl(&pluto->io_mem[reg]);
-       val &= ~mask;
-       val |= bits;
-       writel(val, &pluto->io_mem[reg]);
-}
-
-static void pluto_write_tscr(struct pluto *pluto, u32 val)
-{
-       /* set the number of packets */
-       val &= ~TSCR_ADEF;
-       val |= TS_DMA_PACKETS / 2;
-
-       pluto_writereg(pluto, REG_TSCR, val);
-}
-
-static void pluto_setsda(void *data, int state)
-{
-       struct pluto *pluto = data;
-
-       if (state)
-               pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
-       else
-               pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
-}
-
-static void pluto_setscl(void *data, int state)
-{
-       struct pluto *pluto = data;
-
-       if (state)
-               pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
-       else
-               pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
-
-       /* try to detect i2c_inb() to workaround hardware bug:
-        * reset SDA to high after SCL has been set to low */
-       if ((state) && (pluto->i2cbug == 0)) {
-               pluto->i2cbug = 1;
-       } else {
-               if ((!state) && (pluto->i2cbug == 1))
-                       pluto_setsda(pluto, 1);
-               pluto->i2cbug = 0;
-       }
-}
-
-static int pluto_getsda(void *data)
-{
-       struct pluto *pluto = data;
-
-       return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
-}
-
-static int pluto_getscl(void *data)
-{
-       struct pluto *pluto = data;
-
-       return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
-}
-
-static void pluto_reset_frontend(struct pluto *pluto, int reenable)
-{
-       u32 val = pluto_readreg(pluto, REG_MISC);
-
-       if (val & MISC_FRST) {
-               val &= ~MISC_FRST;
-               pluto_writereg(pluto, REG_MISC, val);
-       }
-       if (reenable) {
-               val |= MISC_FRST;
-               pluto_writereg(pluto, REG_MISC, val);
-       }
-}
-
-static void pluto_reset_ts(struct pluto *pluto, int reenable)
-{
-       u32 val = pluto_readreg(pluto, REG_TSCR);
-
-       if (val & TSCR_RSTN) {
-               val &= ~TSCR_RSTN;
-               pluto_write_tscr(pluto, val);
-       }
-       if (reenable) {
-               val |= TSCR_RSTN;
-               pluto_write_tscr(pluto, val);
-       }
-}
-
-static void pluto_set_dma_addr(struct pluto *pluto)
-{
-       pluto_writereg(pluto, REG_PCAR, pluto->dma_addr);
-}
-
-static int __devinit pluto_dma_map(struct pluto *pluto)
-{
-       pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
-                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
-
-       return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr);
-}
-
-static void pluto_dma_unmap(struct pluto *pluto)
-{
-       pci_unmap_single(pluto->pdev, pluto->dma_addr,
-                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
-}
-
-static int pluto_start_feed(struct dvb_demux_feed *f)
-{
-       struct pluto *pluto = feed_to_pluto(f);
-
-       /* enable PID filtering */
-       if (pluto->users++ == 0)
-               pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
-
-       if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
-               pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
-       else if (pluto->full_ts_users++ == 0)
-               pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
-
-       return 0;
-}
-
-static int pluto_stop_feed(struct dvb_demux_feed *f)
-{
-       struct pluto *pluto = feed_to_pluto(f);
-
-       /* disable PID filtering */
-       if (--pluto->users == 0)
-               pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
-
-       if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
-               pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
-       else if (--pluto->full_ts_users == 0)
-               pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
-
-       return 0;
-}
-
-static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
-{
-       /* synchronize the DMA transfer with the CPU
-        * first so that we see updated contents. */
-       pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
-                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
-
-       /* Workaround for broken hardware:
-        * [1] On startup NBPACKETS seems to contain an uninitialized value,
-        *     but no packets have been transferred.
-        * [2] Sometimes (actually very often) NBPACKETS stays at zero
-        *     although one packet has been transferred.
-        * [3] Sometimes (actually rarely), the card gets into an erroneous
-        *     mode where it continuously generates interrupts, claiming it
-        *     has received nbpackets>TS_DMA_PACKETS packets, but no packet
-        *     has been transferred. Only a reset seems to solve this
-        */
-       if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
-               unsigned int i = 0;
-               while (pluto->dma_buf[i] == 0x47)
-                       i += 188;
-               nbpackets = i / 188;
-               if (i == 0) {
-                       pluto_reset_ts(pluto, 1);
-                       dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
-               }
-       }
-
-       dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
-
-       /* clear the dma buffer. this is needed to be able to identify
-        * new valid ts packets above */
-       memset(pluto->dma_buf, 0, nbpackets * 188);
-
-       /* reset the dma address */
-       pluto_set_dma_addr(pluto);
-
-       /* sync the buffer and give it back to the card */
-       pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
-                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
-}
-
-static irqreturn_t pluto_irq(int irq, void *dev_id)
-{
-       struct pluto *pluto = dev_id;
-       u32 tscr;
-
-       /* check whether an interrupt occurred on this device */
-       tscr = pluto_readreg(pluto, REG_TSCR);
-       if (!(tscr & (TSCR_DE | TSCR_OVR)))
-               return IRQ_NONE;
-
-       if (tscr == 0xffffffff) {
-               if (pluto->dead == 0)
-                       dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
-               /* It's dead Jim */
-               pluto->dead = 1;
-               return IRQ_HANDLED;
-       }
-
-       /* dma end interrupt */
-       if (tscr & TSCR_DE) {
-               pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
-               /* overflow interrupt */
-               if (tscr & TSCR_OVR)
-                       pluto->overflow++;
-               if (pluto->overflow) {
-                       dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
-                                       pluto->overflow);
-                       pluto_reset_ts(pluto, 1);
-                       pluto->overflow = 0;
-               }
-       } else if (tscr & TSCR_OVR) {
-               pluto->overflow++;
-       }
-
-       /* ACK the interrupt */
-       pluto_write_tscr(pluto, tscr | TSCR_IACK);
-
-       return IRQ_HANDLED;
-}
-
-static void __devinit pluto_enable_irqs(struct pluto *pluto)
-{
-       u32 val = pluto_readreg(pluto, REG_TSCR);
-
-       /* disable AFUL and LOCK interrupts */
-       val |= (TSCR_MSKA | TSCR_MSKL);
-       /* enable DMA and OVERFLOW interrupts */
-       val &= ~(TSCR_DEM | TSCR_MSKO);
-       /* clear pending interrupts */
-       val |= TSCR_IACK;
-
-       pluto_write_tscr(pluto, val);
-}
-
-static void pluto_disable_irqs(struct pluto *pluto)
-{
-       u32 val = pluto_readreg(pluto, REG_TSCR);
-
-       /* disable all interrupts */
-       val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
-       /* clear pending interrupts */
-       val |= TSCR_IACK;
-
-       pluto_write_tscr(pluto, val);
-}
-
-static int __devinit pluto_hw_init(struct pluto *pluto)
-{
-       pluto_reset_frontend(pluto, 1);
-
-       /* set automatic LED control by FPGA */
-       pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
-
-       /* set data endianess */
-#ifdef __LITTLE_ENDIAN
-       pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
-#else
-       pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
-#endif
-       /* map DMA and set address */
-       pluto_dma_map(pluto);
-       pluto_set_dma_addr(pluto);
-
-       /* enable interrupts */
-       pluto_enable_irqs(pluto);
-
-       /* reset TS logic */
-       pluto_reset_ts(pluto, 1);
-
-       return 0;
-}
-
-static void pluto_hw_exit(struct pluto *pluto)
-{
-       /* disable interrupts */
-       pluto_disable_irqs(pluto);
-
-       pluto_reset_ts(pluto, 0);
-
-       /* LED: disable automatic control, enable yellow, disable green */
-       pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
-
-       /* unmap DMA */
-       pluto_dma_unmap(pluto);
-
-       pluto_reset_frontend(pluto, 0);
-}
-
-static inline u32 divide(u32 numerator, u32 denominator)
-{
-       if (denominator == 0)
-               return ~0;
-
-       return DIV_ROUND_CLOSEST(numerator, denominator);
-}
-
-/* LG Innotek TDTE-E001P (Infineon TUA6034) */
-static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct pluto *pluto = frontend_to_pluto(fe);
-       struct i2c_msg msg;
-       int ret;
-       u8 buf[4];
-       u32 div;
-
-       // Fref = 166.667 Hz
-       // Fref * 3 = 500.000 Hz
-       // IF = 36166667
-       // IF / Fref = 217
-       //div = divide(p->frequency + 36166667, 166667);
-       div = divide(p->frequency * 3, 500000) + 217;
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = (div >> 0) & 0xff;
-
-       if (p->frequency < 611000000)
-               buf[2] = 0xb4;
-       else if (p->frequency < 811000000)
-               buf[2] = 0xbc;
-       else
-               buf[2] = 0xf4;
-
-       // VHF: 174-230 MHz
-       // center: 350 MHz
-       // UHF: 470-862 MHz
-       if (p->frequency < 350000000)
-               buf[3] = 0x02;
-       else
-               buf[3] = 0x04;
-
-       if (p->bandwidth_hz == 8000000)
-               buf[3] |= 0x08;
-
-       msg.addr = I2C_ADDR_TUA6034 >> 1;
-       msg.flags = 0;
-       msg.buf = buf;
-       msg.len = sizeof(buf);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
-       if (ret < 0)
-               return ret;
-       else if (ret == 0)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int pluto2_request_firmware(struct dvb_frontend *fe,
-                                  const struct firmware **fw, char *name)
-{
-       struct pluto *pluto = frontend_to_pluto(fe);
-
-       return request_firmware(fw, name, &pluto->pdev->dev);
-}
-
-static struct tda1004x_config pluto2_fe_config __devinitdata = {
-       .demod_address = I2C_ADDR_TDA10046 >> 1,
-       .invert = 1,
-       .invert_oclk = 0,
-       .xtal_freq = TDA10046_XTAL_16M,
-       .agc_config = TDA10046_AGC_DEFAULT,
-       .if_freq = TDA10046_FREQ_3617,
-       .request_firmware = pluto2_request_firmware,
-};
-
-static int __devinit frontend_init(struct pluto *pluto)
-{
-       int ret;
-
-       pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
-       if (!pluto->fe) {
-               dev_err(&pluto->pdev->dev, "could not attach frontend\n");
-               return -ENODEV;
-       }
-       pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params;
-
-       ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
-       if (ret < 0) {
-               if (pluto->fe->ops.release)
-                       pluto->fe->ops.release(pluto->fe);
-               return ret;
-       }
-
-       return 0;
-}
-
-static void __devinit pluto_read_rev(struct pluto *pluto)
-{
-       u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
-       dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
-                       (val >> 12) & 0x0f, (val >> 4) & 0xff);
-}
-
-static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
-{
-       u32 val = pluto_readreg(pluto, REG_MMAC);
-       mac[0] = (val >> 8) & 0xff;
-       mac[1] = (val >> 0) & 0xff;
-
-       val = pluto_readreg(pluto, REG_IMAC);
-       mac[2] = (val >> 8) & 0xff;
-       mac[3] = (val >> 0) & 0xff;
-
-       val = pluto_readreg(pluto, REG_LMAC);
-       mac[4] = (val >> 8) & 0xff;
-       mac[5] = (val >> 0) & 0xff;
-
-       dev_info(&pluto->pdev->dev, "MAC %pM\n", mac);
-}
-
-static int __devinit pluto_read_serial(struct pluto *pluto)
-{
-       struct pci_dev *pdev = pluto->pdev;
-       unsigned int i, j;
-       u8 __iomem *cis;
-
-       cis = pci_iomap(pdev, 1, 0);
-       if (!cis)
-               return -EIO;
-
-       dev_info(&pdev->dev, "S/N ");
-
-       for (i = 0xe0; i < 0x100; i += 4) {
-               u32 val = readl(&cis[i]);
-               for (j = 0; j < 32; j += 8) {
-                       if ((val & 0xff) == 0xff)
-                               goto out;
-                       printk("%c", val & 0xff);
-                       val >>= 8;
-               }
-       }
-out:
-       printk("\n");
-       pci_iounmap(pdev, cis);
-
-       return 0;
-}
-
-static int __devinit pluto2_probe(struct pci_dev *pdev,
-                                 const struct pci_device_id *ent)
-{
-       struct pluto *pluto;
-       struct dvb_adapter *dvb_adapter;
-       struct dvb_demux *dvbdemux;
-       struct dmx_demux *dmx;
-       int ret = -ENOMEM;
-
-       pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL);
-       if (!pluto)
-               goto out;
-
-       pluto->pdev = pdev;
-
-       ret = pci_enable_device(pdev);
-       if (ret < 0)
-               goto err_kfree;
-
-       /* enable interrupts */
-       pci_write_config_dword(pdev, 0x6c, 0x8000);
-
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       pci_set_master(pdev);
-
-       ret = pci_request_regions(pdev, DRIVER_NAME);
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       pluto->io_mem = pci_iomap(pdev, 0, 0x40);
-       if (!pluto->io_mem) {
-               ret = -EIO;
-               goto err_pci_release_regions;
-       }
-
-       pci_set_drvdata(pdev, pluto);
-
-       ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto);
-       if (ret < 0)
-               goto err_pci_iounmap;
-
-       ret = pluto_hw_init(pluto);
-       if (ret < 0)
-               goto err_free_irq;
-
-       /* i2c */
-       i2c_set_adapdata(&pluto->i2c_adap, pluto);
-       strcpy(pluto->i2c_adap.name, DRIVER_NAME);
-       pluto->i2c_adap.owner = THIS_MODULE;
-       pluto->i2c_adap.dev.parent = &pdev->dev;
-       pluto->i2c_adap.algo_data = &pluto->i2c_bit;
-       pluto->i2c_bit.data = pluto;
-       pluto->i2c_bit.setsda = pluto_setsda;
-       pluto->i2c_bit.setscl = pluto_setscl;
-       pluto->i2c_bit.getsda = pluto_getsda;
-       pluto->i2c_bit.getscl = pluto_getscl;
-       pluto->i2c_bit.udelay = 10;
-       pluto->i2c_bit.timeout = 10;
-
-       /* Raise SCL and SDA */
-       pluto_setsda(pluto, 1);
-       pluto_setscl(pluto, 1);
-
-       ret = i2c_bit_add_bus(&pluto->i2c_adap);
-       if (ret < 0)
-               goto err_pluto_hw_exit;
-
-       /* dvb */
-       ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME,
-                                  THIS_MODULE, &pdev->dev, adapter_nr);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       dvb_adapter = &pluto->dvb_adapter;
-
-       pluto_read_rev(pluto);
-       pluto_read_serial(pluto);
-       pluto_read_mac(pluto, dvb_adapter->proposed_mac);
-
-       dvbdemux = &pluto->demux;
-       dvbdemux->filternum = 256;
-       dvbdemux->feednum = 256;
-       dvbdemux->start_feed = pluto_start_feed;
-       dvbdemux->stop_feed = pluto_stop_feed;
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
-                       DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-       ret = dvb_dmx_init(dvbdemux);
-       if (ret < 0)
-               goto err_dvb_unregister_adapter;
-
-       dmx = &dvbdemux->dmx;
-
-       pluto->hw_frontend.source = DMX_FRONTEND_0;
-       pluto->mem_frontend.source = DMX_MEMORY_FE;
-       pluto->dmxdev.filternum = NHWFILTERS;
-       pluto->dmxdev.demux = dmx;
-
-       ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
-       if (ret < 0)
-               goto err_dvb_dmx_release;
-
-       ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
-       if (ret < 0)
-               goto err_dvb_dmxdev_release;
-
-       ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
-       if (ret < 0)
-               goto err_remove_hw_frontend;
-
-       ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
-       if (ret < 0)
-               goto err_remove_mem_frontend;
-
-       ret = frontend_init(pluto);
-       if (ret < 0)
-               goto err_disconnect_frontend;
-
-       dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
-out:
-       return ret;
-
-err_disconnect_frontend:
-       dmx->disconnect_frontend(dmx);
-err_remove_mem_frontend:
-       dmx->remove_frontend(dmx, &pluto->mem_frontend);
-err_remove_hw_frontend:
-       dmx->remove_frontend(dmx, &pluto->hw_frontend);
-err_dvb_dmxdev_release:
-       dvb_dmxdev_release(&pluto->dmxdev);
-err_dvb_dmx_release:
-       dvb_dmx_release(dvbdemux);
-err_dvb_unregister_adapter:
-       dvb_unregister_adapter(dvb_adapter);
-err_i2c_del_adapter:
-       i2c_del_adapter(&pluto->i2c_adap);
-err_pluto_hw_exit:
-       pluto_hw_exit(pluto);
-err_free_irq:
-       free_irq(pdev->irq, pluto);
-err_pci_iounmap:
-       pci_iounmap(pdev, pluto->io_mem);
-err_pci_release_regions:
-       pci_release_regions(pdev);
-err_pci_disable_device:
-       pci_disable_device(pdev);
-err_kfree:
-       pci_set_drvdata(pdev, NULL);
-       kfree(pluto);
-       goto out;
-}
-
-static void __devexit pluto2_remove(struct pci_dev *pdev)
-{
-       struct pluto *pluto = pci_get_drvdata(pdev);
-       struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
-       struct dvb_demux *dvbdemux = &pluto->demux;
-       struct dmx_demux *dmx = &dvbdemux->dmx;
-
-       dmx->close(dmx);
-       dvb_net_release(&pluto->dvbnet);
-       if (pluto->fe)
-               dvb_unregister_frontend(pluto->fe);
-
-       dmx->disconnect_frontend(dmx);
-       dmx->remove_frontend(dmx, &pluto->mem_frontend);
-       dmx->remove_frontend(dmx, &pluto->hw_frontend);
-       dvb_dmxdev_release(&pluto->dmxdev);
-       dvb_dmx_release(dvbdemux);
-       dvb_unregister_adapter(dvb_adapter);
-       i2c_del_adapter(&pluto->i2c_adap);
-       pluto_hw_exit(pluto);
-       free_irq(pdev->irq, pluto);
-       pci_iounmap(pdev, pluto->io_mem);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
-       kfree(pluto);
-}
-
-#ifndef PCI_VENDOR_ID_SCM
-#define PCI_VENDOR_ID_SCM      0x0432
-#endif
-#ifndef PCI_DEVICE_ID_PLUTO2
-#define PCI_DEVICE_ID_PLUTO2   0x0001
-#endif
-
-static struct pci_device_id pluto2_id_table[] __devinitdata = {
-       {
-               .vendor = PCI_VENDOR_ID_SCM,
-               .device = PCI_DEVICE_ID_PLUTO2,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       }, {
-               /* empty */
-       },
-};
-
-MODULE_DEVICE_TABLE(pci, pluto2_id_table);
-
-static struct pci_driver pluto2_driver = {
-       .name = DRIVER_NAME,
-       .id_table = pluto2_id_table,
-       .probe = pluto2_probe,
-       .remove = __devexit_p(pluto2_remove),
-};
-
-static int __init pluto2_init(void)
-{
-       return pci_register_driver(&pluto2_driver);
-}
-
-static void __exit pluto2_exit(void)
-{
-       pci_unregister_driver(&pluto2_driver);
-}
-
-module_init(pluto2_init);
-module_exit(pluto2_exit);
-
-MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
-MODULE_DESCRIPTION("Pluto2 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/dvb/pt1/Kconfig
deleted file mode 100644 (file)
index 24501d5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-config DVB_PT1
-       tristate "PT1 cards"
-       depends on DVB_CORE && PCI && I2C
-       help
-         Support for Earthsoft PT1 PCI cards.
-
-         Since these cards have no MPEG decoder onboard, they transmit
-         only compressed MPEG data over the PCI bus, so you need
-         an external software decoder to watch TV on your computer.
-
-         Say Y or M if you own such a device and want to use it.
-
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile
deleted file mode 100644 (file)
index 98e3912..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
-
-obj-$(CONFIG_DVB_PT1) += earth-pt1.o
-
-ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
deleted file mode 100644 (file)
index 15b35c4..0000000
+++ /dev/null
@@ -1,1246 +0,0 @@
-/*
- * driver for Earthsoft PT1/PT2
- *
- * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
- *
- * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
- *
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/pci.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/ratelimit.h>
-
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
-
-#include "va1j5jf8007t.h"
-#include "va1j5jf8007s.h"
-
-#define DRIVER_NAME "earth-pt1"
-
-#define PT1_PAGE_SHIFT 12
-#define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT)
-#define PT1_NR_UPACKETS 1024
-#define PT1_NR_BUFS 511
-
-struct pt1_buffer_page {
-       __le32 upackets[PT1_NR_UPACKETS];
-};
-
-struct pt1_table_page {
-       __le32 next_pfn;
-       __le32 buf_pfns[PT1_NR_BUFS];
-};
-
-struct pt1_buffer {
-       struct pt1_buffer_page *page;
-       dma_addr_t addr;
-};
-
-struct pt1_table {
-       struct pt1_table_page *page;
-       dma_addr_t addr;
-       struct pt1_buffer bufs[PT1_NR_BUFS];
-};
-
-#define PT1_NR_ADAPS 4
-
-struct pt1_adapter;
-
-struct pt1 {
-       struct pci_dev *pdev;
-       void __iomem *regs;
-       struct i2c_adapter i2c_adap;
-       int i2c_running;
-       struct pt1_adapter *adaps[PT1_NR_ADAPS];
-       struct pt1_table *tables;
-       struct task_struct *kthread;
-       int table_index;
-       int buf_index;
-
-       struct mutex lock;
-       int power;
-       int reset;
-};
-
-struct pt1_adapter {
-       struct pt1 *pt1;
-       int index;
-
-       u8 *buf;
-       int upacket_count;
-       int packet_count;
-       int st_count;
-
-       struct dvb_adapter adap;
-       struct dvb_demux demux;
-       int users;
-       struct dmxdev dmxdev;
-       struct dvb_frontend *fe;
-       int (*orig_set_voltage)(struct dvb_frontend *fe,
-                               fe_sec_voltage_t voltage);
-       int (*orig_sleep)(struct dvb_frontend *fe);
-       int (*orig_init)(struct dvb_frontend *fe);
-
-       fe_sec_voltage_t voltage;
-       int sleep;
-};
-
-#define pt1_printk(level, pt1, format, arg...) \
-       dev_printk(level, &(pt1)->pdev->dev, format, ##arg)
-
-static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
-{
-       writel(data, pt1->regs + reg * 4);
-}
-
-static u32 pt1_read_reg(struct pt1 *pt1, int reg)
-{
-       return readl(pt1->regs + reg * 4);
-}
-
-static int pt1_nr_tables = 8;
-module_param_named(nr_tables, pt1_nr_tables, int, 0);
-
-static void pt1_increment_table_count(struct pt1 *pt1)
-{
-       pt1_write_reg(pt1, 0, 0x00000020);
-}
-
-static void pt1_init_table_count(struct pt1 *pt1)
-{
-       pt1_write_reg(pt1, 0, 0x00000010);
-}
-
-static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn)
-{
-       pt1_write_reg(pt1, 5, first_pfn);
-       pt1_write_reg(pt1, 0, 0x0c000040);
-}
-
-static void pt1_unregister_tables(struct pt1 *pt1)
-{
-       pt1_write_reg(pt1, 0, 0x08080000);
-}
-
-static int pt1_sync(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < 57; i++) {
-               if (pt1_read_reg(pt1, 0) & 0x20000000)
-                       return 0;
-               pt1_write_reg(pt1, 0, 0x00000008);
-       }
-       pt1_printk(KERN_ERR, pt1, "could not sync\n");
-       return -EIO;
-}
-
-static u64 pt1_identify(struct pt1 *pt1)
-{
-       int i;
-       u64 id;
-       id = 0;
-       for (i = 0; i < 57; i++) {
-               id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i;
-               pt1_write_reg(pt1, 0, 0x00000008);
-       }
-       return id;
-}
-
-static int pt1_unlock(struct pt1 *pt1)
-{
-       int i;
-       pt1_write_reg(pt1, 0, 0x00000008);
-       for (i = 0; i < 3; i++) {
-               if (pt1_read_reg(pt1, 0) & 0x80000000)
-                       return 0;
-               schedule_timeout_uninterruptible((HZ + 999) / 1000);
-       }
-       pt1_printk(KERN_ERR, pt1, "could not unlock\n");
-       return -EIO;
-}
-
-static int pt1_reset_pci(struct pt1 *pt1)
-{
-       int i;
-       pt1_write_reg(pt1, 0, 0x01010000);
-       pt1_write_reg(pt1, 0, 0x01000000);
-       for (i = 0; i < 10; i++) {
-               if (pt1_read_reg(pt1, 0) & 0x00000001)
-                       return 0;
-               schedule_timeout_uninterruptible((HZ + 999) / 1000);
-       }
-       pt1_printk(KERN_ERR, pt1, "could not reset PCI\n");
-       return -EIO;
-}
-
-static int pt1_reset_ram(struct pt1 *pt1)
-{
-       int i;
-       pt1_write_reg(pt1, 0, 0x02020000);
-       pt1_write_reg(pt1, 0, 0x02000000);
-       for (i = 0; i < 10; i++) {
-               if (pt1_read_reg(pt1, 0) & 0x00000002)
-                       return 0;
-               schedule_timeout_uninterruptible((HZ + 999) / 1000);
-       }
-       pt1_printk(KERN_ERR, pt1, "could not reset RAM\n");
-       return -EIO;
-}
-
-static int pt1_do_enable_ram(struct pt1 *pt1)
-{
-       int i, j;
-       u32 status;
-       status = pt1_read_reg(pt1, 0) & 0x00000004;
-       pt1_write_reg(pt1, 0, 0x00000002);
-       for (i = 0; i < 10; i++) {
-               for (j = 0; j < 1024; j++) {
-                       if ((pt1_read_reg(pt1, 0) & 0x00000004) != status)
-                               return 0;
-               }
-               schedule_timeout_uninterruptible((HZ + 999) / 1000);
-       }
-       pt1_printk(KERN_ERR, pt1, "could not enable RAM\n");
-       return -EIO;
-}
-
-static int pt1_enable_ram(struct pt1 *pt1)
-{
-       int i, ret;
-       int phase;
-       schedule_timeout_uninterruptible((HZ + 999) / 1000);
-       phase = pt1->pdev->device == 0x211a ? 128 : 166;
-       for (i = 0; i < phase; i++) {
-               ret = pt1_do_enable_ram(pt1);
-               if (ret < 0)
-                       return ret;
-       }
-       return 0;
-}
-
-static void pt1_disable_ram(struct pt1 *pt1)
-{
-       pt1_write_reg(pt1, 0, 0x0b0b0000);
-}
-
-static void pt1_set_stream(struct pt1 *pt1, int index, int enabled)
-{
-       pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index);
-}
-
-static void pt1_init_streams(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < PT1_NR_ADAPS; i++)
-               pt1_set_stream(pt1, i, 0);
-}
-
-static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
-{
-       u32 upacket;
-       int i;
-       int index;
-       struct pt1_adapter *adap;
-       int offset;
-       u8 *buf;
-       int sc;
-
-       if (!page->upackets[PT1_NR_UPACKETS - 1])
-               return 0;
-
-       for (i = 0; i < PT1_NR_UPACKETS; i++) {
-               upacket = le32_to_cpu(page->upackets[i]);
-               index = (upacket >> 29) - 1;
-               if (index < 0 || index >=  PT1_NR_ADAPS)
-                       continue;
-
-               adap = pt1->adaps[index];
-               if (upacket >> 25 & 1)
-                       adap->upacket_count = 0;
-               else if (!adap->upacket_count)
-                       continue;
-
-               if (upacket >> 24 & 1)
-                       printk_ratelimited(KERN_INFO "earth-pt1: device "
-                               "buffer overflowing. table[%d] buf[%d]\n",
-                               pt1->table_index, pt1->buf_index);
-               sc = upacket >> 26 & 0x7;
-               if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7))
-                       printk_ratelimited(KERN_INFO "earth-pt1: data loss"
-                               " in streamID(adapter)[%d]\n", index);
-               adap->st_count = sc;
-
-               buf = adap->buf;
-               offset = adap->packet_count * 188 + adap->upacket_count * 3;
-               buf[offset] = upacket >> 16;
-               buf[offset + 1] = upacket >> 8;
-               if (adap->upacket_count != 62)
-                       buf[offset + 2] = upacket;
-
-               if (++adap->upacket_count >= 63) {
-                       adap->upacket_count = 0;
-                       if (++adap->packet_count >= 21) {
-                               dvb_dmx_swfilter_packets(&adap->demux, buf, 21);
-                               adap->packet_count = 0;
-                       }
-               }
-       }
-
-       page->upackets[PT1_NR_UPACKETS - 1] = 0;
-       return 1;
-}
-
-static int pt1_thread(void *data)
-{
-       struct pt1 *pt1;
-       struct pt1_buffer_page *page;
-
-       pt1 = data;
-       set_freezable();
-
-       while (!kthread_should_stop()) {
-               try_to_freeze();
-
-               page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
-               if (!pt1_filter(pt1, page)) {
-                       schedule_timeout_interruptible((HZ + 999) / 1000);
-                       continue;
-               }
-
-               if (++pt1->buf_index >= PT1_NR_BUFS) {
-                       pt1_increment_table_count(pt1);
-                       pt1->buf_index = 0;
-                       if (++pt1->table_index >= pt1_nr_tables)
-                               pt1->table_index = 0;
-               }
-       }
-
-       return 0;
-}
-
-static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr)
-{
-       dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr);
-}
-
-static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp)
-{
-       void *page;
-       dma_addr_t addr;
-
-       page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr,
-                                 GFP_KERNEL);
-       if (page == NULL)
-               return NULL;
-
-       BUG_ON(addr & (PT1_PAGE_SIZE - 1));
-       BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1);
-
-       *addrp = addr;
-       *pfnp = addr >> PT1_PAGE_SHIFT;
-       return page;
-}
-
-static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf)
-{
-       pt1_free_page(pt1, buf->page, buf->addr);
-}
-
-static int
-pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf,  u32 *pfnp)
-{
-       struct pt1_buffer_page *page;
-       dma_addr_t addr;
-
-       page = pt1_alloc_page(pt1, &addr, pfnp);
-       if (page == NULL)
-               return -ENOMEM;
-
-       page->upackets[PT1_NR_UPACKETS - 1] = 0;
-
-       buf->page = page;
-       buf->addr = addr;
-       return 0;
-}
-
-static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table)
-{
-       int i;
-
-       for (i = 0; i < PT1_NR_BUFS; i++)
-               pt1_cleanup_buffer(pt1, &table->bufs[i]);
-
-       pt1_free_page(pt1, table->page, table->addr);
-}
-
-static int
-pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp)
-{
-       struct pt1_table_page *page;
-       dma_addr_t addr;
-       int i, ret;
-       u32 buf_pfn;
-
-       page = pt1_alloc_page(pt1, &addr, pfnp);
-       if (page == NULL)
-               return -ENOMEM;
-
-       for (i = 0; i < PT1_NR_BUFS; i++) {
-               ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn);
-               if (ret < 0)
-                       goto err;
-
-               page->buf_pfns[i] = cpu_to_le32(buf_pfn);
-       }
-
-       pt1_increment_table_count(pt1);
-       table->page = page;
-       table->addr = addr;
-       return 0;
-
-err:
-       while (i--)
-               pt1_cleanup_buffer(pt1, &table->bufs[i]);
-
-       pt1_free_page(pt1, page, addr);
-       return ret;
-}
-
-static void pt1_cleanup_tables(struct pt1 *pt1)
-{
-       struct pt1_table *tables;
-       int i;
-
-       tables = pt1->tables;
-       pt1_unregister_tables(pt1);
-
-       for (i = 0; i < pt1_nr_tables; i++)
-               pt1_cleanup_table(pt1, &tables[i]);
-
-       vfree(tables);
-}
-
-static int pt1_init_tables(struct pt1 *pt1)
-{
-       struct pt1_table *tables;
-       int i, ret;
-       u32 first_pfn, pfn;
-
-       tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
-       if (tables == NULL)
-               return -ENOMEM;
-
-       pt1_init_table_count(pt1);
-
-       i = 0;
-       if (pt1_nr_tables) {
-               ret = pt1_init_table(pt1, &tables[0], &first_pfn);
-               if (ret)
-                       goto err;
-               i++;
-       }
-
-       while (i < pt1_nr_tables) {
-               ret = pt1_init_table(pt1, &tables[i], &pfn);
-               if (ret)
-                       goto err;
-               tables[i - 1].page->next_pfn = cpu_to_le32(pfn);
-               i++;
-       }
-
-       tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn);
-
-       pt1_register_tables(pt1, first_pfn);
-       pt1->tables = tables;
-       return 0;
-
-err:
-       while (i--)
-               pt1_cleanup_table(pt1, &tables[i]);
-
-       vfree(tables);
-       return ret;
-}
-
-static int pt1_start_polling(struct pt1 *pt1)
-{
-       int ret = 0;
-
-       mutex_lock(&pt1->lock);
-       if (!pt1->kthread) {
-               pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1");
-               if (IS_ERR(pt1->kthread)) {
-                       ret = PTR_ERR(pt1->kthread);
-                       pt1->kthread = NULL;
-               }
-       }
-       mutex_unlock(&pt1->lock);
-       return ret;
-}
-
-static int pt1_start_feed(struct dvb_demux_feed *feed)
-{
-       struct pt1_adapter *adap;
-       adap = container_of(feed->demux, struct pt1_adapter, demux);
-       if (!adap->users++) {
-               int ret;
-
-               ret = pt1_start_polling(adap->pt1);
-               if (ret)
-                       return ret;
-               pt1_set_stream(adap->pt1, adap->index, 1);
-       }
-       return 0;
-}
-
-static void pt1_stop_polling(struct pt1 *pt1)
-{
-       int i, count;
-
-       mutex_lock(&pt1->lock);
-       for (i = 0, count = 0; i < PT1_NR_ADAPS; i++)
-               count += pt1->adaps[i]->users;
-
-       if (count == 0 && pt1->kthread) {
-               kthread_stop(pt1->kthread);
-               pt1->kthread = NULL;
-       }
-       mutex_unlock(&pt1->lock);
-}
-
-static int pt1_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct pt1_adapter *adap;
-       adap = container_of(feed->demux, struct pt1_adapter, demux);
-       if (!--adap->users) {
-               pt1_set_stream(adap->pt1, adap->index, 0);
-               pt1_stop_polling(adap->pt1);
-       }
-       return 0;
-}
-
-static void
-pt1_update_power(struct pt1 *pt1)
-{
-       int bits;
-       int i;
-       struct pt1_adapter *adap;
-       static const int sleep_bits[] = {
-               1 << 4,
-               1 << 6 | 1 << 7,
-               1 << 5,
-               1 << 6 | 1 << 8,
-       };
-
-       bits = pt1->power | !pt1->reset << 3;
-       mutex_lock(&pt1->lock);
-       for (i = 0; i < PT1_NR_ADAPS; i++) {
-               adap = pt1->adaps[i];
-               switch (adap->voltage) {
-               case SEC_VOLTAGE_13: /* actually 11V */
-                       bits |= 1 << 1;
-                       break;
-               case SEC_VOLTAGE_18: /* actually 15V */
-                       bits |= 1 << 1 | 1 << 2;
-                       break;
-               default:
-                       break;
-               }
-
-               /* XXX: The bits should be changed depending on adap->sleep. */
-               bits |= sleep_bits[i];
-       }
-       pt1_write_reg(pt1, 1, bits);
-       mutex_unlock(&pt1->lock);
-}
-
-static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct pt1_adapter *adap;
-
-       adap = container_of(fe->dvb, struct pt1_adapter, adap);
-       adap->voltage = voltage;
-       pt1_update_power(adap->pt1);
-
-       if (adap->orig_set_voltage)
-               return adap->orig_set_voltage(fe, voltage);
-       else
-               return 0;
-}
-
-static int pt1_sleep(struct dvb_frontend *fe)
-{
-       struct pt1_adapter *adap;
-
-       adap = container_of(fe->dvb, struct pt1_adapter, adap);
-       adap->sleep = 1;
-       pt1_update_power(adap->pt1);
-
-       if (adap->orig_sleep)
-               return adap->orig_sleep(fe);
-       else
-               return 0;
-}
-
-static int pt1_wakeup(struct dvb_frontend *fe)
-{
-       struct pt1_adapter *adap;
-
-       adap = container_of(fe->dvb, struct pt1_adapter, adap);
-       adap->sleep = 0;
-       pt1_update_power(adap->pt1);
-       schedule_timeout_uninterruptible((HZ + 999) / 1000);
-
-       if (adap->orig_init)
-               return adap->orig_init(fe);
-       else
-               return 0;
-}
-
-static void pt1_free_adapter(struct pt1_adapter *adap)
-{
-       adap->demux.dmx.close(&adap->demux.dmx);
-       dvb_dmxdev_release(&adap->dmxdev);
-       dvb_dmx_release(&adap->demux);
-       dvb_unregister_adapter(&adap->adap);
-       free_page((unsigned long)adap->buf);
-       kfree(adap);
-}
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static struct pt1_adapter *
-pt1_alloc_adapter(struct pt1 *pt1)
-{
-       struct pt1_adapter *adap;
-       void *buf;
-       struct dvb_adapter *dvb_adap;
-       struct dvb_demux *demux;
-       struct dmxdev *dmxdev;
-       int ret;
-
-       adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL);
-       if (!adap) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       adap->pt1 = pt1;
-
-       adap->voltage = SEC_VOLTAGE_OFF;
-       adap->sleep = 1;
-
-       buf = (u8 *)__get_free_page(GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto err_kfree;
-       }
-
-       adap->buf = buf;
-       adap->upacket_count = 0;
-       adap->packet_count = 0;
-       adap->st_count = -1;
-
-       dvb_adap = &adap->adap;
-       dvb_adap->priv = adap;
-       ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE,
-                                  &pt1->pdev->dev, adapter_nr);
-       if (ret < 0)
-               goto err_free_page;
-
-       demux = &adap->demux;
-       demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       demux->priv = adap;
-       demux->feednum = 256;
-       demux->filternum = 256;
-       demux->start_feed = pt1_start_feed;
-       demux->stop_feed = pt1_stop_feed;
-       demux->write_to_decoder = NULL;
-       ret = dvb_dmx_init(demux);
-       if (ret < 0)
-               goto err_unregister_adapter;
-
-       dmxdev = &adap->dmxdev;
-       dmxdev->filternum = 256;
-       dmxdev->demux = &demux->dmx;
-       dmxdev->capabilities = 0;
-       ret = dvb_dmxdev_init(dmxdev, dvb_adap);
-       if (ret < 0)
-               goto err_dmx_release;
-
-       return adap;
-
-err_dmx_release:
-       dvb_dmx_release(demux);
-err_unregister_adapter:
-       dvb_unregister_adapter(dvb_adap);
-err_free_page:
-       free_page((unsigned long)buf);
-err_kfree:
-       kfree(adap);
-err:
-       return ERR_PTR(ret);
-}
-
-static void pt1_cleanup_adapters(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < PT1_NR_ADAPS; i++)
-               pt1_free_adapter(pt1->adaps[i]);
-}
-
-static int pt1_init_adapters(struct pt1 *pt1)
-{
-       int i;
-       struct pt1_adapter *adap;
-       int ret;
-
-       for (i = 0; i < PT1_NR_ADAPS; i++) {
-               adap = pt1_alloc_adapter(pt1);
-               if (IS_ERR(adap)) {
-                       ret = PTR_ERR(adap);
-                       goto err;
-               }
-
-               adap->index = i;
-               pt1->adaps[i] = adap;
-       }
-       return 0;
-
-err:
-       while (i--)
-               pt1_free_adapter(pt1->adaps[i]);
-
-       return ret;
-}
-
-static void pt1_cleanup_frontend(struct pt1_adapter *adap)
-{
-       dvb_unregister_frontend(adap->fe);
-}
-
-static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe)
-{
-       int ret;
-
-       adap->orig_set_voltage = fe->ops.set_voltage;
-       adap->orig_sleep = fe->ops.sleep;
-       adap->orig_init = fe->ops.init;
-       fe->ops.set_voltage = pt1_set_voltage;
-       fe->ops.sleep = pt1_sleep;
-       fe->ops.init = pt1_wakeup;
-
-       ret = dvb_register_frontend(&adap->adap, fe);
-       if (ret < 0)
-               return ret;
-
-       adap->fe = fe;
-       return 0;
-}
-
-static void pt1_cleanup_frontends(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < PT1_NR_ADAPS; i++)
-               pt1_cleanup_frontend(pt1->adaps[i]);
-}
-
-struct pt1_config {
-       struct va1j5jf8007s_config va1j5jf8007s_config;
-       struct va1j5jf8007t_config va1j5jf8007t_config;
-};
-
-static const struct pt1_config pt1_configs[2] = {
-       {
-               {
-                       .demod_address = 0x1b,
-                       .frequency = VA1J5JF8007S_20MHZ,
-               },
-               {
-                       .demod_address = 0x1a,
-                       .frequency = VA1J5JF8007T_20MHZ,
-               },
-       }, {
-               {
-                       .demod_address = 0x19,
-                       .frequency = VA1J5JF8007S_20MHZ,
-               },
-               {
-                       .demod_address = 0x18,
-                       .frequency = VA1J5JF8007T_20MHZ,
-               },
-       },
-};
-
-static const struct pt1_config pt2_configs[2] = {
-       {
-               {
-                       .demod_address = 0x1b,
-                       .frequency = VA1J5JF8007S_25MHZ,
-               },
-               {
-                       .demod_address = 0x1a,
-                       .frequency = VA1J5JF8007T_25MHZ,
-               },
-       }, {
-               {
-                       .demod_address = 0x19,
-                       .frequency = VA1J5JF8007S_25MHZ,
-               },
-               {
-                       .demod_address = 0x18,
-                       .frequency = VA1J5JF8007T_25MHZ,
-               },
-       },
-};
-
-static int pt1_init_frontends(struct pt1 *pt1)
-{
-       int i, j;
-       struct i2c_adapter *i2c_adap;
-       const struct pt1_config *configs, *config;
-       struct dvb_frontend *fe[4];
-       int ret;
-
-       i = 0;
-       j = 0;
-
-       i2c_adap = &pt1->i2c_adap;
-       configs = pt1->pdev->device == 0x211a ? pt1_configs : pt2_configs;
-       do {
-               config = &configs[i / 2];
-
-               fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
-                                           i2c_adap);
-               if (!fe[i]) {
-                       ret = -ENODEV; /* This does not sound nice... */
-                       goto err;
-               }
-               i++;
-
-               fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config,
-                                           i2c_adap);
-               if (!fe[i]) {
-                       ret = -ENODEV;
-                       goto err;
-               }
-               i++;
-
-               ret = va1j5jf8007s_prepare(fe[i - 2]);
-               if (ret < 0)
-                       goto err;
-
-               ret = va1j5jf8007t_prepare(fe[i - 1]);
-               if (ret < 0)
-                       goto err;
-
-       } while (i < 4);
-
-       do {
-               ret = pt1_init_frontend(pt1->adaps[j], fe[j]);
-               if (ret < 0)
-                       goto err;
-       } while (++j < 4);
-
-       return 0;
-
-err:
-       while (i-- > j)
-               fe[i]->ops.release(fe[i]);
-
-       while (j--)
-               dvb_unregister_frontend(fe[j]);
-
-       return ret;
-}
-
-static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable,
-                        int clock, int data, int next_addr)
-{
-       pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 |
-                     !clock << 11 | !data << 10 | next_addr);
-}
-
-static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data)
-{
-       pt1_i2c_emit(pt1, addr,     1, 0, 0, data, addr + 1);
-       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2);
-       pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3);
-       *addrp = addr + 3;
-}
-
-static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp)
-{
-       pt1_i2c_emit(pt1, addr,     1, 0, 0, 1, addr + 1);
-       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2);
-       pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3);
-       pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4);
-       *addrp = addr + 4;
-}
-
-static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data)
-{
-       int i;
-       for (i = 0; i < 8; i++)
-               pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1);
-       pt1_i2c_write_bit(pt1, addr, &addr, 1);
-       *addrp = addr;
-}
-
-static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last)
-{
-       int i;
-       for (i = 0; i < 8; i++)
-               pt1_i2c_read_bit(pt1, addr, &addr);
-       pt1_i2c_write_bit(pt1, addr, &addr, last);
-       *addrp = addr;
-}
-
-static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp)
-{
-       pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
-       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
-       pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3);
-       *addrp = addr + 3;
-}
-
-static void
-pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
-{
-       int i;
-       pt1_i2c_prepare(pt1, addr, &addr);
-       pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1);
-       for (i = 0; i < msg->len; i++)
-               pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]);
-       *addrp = addr;
-}
-
-static void
-pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
-{
-       int i;
-       pt1_i2c_prepare(pt1, addr, &addr);
-       pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1);
-       for (i = 0; i < msg->len; i++)
-               pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1);
-       *addrp = addr;
-}
-
-static int pt1_i2c_end(struct pt1 *pt1, int addr)
-{
-       pt1_i2c_emit(pt1, addr,     1, 0, 0, 0, addr + 1);
-       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
-       pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0);
-
-       pt1_write_reg(pt1, 0, 0x00000004);
-       do {
-               if (signal_pending(current))
-                       return -EINTR;
-               schedule_timeout_interruptible((HZ + 999) / 1000);
-       } while (pt1_read_reg(pt1, 0) & 0x00000080);
-       return 0;
-}
-
-static void pt1_i2c_begin(struct pt1 *pt1, int *addrp)
-{
-       int addr;
-       addr = 0;
-
-       pt1_i2c_emit(pt1, addr,     0, 0, 1, 1, addr /* itself */);
-       addr = addr + 1;
-
-       if (!pt1->i2c_running) {
-               pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
-               pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
-               addr = addr + 2;
-               pt1->i2c_running = 1;
-       }
-       *addrp = addr;
-}
-
-static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
-       struct pt1 *pt1;
-       int i;
-       struct i2c_msg *msg, *next_msg;
-       int addr, ret;
-       u16 len;
-       u32 word;
-
-       pt1 = i2c_get_adapdata(adap);
-
-       for (i = 0; i < num; i++) {
-               msg = &msgs[i];
-               if (msg->flags & I2C_M_RD)
-                       return -ENOTSUPP;
-
-               if (i + 1 < num)
-                       next_msg = &msgs[i + 1];
-               else
-                       next_msg = NULL;
-
-               if (next_msg && next_msg->flags & I2C_M_RD) {
-                       i++;
-
-                       len = next_msg->len;
-                       if (len > 4)
-                               return -ENOTSUPP;
-
-                       pt1_i2c_begin(pt1, &addr);
-                       pt1_i2c_write_msg(pt1, addr, &addr, msg);
-                       pt1_i2c_read_msg(pt1, addr, &addr, next_msg);
-                       ret = pt1_i2c_end(pt1, addr);
-                       if (ret < 0)
-                               return ret;
-
-                       word = pt1_read_reg(pt1, 2);
-                       while (len--) {
-                               next_msg->buf[len] = word;
-                               word >>= 8;
-                       }
-               } else {
-                       pt1_i2c_begin(pt1, &addr);
-                       pt1_i2c_write_msg(pt1, addr, &addr, msg);
-                       ret = pt1_i2c_end(pt1, addr);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return num;
-}
-
-static u32 pt1_i2c_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C;
-}
-
-static const struct i2c_algorithm pt1_i2c_algo = {
-       .master_xfer = pt1_i2c_xfer,
-       .functionality = pt1_i2c_func,
-};
-
-static void pt1_i2c_wait(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < 128; i++)
-               pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0);
-}
-
-static void pt1_i2c_init(struct pt1 *pt1)
-{
-       int i;
-       for (i = 0; i < 1024; i++)
-               pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
-}
-
-static void __devexit pt1_remove(struct pci_dev *pdev)
-{
-       struct pt1 *pt1;
-       void __iomem *regs;
-
-       pt1 = pci_get_drvdata(pdev);
-       regs = pt1->regs;
-
-       if (pt1->kthread)
-               kthread_stop(pt1->kthread);
-       pt1_cleanup_tables(pt1);
-       pt1_cleanup_frontends(pt1);
-       pt1_disable_ram(pt1);
-       pt1->power = 0;
-       pt1->reset = 1;
-       pt1_update_power(pt1);
-       pt1_cleanup_adapters(pt1);
-       i2c_del_adapter(&pt1->i2c_adap);
-       pci_set_drvdata(pdev, NULL);
-       kfree(pt1);
-       pci_iounmap(pdev, regs);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-}
-
-static int __devinit
-pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       int ret;
-       void __iomem *regs;
-       struct pt1 *pt1;
-       struct i2c_adapter *i2c_adap;
-
-       ret = pci_enable_device(pdev);
-       if (ret < 0)
-               goto err;
-
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       pci_set_master(pdev);
-
-       ret = pci_request_regions(pdev, DRIVER_NAME);
-       if (ret < 0)
-               goto err_pci_disable_device;
-
-       regs = pci_iomap(pdev, 0, 0);
-       if (!regs) {
-               ret = -EIO;
-               goto err_pci_release_regions;
-       }
-
-       pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL);
-       if (!pt1) {
-               ret = -ENOMEM;
-               goto err_pci_iounmap;
-       }
-
-       mutex_init(&pt1->lock);
-       pt1->pdev = pdev;
-       pt1->regs = regs;
-       pci_set_drvdata(pdev, pt1);
-
-       ret = pt1_init_adapters(pt1);
-       if (ret < 0)
-               goto err_kfree;
-
-       mutex_init(&pt1->lock);
-
-       pt1->power = 0;
-       pt1->reset = 1;
-       pt1_update_power(pt1);
-
-       i2c_adap = &pt1->i2c_adap;
-       i2c_adap->algo = &pt1_i2c_algo;
-       i2c_adap->algo_data = NULL;
-       i2c_adap->dev.parent = &pdev->dev;
-       strcpy(i2c_adap->name, DRIVER_NAME);
-       i2c_set_adapdata(i2c_adap, pt1);
-       ret = i2c_add_adapter(i2c_adap);
-       if (ret < 0)
-               goto err_pt1_cleanup_adapters;
-
-       pt1_i2c_init(pt1);
-       pt1_i2c_wait(pt1);
-
-       ret = pt1_sync(pt1);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       pt1_identify(pt1);
-
-       ret = pt1_unlock(pt1);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       ret = pt1_reset_pci(pt1);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       ret = pt1_reset_ram(pt1);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       ret = pt1_enable_ram(pt1);
-       if (ret < 0)
-               goto err_i2c_del_adapter;
-
-       pt1_init_streams(pt1);
-
-       pt1->power = 1;
-       pt1_update_power(pt1);
-       schedule_timeout_uninterruptible((HZ + 49) / 50);
-
-       pt1->reset = 0;
-       pt1_update_power(pt1);
-       schedule_timeout_uninterruptible((HZ + 999) / 1000);
-
-       ret = pt1_init_frontends(pt1);
-       if (ret < 0)
-               goto err_pt1_disable_ram;
-
-       ret = pt1_init_tables(pt1);
-       if (ret < 0)
-               goto err_pt1_cleanup_frontends;
-
-       return 0;
-
-err_pt1_cleanup_frontends:
-       pt1_cleanup_frontends(pt1);
-err_pt1_disable_ram:
-       pt1_disable_ram(pt1);
-       pt1->power = 0;
-       pt1->reset = 1;
-       pt1_update_power(pt1);
-err_i2c_del_adapter:
-       i2c_del_adapter(i2c_adap);
-err_pt1_cleanup_adapters:
-       pt1_cleanup_adapters(pt1);
-err_kfree:
-       pci_set_drvdata(pdev, NULL);
-       kfree(pt1);
-err_pci_iounmap:
-       pci_iounmap(pdev, regs);
-err_pci_release_regions:
-       pci_release_regions(pdev);
-err_pci_disable_device:
-       pci_disable_device(pdev);
-err:
-       return ret;
-
-}
-
-static struct pci_device_id pt1_id_table[] = {
-       { PCI_DEVICE(0x10ee, 0x211a) },
-       { PCI_DEVICE(0x10ee, 0x222a) },
-       { },
-};
-MODULE_DEVICE_TABLE(pci, pt1_id_table);
-
-static struct pci_driver pt1_driver = {
-       .name           = DRIVER_NAME,
-       .probe          = pt1_probe,
-       .remove         = __devexit_p(pt1_remove),
-       .id_table       = pt1_id_table,
-};
-
-
-static int __init pt1_init(void)
-{
-       return pci_register_driver(&pt1_driver);
-}
-
-
-static void __exit pt1_cleanup(void)
-{
-       pci_unregister_driver(&pt1_driver);
-}
-
-module_init(pt1_init);
-module_exit(pt1_cleanup);
-
-MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
-MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
deleted file mode 100644 (file)
index d980dfb..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
- *
- * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
- *
- * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
- *
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "va1j5jf8007s.h"
-
-enum va1j5jf8007s_tune_state {
-       VA1J5JF8007S_IDLE,
-       VA1J5JF8007S_SET_FREQUENCY_1,
-       VA1J5JF8007S_SET_FREQUENCY_2,
-       VA1J5JF8007S_SET_FREQUENCY_3,
-       VA1J5JF8007S_CHECK_FREQUENCY,
-       VA1J5JF8007S_SET_MODULATION,
-       VA1J5JF8007S_CHECK_MODULATION,
-       VA1J5JF8007S_SET_TS_ID,
-       VA1J5JF8007S_CHECK_TS_ID,
-       VA1J5JF8007S_TRACK,
-};
-
-struct va1j5jf8007s_state {
-       const struct va1j5jf8007s_config *config;
-       struct i2c_adapter *adap;
-       struct dvb_frontend fe;
-       enum va1j5jf8007s_tune_state tune_state;
-};
-
-static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct va1j5jf8007s_state *state;
-       u8 addr;
-       int i;
-       u8 write_buf[1], read_buf[1];
-       struct i2c_msg msgs[2];
-       s32 word, x1, x2, x3, x4, x5, y;
-
-       state = fe->demodulator_priv;
-       addr = state->config->demod_address;
-
-       word = 0;
-       for (i = 0; i < 2; i++) {
-               write_buf[0] = 0xbc + i;
-
-               msgs[0].addr = addr;
-               msgs[0].flags = 0;
-               msgs[0].len = sizeof(write_buf);
-               msgs[0].buf = write_buf;
-
-               msgs[1].addr = addr;
-               msgs[1].flags = I2C_M_RD;
-               msgs[1].len = sizeof(read_buf);
-               msgs[1].buf = read_buf;
-
-               if (i2c_transfer(state->adap, msgs, 2) != 2)
-                       return -EREMOTEIO;
-
-               word <<= 8;
-               word |= read_buf[0];
-       }
-
-       word -= 3000;
-       if (word < 0)
-               word = 0;
-
-       x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
-       x2 = (s64)x1 * x1 >> 31;
-       x3 = (s64)x2 * x1 >> 31;
-       x4 = (s64)x2 * x2 >> 31;
-       x5 = (s64)x4 * x1 >> 31;
-
-       y = (58857ll << 23) / 1000;
-       y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
-       y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
-       y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
-       y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
-       y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
-
-       *snr = y < 0 ? 0 : y >> 15;
-       return 0;
-}
-
-static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_HW;
-}
-
-static int
-va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct va1j5jf8007s_state *state;
-
-       state = fe->demodulator_priv;
-
-       switch (state->tune_state) {
-       case VA1J5JF8007S_IDLE:
-       case VA1J5JF8007S_SET_FREQUENCY_1:
-       case VA1J5JF8007S_SET_FREQUENCY_2:
-       case VA1J5JF8007S_SET_FREQUENCY_3:
-       case VA1J5JF8007S_CHECK_FREQUENCY:
-               *status = 0;
-               return 0;
-
-
-       case VA1J5JF8007S_SET_MODULATION:
-       case VA1J5JF8007S_CHECK_MODULATION:
-               *status |= FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007S_SET_TS_ID:
-       case VA1J5JF8007S_CHECK_TS_ID:
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
-               return 0;
-
-       case VA1J5JF8007S_TRACK:
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
-               return 0;
-       }
-
-       BUG();
-}
-
-struct va1j5jf8007s_cb_map {
-       u32 frequency;
-       u8 cb;
-};
-
-static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
-       {  986000, 0xb2 },
-       { 1072000, 0xd2 },
-       { 1154000, 0xe2 },
-       { 1291000, 0x20 },
-       { 1447000, 0x40 },
-       { 1615000, 0x60 },
-       { 1791000, 0x80 },
-       { 1972000, 0xa0 },
-};
-
-static u8 va1j5jf8007s_lookup_cb(u32 frequency)
-{
-       int i;
-       const struct va1j5jf8007s_cb_map *map;
-
-       for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
-               map = &va1j5jf8007s_cb_maps[i];
-               if (frequency < map->frequency)
-                       return map->cb;
-       }
-       return 0xc0;
-}
-
-static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
-{
-       u32 frequency;
-       u16 word;
-       u8 buf[6];
-       struct i2c_msg msg;
-
-       frequency = state->fe.dtv_property_cache.frequency;
-
-       word = (frequency + 500) / 1000;
-       if (frequency < 1072000)
-               word = (word << 1 & ~0x1f) | (word & 0x0f);
-
-       buf[0] = 0xfe;
-       buf[1] = 0xc0;
-       buf[2] = 0x40 | word >> 8;
-       buf[3] = word;
-       buf[4] = 0xe0;
-       buf[5] = va1j5jf8007s_lookup_cb(frequency);
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
-{
-       u8 buf[3];
-       struct i2c_msg msg;
-
-       buf[0] = 0xfe;
-       buf[1] = 0xc0;
-       buf[2] = 0xe4;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
-{
-       u32 frequency;
-       u8 buf[4];
-       struct i2c_msg msg;
-
-       frequency = state->fe.dtv_property_cache.frequency;
-
-       buf[0] = 0xfe;
-       buf[1] = 0xc0;
-       buf[2] = 0xf4;
-       buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int
-va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
-{
-       u8 addr;
-       u8 write_buf[2], read_buf[1];
-       struct i2c_msg msgs[2];
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0xfe;
-       write_buf[1] = 0xc1;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       *lock = read_buf[0] & 0x40;
-       return 0;
-}
-
-static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
-{
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       buf[0] = 0x03;
-       buf[1] = 0x01;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int
-va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
-{
-       u8 addr;
-       u8 write_buf[1], read_buf[1];
-       struct i2c_msg msgs[2];
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0xc3;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       *lock = !(read_buf[0] & 0x10);
-       return 0;
-}
-
-static int
-va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
-{
-       u32 ts_id;
-       u8 buf[3];
-       struct i2c_msg msg;
-
-       ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
-       if (!ts_id)
-               return 0;
-
-       buf[0] = 0x8f;
-       buf[1] = ts_id >> 8;
-       buf[2] = ts_id;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int
-va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
-{
-       u8 addr;
-       u8 write_buf[1], read_buf[2];
-       struct i2c_msg msgs[2];
-       u32 ts_id;
-
-       ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
-       if (!ts_id) {
-               *lock = 1;
-               return 0;
-       }
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0xe6;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
-       return 0;
-}
-
-static int
-va1j5jf8007s_tune(struct dvb_frontend *fe,
-                 bool re_tune,
-                 unsigned int mode_flags,  unsigned int *delay,
-                 fe_status_t *status)
-{
-       struct va1j5jf8007s_state *state;
-       int ret;
-       int lock = 0;
-
-       state = fe->demodulator_priv;
-
-       if (re_tune)
-               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
-
-       switch (state->tune_state) {
-       case VA1J5JF8007S_IDLE:
-               *delay = 3 * HZ;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007S_SET_FREQUENCY_1:
-               ret = va1j5jf8007s_set_frequency_1(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
-               *delay = 0;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007S_SET_FREQUENCY_2:
-               ret = va1j5jf8007s_set_frequency_2(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
-               *delay = (HZ + 99) / 100;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007S_SET_FREQUENCY_3:
-               ret = va1j5jf8007s_set_frequency_3(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
-               *delay = 0;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007S_CHECK_FREQUENCY:
-               ret = va1j5jf8007s_check_frequency(state, &lock);
-               if (ret < 0)
-                       return ret;
-
-               if (!lock)  {
-                       *delay = (HZ + 999) / 1000;
-                       *status = 0;
-                       return 0;
-               }
-
-               state->tune_state = VA1J5JF8007S_SET_MODULATION;
-               *delay = 0;
-               *status = FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007S_SET_MODULATION:
-               ret = va1j5jf8007s_set_modulation(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
-               *delay = 0;
-               *status = FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007S_CHECK_MODULATION:
-               ret = va1j5jf8007s_check_modulation(state, &lock);
-               if (ret < 0)
-                       return ret;
-
-               if (!lock)  {
-                       *delay = (HZ + 49) / 50;
-                       *status = FE_HAS_SIGNAL;
-                       return 0;
-               }
-
-               state->tune_state = VA1J5JF8007S_SET_TS_ID;
-               *delay = 0;
-               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
-               return 0;
-
-       case VA1J5JF8007S_SET_TS_ID:
-               ret = va1j5jf8007s_set_ts_id(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
-               return 0;
-
-       case VA1J5JF8007S_CHECK_TS_ID:
-               ret = va1j5jf8007s_check_ts_id(state, &lock);
-               if (ret < 0)
-                       return ret;
-
-               if (!lock)  {
-                       *delay = (HZ + 99) / 100;
-                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
-                       return 0;
-               }
-
-               state->tune_state = VA1J5JF8007S_TRACK;
-               /* fall through */
-
-       case VA1J5JF8007S_TRACK:
-               *delay = 3 * HZ;
-               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
-               return 0;
-       }
-
-       BUG();
-}
-
-static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
-{
-       u8 buf[4];
-       struct i2c_msg msg;
-
-       buf[0] = 0xfe;
-       buf[1] = 0xc0;
-       buf[2] = 0xf0;
-       buf[3] = 0x04;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
-{
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       buf[0] = 0x17;
-       buf[1] = sleep ? 0x01 : 0x00;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007s_state *state;
-       int ret;
-
-       state = fe->demodulator_priv;
-
-       ret = va1j5jf8007s_init_frequency(state);
-       if (ret < 0)
-               return ret;
-
-       return va1j5jf8007s_set_sleep(state, 1);
-}
-
-static int va1j5jf8007s_init(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007s_state *state;
-
-       state = fe->demodulator_priv;
-       state->tune_state = VA1J5JF8007S_IDLE;
-
-       return va1j5jf8007s_set_sleep(state, 0);
-}
-
-static void va1j5jf8007s_release(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007s_state *state;
-       state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops va1j5jf8007s_ops = {
-       .delsys = { SYS_ISDBS },
-       .info = {
-               .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1000,
-               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .read_snr = va1j5jf8007s_read_snr,
-       .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
-       .read_status = va1j5jf8007s_read_status,
-       .tune = va1j5jf8007s_tune,
-       .sleep = va1j5jf8007s_sleep,
-       .init = va1j5jf8007s_init,
-       .release = va1j5jf8007s_release,
-};
-
-static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
-{
-       u8 addr;
-       u8 write_buf[1], read_buf[1];
-       struct i2c_msg msgs[2];
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0x07;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       if (read_buf[0] != 0x41)
-               return -EIO;
-
-       return 0;
-}
-
-static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = {
-       {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
-       {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
-       {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
-       {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
-};
-
-static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = {
-       {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
-       {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
-       {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
-       {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
-};
-
-static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
-{
-       const u8 (*bufs)[2];
-       int size;
-       u8 addr;
-       u8 buf[2];
-       struct i2c_msg msg;
-       int i;
-
-       switch (state->config->frequency) {
-       case VA1J5JF8007S_20MHZ:
-               bufs = va1j5jf8007s_20mhz_prepare_bufs;
-               size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs);
-               break;
-       case VA1J5JF8007S_25MHZ:
-               bufs = va1j5jf8007s_25mhz_prepare_bufs;
-               size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       addr = state->config->demod_address;
-
-       msg.addr = addr;
-       msg.flags = 0;
-       msg.len = 2;
-       msg.buf = buf;
-       for (i = 0; i < size; i++) {
-               memcpy(buf, bufs[i], sizeof(buf));
-               if (i2c_transfer(state->adap, &msg, 1) != 1)
-                       return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-/* must be called after va1j5jf8007t_attach */
-int va1j5jf8007s_prepare(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007s_state *state;
-       int ret;
-
-       state = fe->demodulator_priv;
-
-       ret = va1j5jf8007s_prepare_1(state);
-       if (ret < 0)
-               return ret;
-
-       ret = va1j5jf8007s_prepare_2(state);
-       if (ret < 0)
-               return ret;
-
-       return va1j5jf8007s_init_frequency(state);
-}
-
-struct dvb_frontend *
-va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
-                   struct i2c_adapter *adap)
-{
-       struct va1j5jf8007s_state *state;
-       struct dvb_frontend *fe;
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       state->config = config;
-       state->adap = adap;
-
-       fe = &state->fe;
-       memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
-       fe->demodulator_priv = state;
-
-       buf[0] = 0x01;
-       buf[1] = 0x80;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1) {
-               kfree(state);
-               return NULL;
-       }
-
-       return fe;
-}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h
deleted file mode 100644 (file)
index b7d6f05..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
- *
- * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
- *
- * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
- *
- * 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 VA1J5JF8007S_H
-#define VA1J5JF8007S_H
-
-enum va1j5jf8007s_frequency {
-       VA1J5JF8007S_20MHZ,
-       VA1J5JF8007S_25MHZ,
-};
-
-struct va1j5jf8007s_config {
-       u8 demod_address;
-       enum va1j5jf8007s_frequency frequency;
-};
-
-struct i2c_adapter;
-
-struct dvb_frontend *
-va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
-                   struct i2c_adapter *adap);
-
-/* must be called after va1j5jf8007t_attach */
-int va1j5jf8007s_prepare(struct dvb_frontend *fe);
-
-#endif
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
deleted file mode 100644 (file)
index 2db1515..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
- *
- * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
- *
- * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
- *
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "va1j5jf8007t.h"
-
-enum va1j5jf8007t_tune_state {
-       VA1J5JF8007T_IDLE,
-       VA1J5JF8007T_SET_FREQUENCY,
-       VA1J5JF8007T_CHECK_FREQUENCY,
-       VA1J5JF8007T_SET_MODULATION,
-       VA1J5JF8007T_CHECK_MODULATION,
-       VA1J5JF8007T_TRACK,
-       VA1J5JF8007T_ABORT,
-};
-
-struct va1j5jf8007t_state {
-       const struct va1j5jf8007t_config *config;
-       struct i2c_adapter *adap;
-       struct dvb_frontend fe;
-       enum va1j5jf8007t_tune_state tune_state;
-};
-
-static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct va1j5jf8007t_state *state;
-       u8 addr;
-       int i;
-       u8 write_buf[1], read_buf[1];
-       struct i2c_msg msgs[2];
-       s32 word, x, y;
-
-       state = fe->demodulator_priv;
-       addr = state->config->demod_address;
-
-       word = 0;
-       for (i = 0; i < 3; i++) {
-               write_buf[0] = 0x8b + i;
-
-               msgs[0].addr = addr;
-               msgs[0].flags = 0;
-               msgs[0].len = sizeof(write_buf);
-               msgs[0].buf = write_buf;
-
-               msgs[1].addr = addr;
-               msgs[1].flags = I2C_M_RD;
-               msgs[1].len = sizeof(read_buf);
-               msgs[1].buf = read_buf;
-
-               if (i2c_transfer(state->adap, msgs, 2) != 2)
-                       return -EREMOTEIO;
-
-               word <<= 8;
-               word |= read_buf[0];
-       }
-
-       if (!word)
-               return -EIO;
-
-       x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
-       y = (24ll << 46) / 1000000;
-       y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
-       y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
-       y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
-       y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
-       *snr = y >> 15;
-       return 0;
-}
-
-static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_HW;
-}
-
-static int
-va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct va1j5jf8007t_state *state;
-
-       state = fe->demodulator_priv;
-
-       switch (state->tune_state) {
-       case VA1J5JF8007T_IDLE:
-       case VA1J5JF8007T_SET_FREQUENCY:
-       case VA1J5JF8007T_CHECK_FREQUENCY:
-               *status = 0;
-               return 0;
-
-
-       case VA1J5JF8007T_SET_MODULATION:
-       case VA1J5JF8007T_CHECK_MODULATION:
-       case VA1J5JF8007T_ABORT:
-               *status |= FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007T_TRACK:
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
-               return 0;
-       }
-
-       BUG();
-}
-
-struct va1j5jf8007t_cb_map {
-       u32 frequency;
-       u8 cb;
-};
-
-static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
-       {  90000000, 0x80 },
-       { 140000000, 0x81 },
-       { 170000000, 0xa1 },
-       { 220000000, 0x62 },
-       { 330000000, 0xa2 },
-       { 402000000, 0xe2 },
-       { 450000000, 0x64 },
-       { 550000000, 0x84 },
-       { 600000000, 0xa4 },
-       { 700000000, 0xc4 },
-};
-
-static u8 va1j5jf8007t_lookup_cb(u32 frequency)
-{
-       int i;
-       const struct va1j5jf8007t_cb_map *map;
-
-       for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
-               map = &va1j5jf8007t_cb_maps[i];
-               if (frequency < map->frequency)
-                       return map->cb;
-       }
-       return 0xe4;
-}
-
-static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
-{
-       u32 frequency;
-       u16 word;
-       u8 buf[6];
-       struct i2c_msg msg;
-
-       frequency = state->fe.dtv_property_cache.frequency;
-
-       word = (frequency + 71428) / 142857 + 399;
-       buf[0] = 0xfe;
-       buf[1] = 0xc2;
-       buf[2] = word >> 8;
-       buf[3] = word;
-       buf[4] = 0x80;
-       buf[5] = va1j5jf8007t_lookup_cb(frequency);
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int
-va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
-{
-       u8 addr;
-       u8 write_buf[2], read_buf[1];
-       struct i2c_msg msgs[2];
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0xfe;
-       write_buf[1] = 0xc3;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       *lock = read_buf[0] & 0x40;
-       return 0;
-}
-
-static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
-{
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       buf[0] = 0x01;
-       buf[1] = 0x40;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
-                                        int *lock, int *retry)
-{
-       u8 addr;
-       u8 write_buf[1], read_buf[1];
-       struct i2c_msg msgs[2];
-
-       addr = state->config->demod_address;
-
-       write_buf[0] = 0x80;
-
-       msgs[0].addr = addr;
-       msgs[0].flags = 0;
-       msgs[0].len = sizeof(write_buf);
-       msgs[0].buf = write_buf;
-
-       msgs[1].addr = addr;
-       msgs[1].flags = I2C_M_RD;
-       msgs[1].len = sizeof(read_buf);
-       msgs[1].buf = read_buf;
-
-       if (i2c_transfer(state->adap, msgs, 2) != 2)
-               return -EREMOTEIO;
-
-       *lock = !(read_buf[0] & 0x10);
-       *retry = read_buf[0] & 0x80;
-       return 0;
-}
-
-static int
-va1j5jf8007t_tune(struct dvb_frontend *fe,
-                 bool re_tune,
-                 unsigned int mode_flags,  unsigned int *delay,
-                 fe_status_t *status)
-{
-       struct va1j5jf8007t_state *state;
-       int ret;
-       int lock = 0, retry = 0;
-
-       state = fe->demodulator_priv;
-
-       if (re_tune)
-               state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
-
-       switch (state->tune_state) {
-       case VA1J5JF8007T_IDLE:
-               *delay = 3 * HZ;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007T_SET_FREQUENCY:
-               ret = va1j5jf8007t_set_frequency(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
-               *delay = 0;
-               *status = 0;
-               return 0;
-
-       case VA1J5JF8007T_CHECK_FREQUENCY:
-               ret = va1j5jf8007t_check_frequency(state, &lock);
-               if (ret < 0)
-                       return ret;
-
-               if (!lock)  {
-                       *delay = (HZ + 999) / 1000;
-                       *status = 0;
-                       return 0;
-               }
-
-               state->tune_state = VA1J5JF8007T_SET_MODULATION;
-               *delay = 0;
-               *status = FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007T_SET_MODULATION:
-               ret = va1j5jf8007t_set_modulation(state);
-               if (ret < 0)
-                       return ret;
-
-               state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
-               *delay = 0;
-               *status = FE_HAS_SIGNAL;
-               return 0;
-
-       case VA1J5JF8007T_CHECK_MODULATION:
-               ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
-               if (ret < 0)
-                       return ret;
-
-               if (!lock)  {
-                       if (!retry)  {
-                               state->tune_state = VA1J5JF8007T_ABORT;
-                               *delay = 3 * HZ;
-                               *status = FE_HAS_SIGNAL;
-                               return 0;
-                       }
-                       *delay = (HZ + 999) / 1000;
-                       *status = FE_HAS_SIGNAL;
-                       return 0;
-               }
-
-               state->tune_state = VA1J5JF8007T_TRACK;
-               /* fall through */
-
-       case VA1J5JF8007T_TRACK:
-               *delay = 3 * HZ;
-               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
-               return 0;
-
-       case VA1J5JF8007T_ABORT:
-               *delay = 3 * HZ;
-               *status = FE_HAS_SIGNAL;
-               return 0;
-       }
-
-       BUG();
-}
-
-static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
-{
-       u8 buf[7];
-       struct i2c_msg msg;
-
-       buf[0] = 0xfe;
-       buf[1] = 0xc2;
-       buf[2] = 0x01;
-       buf[3] = 0x8f;
-       buf[4] = 0xc1;
-       buf[5] = 0x80;
-       buf[6] = 0x80;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
-{
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       buf[0] = 0x03;
-       buf[1] = sleep ? 0x90 : 0x80;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007t_state *state;
-       int ret;
-
-       state = fe->demodulator_priv;
-
-       ret = va1j5jf8007t_init_frequency(state);
-       if (ret < 0)
-               return ret;
-
-       return va1j5jf8007t_set_sleep(state, 1);
-}
-
-static int va1j5jf8007t_init(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007t_state *state;
-
-       state = fe->demodulator_priv;
-       state->tune_state = VA1J5JF8007T_IDLE;
-
-       return va1j5jf8007t_set_sleep(state, 0);
-}
-
-static void va1j5jf8007t_release(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007t_state *state;
-       state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops va1j5jf8007t_ops = {
-       .delsys = { SYS_ISDBT },
-       .info = {
-               .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T",
-               .frequency_min = 90000000,
-               .frequency_max = 770000000,
-               .frequency_stepsize = 142857,
-               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .read_snr = va1j5jf8007t_read_snr,
-       .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
-       .read_status = va1j5jf8007t_read_status,
-       .tune = va1j5jf8007t_tune,
-       .sleep = va1j5jf8007t_sleep,
-       .init = va1j5jf8007t_init,
-       .release = va1j5jf8007t_release,
-};
-
-static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = {
-       {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
-       {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
-       {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
-       {0xef, 0x01}
-};
-
-static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = {
-       {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
-       {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
-       {0x77, 0x03}, {0xef, 0x01}
-};
-
-int va1j5jf8007t_prepare(struct dvb_frontend *fe)
-{
-       struct va1j5jf8007t_state *state;
-       const u8 (*bufs)[2];
-       int size;
-       u8 buf[2];
-       struct i2c_msg msg;
-       int i;
-
-       state = fe->demodulator_priv;
-
-       switch (state->config->frequency) {
-       case VA1J5JF8007T_20MHZ:
-               bufs = va1j5jf8007t_20mhz_prepare_bufs;
-               size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs);
-               break;
-       case VA1J5JF8007T_25MHZ:
-               bufs = va1j5jf8007t_25mhz_prepare_bufs;
-               size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       for (i = 0; i < size; i++) {
-               memcpy(buf, bufs[i], sizeof(buf));
-               if (i2c_transfer(state->adap, &msg, 1) != 1)
-                       return -EREMOTEIO;
-       }
-
-       return va1j5jf8007t_init_frequency(state);
-}
-
-struct dvb_frontend *
-va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
-                   struct i2c_adapter *adap)
-{
-       struct va1j5jf8007t_state *state;
-       struct dvb_frontend *fe;
-       u8 buf[2];
-       struct i2c_msg msg;
-
-       state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       state->config = config;
-       state->adap = adap;
-
-       fe = &state->fe;
-       memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
-       fe->demodulator_priv = state;
-
-       buf[0] = 0x01;
-       buf[1] = 0x80;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.len = sizeof(buf);
-       msg.buf = buf;
-
-       if (i2c_transfer(state->adap, &msg, 1) != 1) {
-               kfree(state);
-               return NULL;
-       }
-
-       return fe;
-}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h
deleted file mode 100644 (file)
index 2903be5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
- *
- * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
- *
- * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
- *
- * 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 VA1J5JF8007T_H
-#define VA1J5JF8007T_H
-
-enum va1j5jf8007t_frequency {
-       VA1J5JF8007T_20MHZ,
-       VA1J5JF8007T_25MHZ,
-};
-
-struct va1j5jf8007t_config {
-       u8 demod_address;
-       enum va1j5jf8007t_frequency frequency;
-};
-
-struct i2c_adapter;
-
-struct dvb_frontend *
-va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
-                   struct i2c_adapter *adap);
-
-/* must be called after va1j5jf8007s_attach */
-int va1j5jf8007t_prepare(struct dvb_frontend *fe);
-
-#endif
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
deleted file mode 100644 (file)
index 9d83ced..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-config TTPCI_EEPROM
-       tristate
-       depends on I2C
-       default n
-
-config DVB_AV7110
-       tristate "AV7110 cards"
-       depends on DVB_CORE && PCI && I2C
-       select TTPCI_EEPROM
-       select VIDEO_SAA7146_VV
-       depends on VIDEO_DEV    # dependencies of VIDEO_SAA7146_VV
-       select DVB_VES1820 if !DVB_FE_CUSTOMISE
-       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
-       select DVB_SP8870 if !DVB_FE_CUSTOMISE
-       select DVB_STV0297 if !DVB_FE_CUSTOMISE
-       select DVB_L64781 if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       help
-         Support for SAA7146 and AV7110 based DVB cards as produced
-         by Fujitsu-Siemens, Technotrend, Hauppauge and others.
-
-         This driver only supports the fullfeatured cards with
-         onboard MPEG2 decoder.
-
-         This driver needs an external firmware. Please use the script
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
-         download/extract it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-         Alternatively, you can download the file and use the kernel's
-         EXTRA_FIRMWARE configuration option to build it into your
-         kernel image by adding the filename to the EXTRA_FIRMWARE
-         configuration option string.
-
-         Say Y if you own such a card and want to use it.
-
-config DVB_AV7110_OSD
-       bool "AV7110 OSD support"
-       depends on DVB_AV7110
-       default y if DVB_AV7110=y || DVB_AV7110=m
-       help
-         The AV7110 firmware provides some code to generate an OnScreenDisplay
-         on the video output. This is kind of nonstandard and not guaranteed to
-         be maintained.
-
-         Anyway, some popular DVB software like VDR uses this OSD to render
-         its menus, so say Y if you want to use this software.
-
-         All other people say N.
-
-config DVB_BUDGET_CORE
-       tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)"
-       depends on DVB_CORE && PCI && I2C
-       select VIDEO_SAA7146
-       select TTPCI_EEPROM
-       help
-         Support for simple SAA7146 based DVB cards
-         (so called Budget- or Nova-PCI cards) without onboard
-         MPEG2 decoder.
-
-config DVB_BUDGET
-       tristate "Budget cards"
-       depends on DVB_BUDGET_CORE && I2C
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
-       select DVB_VES1820 if !DVB_FE_CUSTOMISE
-       select DVB_L64781 if !DVB_FE_CUSTOMISE
-       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
-       select DVB_S5H1420 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
-       select DVB_TDA826X if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
-       select DVB_STV090x if !DVB_FE_CUSTOMISE
-       select DVB_STV6110x if !DVB_FE_CUSTOMISE
-       help
-         Support for simple SAA7146 based DVB cards (so called Budget-
-         or Nova-PCI cards) without onboard MPEG2 decoder, and without
-         analog inputs or an onboard Common Interface connector.
-
-         Say Y if you own such a card and want to use it.
-
-         To compile this driver as a module, choose M here: the
-         module will be called budget.
-
-config DVB_BUDGET_CI
-       tristate "Budget cards with onboard CI connector"
-       depends on DVB_BUDGET_CORE && I2C
-       select DVB_STV0297 if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_STV0288 if !DVB_FE_CUSTOMISE
-       select DVB_STB6000 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
-       depends on RC_CORE
-       help
-         Support for simple SAA7146 based DVB cards
-         (so called Budget- or Nova-PCI cards) without onboard
-         MPEG2 decoder, but with onboard Common Interface connector.
-
-         Note: The Common Interface is not yet supported by this driver
-         due to lack of information from the vendor.
-
-         Say Y if you own such a card and want to use it.
-
-         To compile this driver as a module, choose M here: the
-         module will be called budget-ci.
-
-config DVB_BUDGET_AV
-       tristate "Budget cards with analog video inputs"
-       depends on DVB_BUDGET_CORE && I2C
-       select VIDEO_SAA7146_VV
-       depends on VIDEO_DEV    # dependencies of VIDEO_SAA7146_VV
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-       select DVB_TDA10021 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_TDA8261 if !DVB_FE_CUSTOMISE
-       select DVB_TUA6100 if !DVB_FE_CUSTOMISE
-       help
-         Support for simple SAA7146 based DVB cards
-         (so called Budget- or Nova-PCI cards) without onboard
-         MPEG2 decoder, but with one or more analog video inputs.
-
-         Say Y if you own such a card and want to use it.
-
-         To compile this driver as a module, choose M here: the
-         module will be called budget-av.
-
-config DVB_BUDGET_PATCH
-       tristate "AV7110 cards with Budget Patch"
-       depends on DVB_BUDGET_CORE && I2C
-       depends on DVB_AV7110
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
-       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
-       help
-         Support for Budget Patch (full TS) modification on
-         SAA7146+AV7110 based cards (DVB-S cards). This
-         driver doesn't use onboard MPEG2 decoder. The
-         card is driven in Budget-only mode. Card is
-         required to have loaded firmware to tune properly.
-         Firmware can be loaded by insertion and removal of
-         standard AV7110 driver prior to loading this
-         driver.
-
-         Say Y if you own such a card and want to use it.
-
-         To compile this driver as a module, choose M here: the
-         module will be called budget-patch.
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
deleted file mode 100644 (file)
index 22a235f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile for the kernel SAA7146 FULL TS DVB device driver
-# and the AV7110 DVB device driver
-#
-
-dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o
-
-ifdef CONFIG_INPUT_EVDEV
-dvb-ttpci-objs += av7110_ir.o
-endif
-
-obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o
-obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o
-obj-$(CONFIG_DVB_BUDGET) += budget.o
-obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o
-obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
-obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
-obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
deleted file mode 100644 (file)
index 4bd8bd5..0000000
+++ /dev/null
@@ -1,2939 +0,0 @@
-/*
- * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
- * av7110.c: initialization and demux stuff
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * originally based on code by:
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/timer.h>
-#include <linux/poll.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-#include <linux/crc32.h>
-#include <linux/i2c.h>
-#include <linux/kthread.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-
-
-#include <linux/dvb/frontend.h>
-
-#include "dvb_frontend.h"
-
-#include "ttpci-eeprom.h"
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "av7110_av.h"
-#include "av7110_ca.h"
-#include "av7110_ipack.h"
-
-#include "bsbe1.h"
-#include "lnbp21.h"
-#include "bsru6.h"
-
-#define TS_WIDTH  376
-#define TS_HEIGHT 512
-#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
-#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
-
-
-int av7110_debug;
-
-static int vidmode = CVBS_RGB_OUT;
-static int pids_off;
-static int adac = DVB_ADAC_TI;
-static int hw_sections;
-static int rgb_on;
-static int volume = 255;
-static int budgetpatch;
-static int wss_cfg_4_3 = 0x4008;
-static int wss_cfg_16_9 = 0x0007;
-static int tv_standard;
-static int full_ts;
-
-module_param_named(debug, av7110_debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
-module_param(vidmode, int, 0444);
-MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
-module_param(pids_off, int, 0444);
-MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
-module_param(adac, int, 0444);
-MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
-module_param(hw_sections, int, 0444);
-MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
-module_param(rgb_on, int, 0444);
-MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
-               " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
-module_param(volume, int, 0444);
-MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
-module_param(budgetpatch, int, 0444);
-MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
-module_param(full_ts, int, 0444);
-MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable");
-module_param(wss_cfg_4_3, int, 0444);
-MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
-module_param(wss_cfg_16_9, int, 0444);
-MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data");
-module_param(tv_standard, int, 0444);
-MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static void restart_feeds(struct av7110 *av7110);
-static int budget_start_feed(struct dvb_demux_feed *feed);
-static int budget_stop_feed(struct dvb_demux_feed *feed);
-
-static int av7110_num;
-
-#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
-{\
-       if (fe_func != NULL) { \
-               av7110_copy = fe_func; \
-               fe_func = av7110_func; \
-       } \
-}
-
-
-static void init_av7110_av(struct av7110 *av7110)
-{
-       int ret;
-       struct saa7146_dev *dev = av7110->dev;
-
-       /* set internal volume control to maximum */
-       av7110->adac_type = DVB_ADAC_TI;
-       ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
-       if (ret < 0)
-               printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
-
-       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
-                           1, (u16) av7110->display_ar);
-       if (ret < 0)
-               printk("dvb-ttpci: unable to set aspect ratio\n");
-       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
-                           1, av7110->display_panscan);
-       if (ret < 0)
-               printk("dvb-ttpci: unable to set pan scan\n");
-
-       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3);
-       if (ret < 0)
-               printk("dvb-ttpci: unable to configure 4:3 wss\n");
-       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9);
-       if (ret < 0)
-               printk("dvb-ttpci: unable to configure 16:9 wss\n");
-
-       ret = av7710_set_video_mode(av7110, vidmode);
-       if (ret < 0)
-               printk("dvb-ttpci:cannot set video mode:%d\n",ret);
-
-       /* handle different card types */
-       /* remaining inits according to card and frontend type */
-       av7110->analog_tuner_flags = 0;
-       av7110->current_input = 0;
-       if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a)
-               av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
-       if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
-               printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
-                       av7110->dvb_adapter.num);
-               av7110->adac_type = DVB_ADAC_CRYSTAL;
-               i2c_writereg(av7110, 0x20, 0x01, 0xd2);
-               i2c_writereg(av7110, 0x20, 0x02, 0x49);
-               i2c_writereg(av7110, 0x20, 0x03, 0x00);
-               i2c_writereg(av7110, 0x20, 0x04, 0x00);
-
-               /**
-                * some special handling for the Siemens DVB-C cards...
-                */
-       } else if (0 == av7110_init_analog_module(av7110)) {
-               /* done. */
-       }
-       else if (dev->pci->subsystem_vendor == 0x110a) {
-               printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
-                       av7110->dvb_adapter.num);
-               av7110->adac_type = DVB_ADAC_NONE;
-       }
-       else {
-               av7110->adac_type = adac;
-               printk("dvb-ttpci: adac type set to %d @ card %d\n",
-                       av7110->adac_type, av7110->dvb_adapter.num);
-       }
-
-       if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
-               // switch DVB SCART on
-               ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
-               if (ret < 0)
-                       printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
-               ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
-               if (ret < 0)
-                       printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
-               if (rgb_on &&
-                   ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
-                    (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
-                    (av7110->dev->pci->subsystem_device == 0x0000)) {
-                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
-                       //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
-               }
-       }
-
-       if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
-               av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
-
-       ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
-       if (ret < 0)
-               printk("dvb-ttpci:cannot set volume :%d\n",ret);
-}
-
-static void recover_arm(struct av7110 *av7110)
-{
-       dprintk(4, "%p\n",av7110);
-
-       av7110_bootarm(av7110);
-       msleep(100);
-
-       init_av7110_av(av7110);
-
-       /* card-specific recovery */
-       if (av7110->recover)
-               av7110->recover(av7110);
-
-       restart_feeds(av7110);
-
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
-       av7110_check_ir_config(av7110, true);
-#endif
-}
-
-static void av7110_arm_sync(struct av7110 *av7110)
-{
-       if (av7110->arm_thread)
-               kthread_stop(av7110->arm_thread);
-
-       av7110->arm_thread = NULL;
-}
-
-static int arm_thread(void *data)
-{
-       struct av7110 *av7110 = data;
-       u16 newloops = 0;
-       int timeout;
-
-       dprintk(4, "%p\n",av7110);
-
-       for (;;) {
-               timeout = wait_event_interruptible_timeout(av7110->arm_wait,
-                       kthread_should_stop(), 5 * HZ);
-
-               if (-ERESTARTSYS == timeout || kthread_should_stop()) {
-                       /* got signal or told to quit*/
-                       break;
-               }
-
-               if (!av7110->arm_ready)
-                       continue;
-
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
-               av7110_check_ir_config(av7110, false);
-#endif
-
-               if (mutex_lock_interruptible(&av7110->dcomlock))
-                       break;
-               newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
-               mutex_unlock(&av7110->dcomlock);
-
-               if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
-                       printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
-                              av7110->dvb_adapter.num);
-
-                       recover_arm(av7110);
-
-                       if (mutex_lock_interruptible(&av7110->dcomlock))
-                               break;
-                       newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
-                       mutex_unlock(&av7110->dcomlock);
-               }
-               av7110->arm_loops = newloops;
-               av7110->arm_errors = 0;
-       }
-
-       return 0;
-}
-
-
-/****************************************************************************
- * IRQ handling
- ****************************************************************************/
-
-static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
-                               u8 *buffer2, size_t buffer2_len,
-                               struct dvb_demux_filter *dvbdmxfilter,
-                               enum dmx_success success,
-                               struct av7110 *av7110)
-{
-       if (!dvbdmxfilter->feed->demux->dmx.frontend)
-               return 0;
-       if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
-               return 0;
-
-       switch (dvbdmxfilter->type) {
-       case DMX_TYPE_SEC:
-               if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
-                       return 0;
-               if (dvbdmxfilter->doneq) {
-                       struct dmx_section_filter *filter = &dvbdmxfilter->filter;
-                       int i;
-                       u8 xor, neq = 0;
-
-                       for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
-                               xor = filter->filter_value[i] ^ buffer1[i];
-                               neq |= dvbdmxfilter->maskandnotmode[i] & xor;
-                       }
-                       if (!neq)
-                               return 0;
-               }
-               return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
-                                                 buffer2, buffer2_len,
-                                                 &dvbdmxfilter->filter,
-                                                 DMX_OK);
-       case DMX_TYPE_TS:
-               if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
-                       return 0;
-               if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
-                       return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
-                                                        buffer2, buffer2_len,
-                                                        &dvbdmxfilter->feed->feed.ts,
-                                                        DMX_OK);
-               else
-                       av7110_p2t_write(buffer1, buffer1_len,
-                                        dvbdmxfilter->feed->pid,
-                                        &av7110->p2t_filter[dvbdmxfilter->index]);
-       default:
-               return 0;
-       }
-}
-
-
-//#define DEBUG_TIMING
-static inline void print_time(char *s)
-{
-#ifdef DEBUG_TIMING
-       struct timeval tv;
-       do_gettimeofday(&tv);
-       printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
-#endif
-}
-
-#define DEBI_READ 0
-#define DEBI_WRITE 1
-static inline void start_debi_dma(struct av7110 *av7110, int dir,
-                                 unsigned long addr, unsigned int len)
-{
-       dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
-       if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
-               printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
-               return;
-       }
-
-       SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
-       SAA7146_IER_ENABLE(av7110->dev, MASK_19);
-       if (len < 5)
-               len = 5; /* we want a real DEBI DMA */
-       if (dir == DEBI_WRITE)
-               iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
-       else
-               irdebi(av7110, DEBISWAB, addr, 0, len);
-}
-
-static void debiirq(unsigned long cookie)
-{
-       struct av7110 *av7110 = (struct av7110 *)cookie;
-       int type = av7110->debitype;
-       int handle = (type >> 8) & 0x1f;
-       unsigned int xfer = 0;
-
-       print_time("debi");
-       dprintk(4, "type 0x%04x\n", type);
-
-       if (type == -1) {
-               printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
-                      jiffies, saa7146_read(av7110->dev, PSR),
-                      saa7146_read(av7110->dev, SSR));
-               goto debi_done;
-       }
-       av7110->debitype = -1;
-
-       switch (type & 0xff) {
-
-       case DATA_TS_RECORD:
-               dvb_dmx_swfilter_packets(&av7110->demux,
-                                        (const u8 *) av7110->debi_virt,
-                                        av7110->debilen / 188);
-               xfer = RX_BUFF;
-               break;
-
-       case DATA_PES_RECORD:
-               if (av7110->demux.recording)
-                       av7110_record_cb(&av7110->p2t[handle],
-                                        (u8 *) av7110->debi_virt,
-                                        av7110->debilen);
-               xfer = RX_BUFF;
-               break;
-
-       case DATA_IPMPE:
-       case DATA_FSECTION:
-       case DATA_PIPING:
-               if (av7110->handle2filter[handle])
-                       DvbDmxFilterCallback((u8 *)av7110->debi_virt,
-                                            av7110->debilen, NULL, 0,
-                                            av7110->handle2filter[handle],
-                                            DMX_OK, av7110);
-               xfer = RX_BUFF;
-               break;
-
-       case DATA_CI_GET:
-       {
-               u8 *data = av7110->debi_virt;
-
-               if ((data[0] < 2) && data[2] == 0xff) {
-                       int flags = 0;
-                       if (data[5] > 0)
-                               flags |= CA_CI_MODULE_PRESENT;
-                       if (data[5] > 5)
-                               flags |= CA_CI_MODULE_READY;
-                       av7110->ci_slot[data[0]].flags = flags;
-               } else
-                       ci_get_data(&av7110->ci_rbuffer,
-                                   av7110->debi_virt,
-                                   av7110->debilen);
-               xfer = RX_BUFF;
-               break;
-       }
-
-       case DATA_COMMON_INTERFACE:
-               CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
-#if 0
-       {
-               int i;
-
-               printk("av7110%d: ", av7110->num);
-               printk("%02x ", *(u8 *)av7110->debi_virt);
-               printk("%02x ", *(1+(u8 *)av7110->debi_virt));
-               for (i = 2; i < av7110->debilen; i++)
-                       printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
-               for (i = 2; i < av7110->debilen; i++)
-                       printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
-
-               printk("\n");
-       }
-#endif
-               xfer = RX_BUFF;
-               break;
-
-       case DATA_DEBUG_MESSAGE:
-               ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
-               printk("%s\n", (s8 *) av7110->debi_virt);
-               xfer = RX_BUFF;
-               break;
-
-       case DATA_CI_PUT:
-               dprintk(4, "debi DATA_CI_PUT\n");
-       case DATA_MPEG_PLAY:
-               dprintk(4, "debi DATA_MPEG_PLAY\n");
-       case DATA_BMP_LOAD:
-               dprintk(4, "debi DATA_BMP_LOAD\n");
-               xfer = TX_BUFF;
-               break;
-       default:
-               break;
-       }
-debi_done:
-       spin_lock(&av7110->debilock);
-       if (xfer)
-               iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
-       ARM_ClearMailBox(av7110);
-       spin_unlock(&av7110->debilock);
-}
-
-/* irq from av7110 firmware writing the mailbox register in the DPRAM */
-static void gpioirq(unsigned long cookie)
-{
-       struct av7110 *av7110 = (struct av7110 *)cookie;
-       u32 rxbuf, txbuf;
-       int len;
-
-       if (av7110->debitype != -1)
-               /* we shouldn't get any irq while a debi xfer is running */
-               printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
-                      jiffies, saa7146_read(av7110->dev, PSR),
-                      saa7146_read(av7110->dev, SSR));
-
-       if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
-               printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
-               BUG(); /* maybe we should try resetting the debi? */
-       }
-
-       spin_lock(&av7110->debilock);
-       ARM_ClearIrq(av7110);
-
-       /* see what the av7110 wants */
-       av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
-       av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-       rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-       txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-       len = (av7110->debilen + 3) & ~3;
-
-       print_time("gpio");
-       dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
-
-       switch (av7110->debitype & 0xff) {
-
-       case DATA_TS_PLAY:
-       case DATA_PES_PLAY:
-               break;
-
-       case DATA_MPEG_VIDEO_EVENT:
-       {
-               u32 h_ar;
-               struct video_event event;
-
-               av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
-               h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
-
-               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-               iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-
-               av7110->video_size.h = h_ar & 0xfff;
-
-               event.type = VIDEO_EVENT_SIZE_CHANGED;
-               event.u.size.w = av7110->video_size.w;
-               event.u.size.h = av7110->video_size.h;
-               switch ((h_ar >> 12) & 0xf)
-               {
-               case 3:
-                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
-                       event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
-                       av7110->videostate.video_format = VIDEO_FORMAT_16_9;
-                       break;
-               case 4:
-                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
-                       event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
-                       av7110->videostate.video_format = VIDEO_FORMAT_221_1;
-                       break;
-               default:
-                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
-                       event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
-                       av7110->videostate.video_format = VIDEO_FORMAT_4_3;
-               }
-
-               dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
-                       av7110->video_size.w, av7110->video_size.h,
-                       av7110->video_size.aspect_ratio);
-
-               dvb_video_add_event(av7110, &event);
-               break;
-       }
-
-       case DATA_CI_PUT:
-       {
-               int avail;
-               struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
-
-               avail = dvb_ringbuffer_avail(cibuf);
-               if (avail <= 2) {
-                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                       break;
-               }
-               len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
-               len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
-               if (avail < len + 2) {
-                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                       break;
-               }
-               DVB_RINGBUFFER_SKIP(cibuf, 2);
-
-               dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
-
-               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-               dprintk(8, "DMA: CI\n");
-               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
-               spin_unlock(&av7110->debilock);
-               wake_up(&cibuf->queue);
-               return;
-       }
-
-       case DATA_MPEG_PLAY:
-               if (!av7110->playing) {
-                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                       break;
-               }
-               len = 0;
-               if (av7110->debitype & 0x100) {
-                       spin_lock(&av7110->aout.lock);
-                       len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
-                       spin_unlock(&av7110->aout.lock);
-               }
-               if (len <= 0 && (av7110->debitype & 0x200)
-                   &&av7110->videostate.play_state != VIDEO_FREEZED) {
-                       spin_lock(&av7110->avout.lock);
-                       len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
-                       spin_unlock(&av7110->avout.lock);
-               }
-               if (len <= 0) {
-                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                       break;
-               }
-               dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
-               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-               dprintk(8, "DMA: MPEG_PLAY\n");
-               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
-               spin_unlock(&av7110->debilock);
-               return;
-
-       case DATA_BMP_LOAD:
-               len = av7110->debilen;
-               dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
-               if (!len) {
-                       av7110->bmp_state = BMP_LOADED;
-                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
-                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                       wake_up(&av7110->bmpq);
-                       dprintk(8, "gpio DATA_BMP_LOAD done\n");
-                       break;
-               }
-               if (len > av7110->bmplen)
-                       len = av7110->bmplen;
-               if (len > 2 * 1024)
-                       len = 2 * 1024;
-               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
-               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-               memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
-               av7110->bmpp += len;
-               av7110->bmplen -= len;
-               dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
-               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
-               spin_unlock(&av7110->debilock);
-               return;
-
-       case DATA_CI_GET:
-       case DATA_COMMON_INTERFACE:
-       case DATA_FSECTION:
-       case DATA_IPMPE:
-       case DATA_PIPING:
-               if (!len || len > 4 * 1024) {
-                       iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                       break;
-               }
-               /* fall through */
-
-       case DATA_TS_RECORD:
-       case DATA_PES_RECORD:
-               dprintk(8, "DMA: TS_REC etc.\n");
-               start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
-               spin_unlock(&av7110->debilock);
-               return;
-
-       case DATA_DEBUG_MESSAGE:
-               if (!len || len > 0xff) {
-                       iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                       break;
-               }
-               start_debi_dma(av7110, DEBI_READ, Reserved, len);
-               spin_unlock(&av7110->debilock);
-               return;
-
-       case DATA_IRCOMMAND:
-               if (av7110->ir.ir_handler)
-                       av7110->ir.ir_handler(av7110,
-                               swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
-               iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-               break;
-
-       default:
-               printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
-                      av7110->debitype, av7110->debilen);
-               break;
-       }
-       av7110->debitype = -1;
-       ARM_ClearMailBox(av7110);
-       spin_unlock(&av7110->debilock);
-}
-
-
-#ifdef CONFIG_DVB_AV7110_OSD
-static int dvb_osd_ioctl(struct file *file,
-                        unsigned int cmd, void *parg)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (cmd == OSD_SEND_CMD)
-               return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
-       if (cmd == OSD_GET_CAPABILITY)
-               return av7110_osd_capability(av7110, (osd_cap_t *) parg);
-
-       return -EINVAL;
-}
-
-
-static const struct file_operations dvb_osd_fops = {
-       .owner          = THIS_MODULE,
-       .unlocked_ioctl = dvb_generic_ioctl,
-       .open           = dvb_generic_open,
-       .release        = dvb_generic_release,
-       .llseek         = noop_llseek,
-};
-
-static struct dvb_device dvbdev_osd = {
-       .priv           = NULL,
-       .users          = 1,
-       .writers        = 1,
-       .fops           = &dvb_osd_fops,
-       .kernel_ioctl   = dvb_osd_ioctl,
-};
-#endif /* CONFIG_DVB_AV7110_OSD */
-
-
-static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
-                         u16 subpid, u16 pcrpid)
-{
-       u16 aflags = 0;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (vpid == 0x1fff || apid == 0x1fff ||
-           ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
-               vpid = apid = ttpid = subpid = pcrpid = 0;
-               av7110->pids[DMX_PES_VIDEO] = 0;
-               av7110->pids[DMX_PES_AUDIO] = 0;
-               av7110->pids[DMX_PES_TELETEXT] = 0;
-               av7110->pids[DMX_PES_PCR] = 0;
-       }
-
-       if (av7110->audiostate.bypass_mode)
-               aflags |= 0x8000;
-
-       return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
-                            pcrpid, vpid, apid, ttpid, subpid, aflags);
-}
-
-int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
-               u16 subpid, u16 pcrpid)
-{
-       int ret = 0;
-       dprintk(4, "%p\n", av7110);
-
-       if (mutex_lock_interruptible(&av7110->pid_mutex))
-               return -ERESTARTSYS;
-
-       if (!(vpid & 0x8000))
-               av7110->pids[DMX_PES_VIDEO] = vpid;
-       if (!(apid & 0x8000))
-               av7110->pids[DMX_PES_AUDIO] = apid;
-       if (!(ttpid & 0x8000))
-               av7110->pids[DMX_PES_TELETEXT] = ttpid;
-       if (!(pcrpid & 0x8000))
-               av7110->pids[DMX_PES_PCR] = pcrpid;
-
-       av7110->pids[DMX_PES_SUBTITLE] = 0;
-
-       if (av7110->fe_synced) {
-               pcrpid = av7110->pids[DMX_PES_PCR];
-               ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
-       }
-
-       mutex_unlock(&av7110->pid_mutex);
-       return ret;
-}
-
-
-/******************************************************************************
- * hardware filter functions
- ******************************************************************************/
-
-static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
-{
-       struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
-       struct av7110 *av7110 = dvbdmxfeed->demux->priv;
-       u16 buf[20];
-       int ret, i;
-       u16 handle;
-//     u16 mode = 0x0320;
-       u16 mode = 0xb96a;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (av7110->full_ts)
-               return 0;
-
-       if (dvbdmxfilter->type == DMX_TYPE_SEC) {
-               if (hw_sections) {
-                       buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
-                               dvbdmxfilter->maskandmode[0];
-                       for (i = 3; i < 18; i++)
-                               buf[i + 4 - 2] =
-                                       (dvbdmxfilter->filter.filter_value[i] << 8) |
-                                       dvbdmxfilter->maskandmode[i];
-                       mode = 4;
-               }
-       } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
-                  !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
-               av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
-       }
-
-       buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
-       buf[1] = 16;
-       buf[2] = dvbdmxfeed->pid;
-       buf[3] = mode;
-
-       ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
-       if (ret != 0 || handle >= 32) {
-               printk("dvb-ttpci: %s error  buf %04x %04x %04x %04x  "
-                               "ret %d  handle %04x\n",
-                               __func__, buf[0], buf[1], buf[2], buf[3],
-                               ret, handle);
-               dvbdmxfilter->hw_handle = 0xffff;
-               if (!ret)
-                       ret = -1;
-               return ret;
-       }
-
-       av7110->handle2filter[handle] = dvbdmxfilter;
-       dvbdmxfilter->hw_handle = handle;
-
-       return ret;
-}
-
-static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
-{
-       struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv;
-       u16 buf[3];
-       u16 answ[2];
-       int ret;
-       u16 handle;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (av7110->full_ts)
-               return 0;
-
-       handle = dvbdmxfilter->hw_handle;
-       if (handle >= 32) {
-               printk("%s tried to stop invalid filter %04x, filter type = %x\n",
-                               __func__, handle, dvbdmxfilter->type);
-               return -EINVAL;
-       }
-
-       av7110->handle2filter[handle] = NULL;
-
-       buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
-       buf[1] = 1;
-       buf[2] = handle;
-       ret = av7110_fw_request(av7110, buf, 3, answ, 2);
-       if (ret != 0 || answ[1] != handle) {
-               printk("dvb-ttpci: %s error  cmd %04x %04x %04x  ret %x  "
-                               "resp %04x %04x  pid %d\n",
-                               __func__, buf[0], buf[1], buf[2], ret,
-                               answ[0], answ[1], dvbdmxfilter->feed->pid);
-               if (!ret)
-                       ret = -1;
-       }
-       return ret;
-}
-
-
-static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct av7110 *av7110 = dvbdmx->priv;
-       u16 *pid = dvbdmx->pids, npids[5];
-       int i;
-       int ret = 0;
-
-       dprintk(4, "%p\n", av7110);
-
-       npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
-       i = dvbdmxfeed->pes_type;
-       npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
-       if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
-               npids[i] = 0;
-               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
-               if (!ret)
-                       ret = StartHWFilter(dvbdmxfeed->filter);
-               return ret;
-       }
-       if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
-               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
-               if (ret)
-                       return ret;
-       }
-
-       if (dvbdmxfeed->pes_type < 2 && npids[0])
-               if (av7110->fe_synced)
-               {
-                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
-                       if (ret)
-                               return ret;
-               }
-
-       if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) {
-               if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
-                       ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
-               if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
-                       ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
-       }
-       return ret;
-}
-
-static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct av7110 *av7110 = dvbdmx->priv;
-       u16 *pid = dvbdmx->pids, npids[5];
-       int i;
-
-       int ret = 0;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (dvbdmxfeed->pes_type <= 1) {
-               ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ?  RP_VIDEO : RP_AUDIO);
-               if (ret)
-                       return ret;
-               if (!av7110->rec_mode)
-                       dvbdmx->recording = 0;
-               if (!av7110->playing)
-                       dvbdmx->playing = 0;
-       }
-       npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
-       i = dvbdmxfeed->pes_type;
-       switch (i) {
-       case 2: //teletext
-               if (dvbdmxfeed->ts_type & TS_PACKET)
-                       ret = StopHWFilter(dvbdmxfeed->filter);
-               npids[2] = 0;
-               break;
-       case 0:
-       case 1:
-       case 4:
-               if (!pids_off)
-                       return 0;
-               npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
-               break;
-       }
-       if (!ret)
-               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
-       return ret;
-}
-
-static int av7110_start_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct av7110 *av7110 = demux->priv;
-       int ret = 0;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (!demux->dmx.frontend)
-               return -EINVAL;
-
-       if (!av7110->full_ts && feed->pid > 0x1fff)
-               return -EINVAL;
-
-       if (feed->type == DMX_TYPE_TS) {
-               if ((feed->ts_type & TS_DECODER) &&
-                   (feed->pes_type <= DMX_TS_PES_PCR)) {
-                       switch (demux->dmx.frontend->source) {
-                       case DMX_MEMORY_FE:
-                               if (feed->ts_type & TS_DECODER)
-                                      if (feed->pes_type < 2 &&
-                                          !(demux->pids[0] & 0x8000) &&
-                                          !(demux->pids[1] & 0x8000)) {
-                                              dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
-                                              dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
-                                              ret = av7110_av_start_play(av7110,RP_AV);
-                                              if (!ret)
-                                                      demux->playing = 1;
-                                       }
-                               break;
-                       default:
-                               ret = dvb_feed_start_pid(feed);
-                               break;
-                       }
-               } else if ((feed->ts_type & TS_PACKET) &&
-                          (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
-                       ret = StartHWFilter(feed->filter);
-               }
-       }
-
-       if (av7110->full_ts) {
-               budget_start_feed(feed);
-               return ret;
-       }
-
-       if (feed->type == DMX_TYPE_SEC) {
-               int i;
-
-               for (i = 0; i < demux->filternum; i++) {
-                       if (demux->filter[i].state != DMX_STATE_READY)
-                               continue;
-                       if (demux->filter[i].type != DMX_TYPE_SEC)
-                               continue;
-                       if (demux->filter[i].filter.parent != &feed->feed.sec)
-                               continue;
-                       demux->filter[i].state = DMX_STATE_GO;
-                       if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
-                               ret = StartHWFilter(&demux->filter[i]);
-                               if (ret)
-                                       break;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-
-static int av7110_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct av7110 *av7110 = demux->priv;
-       int i, rc, ret = 0;
-       dprintk(4, "%p\n", av7110);
-
-       if (feed->type == DMX_TYPE_TS) {
-               if (feed->ts_type & TS_DECODER) {
-                       if (feed->pes_type >= DMX_TS_PES_OTHER ||
-                           !demux->pesfilter[feed->pes_type])
-                               return -EINVAL;
-                       demux->pids[feed->pes_type] |= 0x8000;
-                       demux->pesfilter[feed->pes_type] = NULL;
-               }
-               if (feed->ts_type & TS_DECODER &&
-                   feed->pes_type < DMX_TS_PES_OTHER) {
-                       ret = dvb_feed_stop_pid(feed);
-               } else
-                       if ((feed->ts_type & TS_PACKET) &&
-                           (demux->dmx.frontend->source != DMX_MEMORY_FE))
-                               ret = StopHWFilter(feed->filter);
-       }
-
-       if (av7110->full_ts) {
-               budget_stop_feed(feed);
-               return ret;
-       }
-
-       if (feed->type == DMX_TYPE_SEC) {
-               for (i = 0; i<demux->filternum; i++) {
-                       if (demux->filter[i].state == DMX_STATE_GO &&
-                           demux->filter[i].filter.parent == &feed->feed.sec) {
-                               demux->filter[i].state = DMX_STATE_READY;
-                               if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
-                                       rc = StopHWFilter(&demux->filter[i]);
-                                       if (!ret)
-                                               ret = rc;
-                                       /* keep going, stop as many filters as possible */
-                               }
-                       }
-               }
-       }
-
-       return ret;
-}
-
-
-static void restart_feeds(struct av7110 *av7110)
-{
-       struct dvb_demux *dvbdmx = &av7110->demux;
-       struct dvb_demux_feed *feed;
-       int mode;
-       int feeding;
-       int i, j;
-
-       dprintk(4, "%p\n", av7110);
-
-       mode = av7110->playing;
-       av7110->playing = 0;
-       av7110->rec_mode = 0;
-
-       feeding = av7110->feeding1; /* full_ts mod */
-
-       for (i = 0; i < dvbdmx->feednum; i++) {
-               feed = &dvbdmx->feed[i];
-               if (feed->state == DMX_STATE_GO) {
-                       if (feed->type == DMX_TYPE_SEC) {
-                               for (j = 0; j < dvbdmx->filternum; j++) {
-                                       if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
-                                               continue;
-                                       if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
-                                               continue;
-                                       if (dvbdmx->filter[j].state == DMX_STATE_GO)
-                                               dvbdmx->filter[j].state = DMX_STATE_READY;
-                               }
-                       }
-                       av7110_start_feed(feed);
-               }
-       }
-
-       av7110->feeding1 = feeding; /* full_ts mod */
-
-       if (mode)
-               av7110_av_start_play(av7110, mode);
-}
-
-static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
-                      uint64_t *stc, unsigned int *base)
-{
-       int ret;
-       u16 fwstc[4];
-       u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
-       struct dvb_demux *dvbdemux;
-       struct av7110 *av7110;
-
-       /* pointer casting paranoia... */
-       BUG_ON(!demux);
-       dvbdemux = demux->priv;
-       BUG_ON(!dvbdemux);
-       av7110 = dvbdemux->priv;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (num != 0)
-               return -EINVAL;
-
-       ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
-       if (ret) {
-               printk(KERN_ERR "%s: av7110_fw_request error\n", __func__);
-               return ret;
-       }
-       dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
-               fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
-
-       *stc =  (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
-               (((uint64_t)  fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
-       *base = 1;
-
-       dprintk(4, "stc = %lu\n", (unsigned long)*stc);
-
-       return 0;
-}
-
-
-/******************************************************************************
- * SEC device file operations
- ******************************************************************************/
-
-
-static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               return Set22K(av7110, 1);
-
-       case SEC_TONE_OFF:
-               return Set22K(av7110, 0);
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
-                                        struct dvb_diseqc_master_cmd* cmd)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
-}
-
-static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
-                                   fe_sec_mini_cmd_t minicmd)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       return av7110_diseqc_send(av7110, 0, NULL, minicmd);
-}
-
-/* simplified code from budget-core.c */
-static int stop_ts_capture(struct av7110 *budget)
-{
-       dprintk(2, "budget: %p\n", budget);
-
-       if (--budget->feeding1)
-               return budget->feeding1;
-       saa7146_write(budget->dev, MC1, MASK_20);       /* DMA3 off */
-       SAA7146_IER_DISABLE(budget->dev, MASK_10);
-       SAA7146_ISR_CLEAR(budget->dev, MASK_10);
-       return 0;
-}
-
-static int start_ts_capture(struct av7110 *budget)
-{
-       dprintk(2, "budget: %p\n", budget);
-
-       if (budget->feeding1)
-               return ++budget->feeding1;
-       memset(budget->grabbing, 0x00, TS_BUFLEN);
-       budget->ttbp = 0;
-       SAA7146_ISR_CLEAR(budget->dev, MASK_10);  /* VPE */
-       SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
-       saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
-       return ++budget->feeding1;
-}
-
-static int budget_start_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct av7110 *budget = demux->priv;
-       int status;
-
-       dprintk(2, "av7110: %p\n", budget);
-
-       spin_lock(&budget->feedlock1);
-       feed->pusi_seen = 0; /* have a clean section start */
-       status = start_ts_capture(budget);
-       spin_unlock(&budget->feedlock1);
-       return status;
-}
-
-static int budget_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct av7110 *budget = demux->priv;
-       int status;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       spin_lock(&budget->feedlock1);
-       status = stop_ts_capture(budget);
-       spin_unlock(&budget->feedlock1);
-       return status;
-}
-
-static void vpeirq(unsigned long cookie)
-{
-       struct av7110 *budget = (struct av7110 *)cookie;
-       u8 *mem = (u8 *) (budget->grabbing);
-       u32 olddma = budget->ttbp;
-       u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
-       struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1;
-
-       /* nearest lower position divisible by 188 */
-       newdma -= newdma % 188;
-
-       if (newdma >= TS_BUFLEN)
-               return;
-
-       budget->ttbp = newdma;
-
-       if (!budget->feeding1 || (newdma == olddma))
-               return;
-
-       /* Ensure streamed PCI data is synced to CPU */
-       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
-
-#if 0
-       /* track rps1 activity */
-       printk("vpeirq: %02x Event Counter 1 0x%04x\n",
-              mem[olddma],
-              saa7146_read(budget->dev, EC1R) & 0x3fff);
-#endif
-
-       if (newdma > olddma)
-               /* no wraparound, dump olddma..newdma */
-               dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188);
-       else {
-               /* wraparound, dump olddma..buflen and 0..newdma */
-               dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
-               dvb_dmx_swfilter_packets(demux, mem, newdma / 188);
-       }
-}
-
-static int av7110_register(struct av7110 *av7110)
-{
-       int ret, i;
-       struct dvb_demux *dvbdemux = &av7110->demux;
-       struct dvb_demux *dvbdemux1 = &av7110->demux1;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (av7110->registered)
-               return -1;
-
-       av7110->registered = 1;
-
-       dvbdemux->priv = (void *) av7110;
-
-       for (i = 0; i < 32; i++)
-               av7110->handle2filter[i] = NULL;
-
-       dvbdemux->filternum = (av7110->full_ts) ? 256 : 32;
-       dvbdemux->feednum = (av7110->full_ts) ? 256 : 32;
-       dvbdemux->start_feed = av7110_start_feed;
-       dvbdemux->stop_feed = av7110_stop_feed;
-       dvbdemux->write_to_decoder = av7110_write_to_decoder;
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
-                                     DMX_MEMORY_BASED_FILTERING);
-
-       dvb_dmx_init(&av7110->demux);
-       av7110->demux.dmx.get_stc = dvb_get_stc;
-
-       av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32;
-       av7110->dmxdev.demux = &dvbdemux->dmx;
-       av7110->dmxdev.capabilities = 0;
-
-       dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
-
-       av7110->hw_frontend.source = DMX_FRONTEND_0;
-
-       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
-
-       if (ret < 0)
-               return ret;
-
-       av7110->mem_frontend.source = DMX_MEMORY_FE;
-
-       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
-
-       if (ret < 0)
-               return ret;
-
-       ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
-                                            &av7110->hw_frontend);
-       if (ret < 0)
-               return ret;
-
-       av7110_av_register(av7110);
-       av7110_ca_register(av7110);
-
-#ifdef CONFIG_DVB_AV7110_OSD
-       dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
-                           &dvbdev_osd, av7110, DVB_DEVICE_OSD);
-#endif
-
-       dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
-
-       if (budgetpatch) {
-               /* initialize software demux1 without its own frontend
-                * demux1 hardware is connected to frontend0 of demux0
-                */
-               dvbdemux1->priv = (void *) av7110;
-
-               dvbdemux1->filternum = 256;
-               dvbdemux1->feednum = 256;
-               dvbdemux1->start_feed = budget_start_feed;
-               dvbdemux1->stop_feed = budget_stop_feed;
-               dvbdemux1->write_to_decoder = NULL;
-
-               dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
-                                              DMX_MEMORY_BASED_FILTERING);
-
-               dvb_dmx_init(&av7110->demux1);
-
-               av7110->dmxdev1.filternum = 256;
-               av7110->dmxdev1.demux = &dvbdemux1->dmx;
-               av7110->dmxdev1.capabilities = 0;
-
-               dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
-
-               dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
-               printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
-       }
-       return 0;
-}
-
-
-static void dvb_unregister(struct av7110 *av7110)
-{
-       struct dvb_demux *dvbdemux = &av7110->demux;
-       struct dvb_demux *dvbdemux1 = &av7110->demux1;
-
-       dprintk(4, "%p\n", av7110);
-
-       if (!av7110->registered)
-               return;
-
-       if (budgetpatch) {
-               dvb_net_release(&av7110->dvb_net1);
-               dvbdemux->dmx.close(&dvbdemux1->dmx);
-               dvb_dmxdev_release(&av7110->dmxdev1);
-               dvb_dmx_release(&av7110->demux1);
-       }
-
-       dvb_net_release(&av7110->dvb_net);
-
-       dvbdemux->dmx.close(&dvbdemux->dmx);
-       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
-       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
-
-       dvb_dmxdev_release(&av7110->dmxdev);
-       dvb_dmx_release(&av7110->demux);
-
-       if (av7110->fe != NULL) {
-               dvb_unregister_frontend(av7110->fe);
-               dvb_frontend_detach(av7110->fe);
-       }
-       dvb_unregister_device(av7110->osd_dev);
-       av7110_av_unregister(av7110);
-       av7110_ca_unregister(av7110);
-}
-
-
-/****************************************************************************
- * I2C client commands
- ****************************************************************************/
-
-int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
-{
-       u8 msg[2] = { reg, val };
-       struct i2c_msg msgs;
-
-       msgs.flags = 0;
-       msgs.addr = id / 2;
-       msgs.len = 2;
-       msgs.buf = msg;
-       return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
-}
-
-u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
-{
-       u8 mm1[] = {0x00};
-       u8 mm2[] = {0x00};
-       struct i2c_msg msgs[2];
-
-       msgs[0].flags = 0;
-       msgs[1].flags = I2C_M_RD;
-       msgs[0].addr = msgs[1].addr = id / 2;
-       mm1[0] = reg;
-       msgs[0].len = 1; msgs[1].len = 1;
-       msgs[0].buf = mm1; msgs[1].buf = mm2;
-       i2c_transfer(&av7110->i2c_adap, msgs, 2);
-
-       return mm2[0];
-}
-
-/****************************************************************************
- * INITIALIZATION
- ****************************************************************************/
-
-
-static int check_firmware(struct av7110* av7110)
-{
-       u32 crc = 0, len = 0;
-       unsigned char *ptr;
-
-       /* check for firmware magic */
-       ptr = av7110->bin_fw;
-       if (ptr[0] != 'A' || ptr[1] != 'V' ||
-           ptr[2] != 'F' || ptr[3] != 'W') {
-               printk("dvb-ttpci: this is not an av7110 firmware\n");
-               return -EINVAL;
-       }
-       ptr += 4;
-
-       /* check dpram file */
-       crc = get_unaligned_be32(ptr);
-       ptr += 4;
-       len = get_unaligned_be32(ptr);
-       ptr += 4;
-       if (len >= 512) {
-               printk("dvb-ttpci: dpram file is way too big.\n");
-               return -EINVAL;
-       }
-       if (crc != crc32_le(0, ptr, len)) {
-               printk("dvb-ttpci: crc32 of dpram file does not match.\n");
-               return -EINVAL;
-       }
-       av7110->bin_dpram = ptr;
-       av7110->size_dpram = len;
-       ptr += len;
-
-       /* check root file */
-       crc = get_unaligned_be32(ptr);
-       ptr += 4;
-       len = get_unaligned_be32(ptr);
-       ptr += 4;
-
-       if (len <= 200000 || len >= 300000 ||
-           len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
-               printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
-               return -EINVAL;
-       }
-       if( crc != crc32_le(0, ptr, len)) {
-               printk("dvb-ttpci: crc32 of root file does not match.\n");
-               return -EINVAL;
-       }
-       av7110->bin_root = ptr;
-       av7110->size_root = len;
-       return 0;
-}
-
-static void put_firmware(struct av7110* av7110)
-{
-       vfree(av7110->bin_fw);
-}
-
-static int get_firmware(struct av7110* av7110)
-{
-       int ret;
-       const struct firmware *fw;
-
-       /* request the av7110 firmware, this will block until someone uploads it */
-       ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
-       if (ret) {
-               if (ret == -ENOENT) {
-                       printk(KERN_ERR "dvb-ttpci: could not load firmware,"
-                              " file not found: dvb-ttpci-01.fw\n");
-                       printk(KERN_ERR "dvb-ttpci: usually this should be in "
-                              "/usr/lib/hotplug/firmware or /lib/firmware\n");
-                       printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
-                              " http://www.linuxtv.org/download/dvb/firmware/\n");
-               } else
-                       printk(KERN_ERR "dvb-ttpci: cannot request firmware"
-                              " (error %i)\n", ret);
-               return -EINVAL;
-       }
-
-       if (fw->size <= 200000) {
-               printk("dvb-ttpci: this firmware is way too small.\n");
-               release_firmware(fw);
-               return -EINVAL;
-       }
-
-       /* check if the firmware is available */
-       av7110->bin_fw = vmalloc(fw->size);
-       if (NULL == av7110->bin_fw) {
-               dprintk(1, "out of memory\n");
-               release_firmware(fw);
-               return -ENOMEM;
-       }
-
-       memcpy(av7110->bin_fw, fw->data, fw->size);
-       av7110->size_fw = fw->size;
-       if ((ret = check_firmware(av7110)))
-               vfree(av7110->bin_fw);
-
-       release_firmware(fw);
-       return ret;
-}
-
-static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u8 pwr = 0;
-       u8 buf[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-       u32 div = (p->frequency + 479500) / 125;
-
-       if (p->frequency > 2000000)
-               pwr = 3;
-       else if (p->frequency > 1800000)
-               pwr = 2;
-       else if (p->frequency > 1600000)
-               pwr = 1;
-       else if (p->frequency > 1200000)
-               pwr = 0;
-       else if (p->frequency >= 1100000)
-               pwr = 1;
-       else
-               pwr = 2;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = ((div & 0x18000) >> 10) | 0x95;
-       buf[3] = (pwr << 6) | 0x30;
-
-       // NOTE: since we're using a prescaler of 2, we set the
-       // divisor frequency to 62.5kHz and divide by 125 above
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct ves1x93_config alps_bsrv2_config = {
-       .demod_address = 0x08,
-       .xin = 90100000UL,
-       .invert_pwm = 0,
-};
-
-static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (p->frequency + 35937500 + 31250) / 62500;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x85 | ((div >> 10) & 0x60);
-       data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct ves1820_config alps_tdbe2_config = {
-       .demod_address = 0x09,
-       .xin = 57840000UL,
-       .invert = 1,
-       .selagc = VES1820_SELAGC_SIGNAMPERR,
-};
-
-
-
-
-static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = p->frequency / 125;
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x8e;
-       data[3] = 0x00;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct tda8083_config grundig_29504_451_config = {
-       .demod_address = 0x68,
-};
-
-
-
-static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div;
-       u32 f = p->frequency;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (f + 36125000 + 31250) / 62500;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x8e;
-       data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct ves1820_config philips_cd1516_config = {
-       .demod_address = 0x09,
-       .xin = 57840000UL,
-       .invert = 1,
-       .selagc = VES1820_SELAGC_SIGNAMPERR,
-};
-
-
-
-static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div, pwr;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (p->frequency + 36200000) / 166666;
-
-       if (p->frequency <= 782000000)
-               pwr = 1;
-       else
-               pwr = 2;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x85;
-       data[3] = pwr << 6;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
-#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
-       struct av7110* av7110 = fe->dvb->priv;
-
-       return request_firmware(fw, name, &av7110->dev->pci->dev);
-#else
-       return -EINVAL;
-#endif
-}
-
-static struct sp8870_config alps_tdlb7_config = {
-
-       .demod_address = 0x71,
-       .request_firmware = alps_tdlb7_request_firmware,
-};
-
-
-static u8 nexusca_stv0297_inittab[] = {
-       0x80, 0x01,
-       0x80, 0x00,
-       0x81, 0x01,
-       0x81, 0x00,
-       0x00, 0x09,
-       0x01, 0x69,
-       0x03, 0x00,
-       0x04, 0x00,
-       0x07, 0x00,
-       0x08, 0x00,
-       0x20, 0x00,
-       0x21, 0x40,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x24, 0x40,
-       0x25, 0x88,
-       0x30, 0xff,
-       0x31, 0x00,
-       0x32, 0xff,
-       0x33, 0x00,
-       0x34, 0x50,
-       0x35, 0x7f,
-       0x36, 0x00,
-       0x37, 0x20,
-       0x38, 0x00,
-       0x40, 0x1c,
-       0x41, 0xff,
-       0x42, 0x29,
-       0x43, 0x00,
-       0x44, 0xff,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x49, 0x04,
-       0x4a, 0x00,
-       0x4b, 0x7b,
-       0x52, 0x30,
-       0x55, 0xae,
-       0x56, 0x47,
-       0x57, 0xe1,
-       0x58, 0x3a,
-       0x5a, 0x1e,
-       0x5b, 0x34,
-       0x60, 0x00,
-       0x63, 0x00,
-       0x64, 0x00,
-       0x65, 0x00,
-       0x66, 0x00,
-       0x67, 0x00,
-       0x68, 0x00,
-       0x69, 0x00,
-       0x6a, 0x02,
-       0x6b, 0x00,
-       0x70, 0xff,
-       0x71, 0x00,
-       0x72, 0x00,
-       0x73, 0x00,
-       0x74, 0x0c,
-       0x80, 0x00,
-       0x81, 0x00,
-       0x82, 0x00,
-       0x83, 0x00,
-       0x84, 0x04,
-       0x85, 0x80,
-       0x86, 0x24,
-       0x87, 0x78,
-       0x88, 0x10,
-       0x89, 0x00,
-       0x90, 0x01,
-       0x91, 0x01,
-       0xa0, 0x04,
-       0xa1, 0x00,
-       0xa2, 0x00,
-       0xb0, 0x91,
-       0xb1, 0x0b,
-       0xc0, 0x53,
-       0xc1, 0x70,
-       0xc2, 0x12,
-       0xd0, 0x00,
-       0xd1, 0x00,
-       0xd2, 0x00,
-       0xd3, 0x00,
-       0xd4, 0x00,
-       0xd5, 0x00,
-       0xde, 0x00,
-       0xdf, 0x00,
-       0x61, 0x49,
-       0x62, 0x0b,
-       0x53, 0x08,
-       0x59, 0x08,
-       0xff, 0xff,
-};
-
-static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
-       struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
-       int i;
-
-       div = (p->frequency + 36150000 + 31250) / 62500;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0xce;
-
-       if (p->frequency < 45000000)
-               return -EINVAL;
-       else if (p->frequency < 137000000)
-               data[3] = 0x01;
-       else if (p->frequency < 403000000)
-               data[3] = 0x02;
-       else if (p->frequency < 860000000)
-               data[3] = 0x04;
-       else
-               return -EINVAL;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
-               printk("nexusca: pll transfer failed!\n");
-               return -EIO;
-       }
-
-       // wait for PLL lock
-       for(i = 0; i < 20; i++) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
-                       if (data[0] & 0x40) break;
-               msleep(10);
-       }
-
-       return 0;
-}
-
-static struct stv0297_config nexusca_stv0297_config = {
-
-       .demod_address = 0x1C,
-       .inittab = nexusca_stv0297_inittab,
-       .invert = 1,
-       .stop_during_read = 1,
-};
-
-
-
-static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct av7110* av7110 = fe->dvb->priv;
-       u32 div;
-       u8 cfg, cpump, band_select;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (36125000 + p->frequency) / 166666;
-
-       cfg = 0x88;
-
-       if (p->frequency < 175000000)
-               cpump = 2;
-       else if (p->frequency < 390000000)
-               cpump = 1;
-       else if (p->frequency < 470000000)
-               cpump = 2;
-       else if (p->frequency < 750000000)
-               cpump = 1;
-       else
-               cpump = 3;
-
-       if (p->frequency < 175000000)
-               band_select = 0x0e;
-       else if (p->frequency < 470000000)
-               band_select = 0x05;
-       else
-               band_select = 0x03;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = ((div >> 10) & 0x60) | cfg;
-       data[3] = (cpump << 6) | band_select;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct l64781_config grundig_29504_401_config = {
-       .demod_address = 0x55,
-};
-
-
-
-static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
-{
-       int ret = 0;
-       int synced = (status & FE_HAS_LOCK) ? 1 : 0;
-
-       av7110->fe_status = status;
-
-       if (av7110->fe_synced == synced)
-               return 0;
-
-       if (av7110->playing) {
-               av7110->fe_synced = synced;
-               return 0;
-       }
-
-       if (mutex_lock_interruptible(&av7110->pid_mutex))
-               return -ERESTARTSYS;
-
-       if (synced) {
-               ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
-                       av7110->pids[DMX_PES_AUDIO],
-                       av7110->pids[DMX_PES_TELETEXT], 0,
-                       av7110->pids[DMX_PES_PCR]);
-               if (!ret)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
-       } else {
-               ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
-               if (!ret) {
-                       ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
-                       if (!ret)
-                               ret = av7110_wait_msgstate(av7110, GPMQBusy);
-               }
-       }
-
-       if (!ret)
-               av7110->fe_synced = synced;
-
-       mutex_unlock(&av7110->pid_mutex);
-       return ret;
-}
-
-static int av7110_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret)
-               ret = av7110->fe_set_frontend(fe);
-
-       return ret;
-}
-
-static int av7110_fe_init(struct dvb_frontend* fe)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret)
-               ret = av7110->fe_init(fe);
-       return ret;
-}
-
-static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       /* call the real implementation */
-       int ret = av7110->fe_read_status(fe, status);
-       if (!ret)
-               if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
-                       ret = av7110_fe_lock_fix(av7110, *status);
-       return ret;
-}
-
-static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret)
-               ret = av7110->fe_diseqc_reset_overload(fe);
-       return ret;
-}
-
-static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
-                                           struct dvb_diseqc_master_cmd* cmd)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret) {
-               av7110->saved_master_cmd = *cmd;
-               ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
-       }
-       return ret;
-}
-
-static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret) {
-               av7110->saved_minicmd = minicmd;
-               ret = av7110->fe_diseqc_send_burst(fe, minicmd);
-       }
-       return ret;
-}
-
-static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret) {
-               av7110->saved_tone = tone;
-               ret = av7110->fe_set_tone(fe, tone);
-       }
-       return ret;
-}
-
-static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret) {
-               av7110->saved_voltage = voltage;
-               ret = av7110->fe_set_voltage(fe, voltage);
-       }
-       return ret;
-}
-
-static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
-{
-       struct av7110* av7110 = fe->dvb->priv;
-
-       int ret = av7110_fe_lock_fix(av7110, 0);
-       if (!ret)
-               ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
-       return ret;
-}
-
-static void dvb_s_recover(struct av7110* av7110)
-{
-       av7110_fe_init(av7110->fe);
-
-       av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
-       if (av7110->saved_master_cmd.msg_len) {
-               msleep(20);
-               av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
-       }
-       msleep(20);
-       av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
-       msleep(20);
-       av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
-
-       av7110_fe_set_frontend(av7110->fe);
-}
-
-static u8 read_pwm(struct av7110* av7110)
-{
-       u8 b = 0xff;
-       u8 pwm;
-       struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
-                                { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
-
-       if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-static int frontend_init(struct av7110 *av7110)
-{
-       int ret;
-
-       if (av7110->dev->pci->subsystem_vendor == 0x110a) {
-               switch(av7110->dev->pci->subsystem_device) {
-               case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
-                       av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config,
-                                                   &av7110->i2c_adap, read_pwm(av7110));
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
-                       }
-                       break;
-               }
-
-       } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
-               switch(av7110->dev->pci->subsystem_device) {
-               case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
-               case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
-               case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
-
-                       // try the ALPS BSRV2 first of all
-                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
-                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
-                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
-                               av7110->fe->ops.set_tone = av7110_set_tone;
-                               av7110->recover = dvb_s_recover;
-                               break;
-                       }
-
-                       // try the ALPS BSRU6 now
-                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
-                               av7110->fe->tuner_priv = &av7110->i2c_adap;
-
-                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
-                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
-                               av7110->fe->ops.set_tone = av7110_set_tone;
-                               av7110->recover = dvb_s_recover;
-                               break;
-                       }
-
-                       // Try the grundig 29504-451
-                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
-                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
-                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
-                               av7110->fe->ops.set_tone = av7110_set_tone;
-                               av7110->recover = dvb_s_recover;
-                               break;
-                       }
-
-                       /* Try DVB-C cards */
-                       switch(av7110->dev->pci->subsystem_device) {
-                       case 0x0000:
-                               /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
-                               av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap,
-                                                       read_pwm(av7110));
-                               if (av7110->fe) {
-                                       av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
-                               }
-                               break;
-                       case 0x0003:
-                               /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
-                               av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap,
-                                                       read_pwm(av7110));
-                               if (av7110->fe) {
-                                       av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
-                               }
-                               break;
-                       }
-                       break;
-
-               case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
-                       // try ALPS TDLB7 first, then Grundig 29504-401
-                       av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params;
-                               break;
-                       }
-                       /* fall-thru */
-
-               case 0x0008: // Hauppauge/TT DVB-T
-                       // Grundig 29504-401
-                       av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap);
-                       if (av7110->fe)
-                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
-                       break;
-
-               case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
-
-                       av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
-                       }
-                       break;
-
-               case 0x0004: // Galaxis DVB-S rev1.3
-                       /* ALPS BSRV2 */
-                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
-                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
-                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
-                               av7110->fe->ops.set_tone = av7110_set_tone;
-                               av7110->recover = dvb_s_recover;
-                       }
-                       break;
-
-               case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
-                       /* Grundig 29504-451 */
-                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
-                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
-                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
-                               av7110->fe->ops.set_tone = av7110_set_tone;
-                               av7110->recover = dvb_s_recover;
-                       }
-                       break;
-
-               case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
-
-                       av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params;
-
-                               /* set TDA9819 into DVB mode */
-                               saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
-                               saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
-
-                               /* tuner on this needs a slower i2c bus speed */
-                               av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
-                               break;
-                       }
-                       break;
-
-               case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
-                       /* ALPS BSBE1 */
-                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap);
-                       if (av7110->fe) {
-                               av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
-                               av7110->fe->tuner_priv = &av7110->i2c_adap;
-
-                               if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) {
-                                       printk("dvb-ttpci: LNBP21 not found!\n");
-                                       if (av7110->fe->ops.release)
-                                               av7110->fe->ops.release(av7110->fe);
-                                       av7110->fe = NULL;
-                               } else {
-                                       av7110->fe->ops.dishnetwork_send_legacy_command = NULL;
-                                       av7110->recover = dvb_s_recover;
-                               }
-                       }
-                       break;
-               }
-       }
-
-       if (!av7110->fe) {
-               /* FIXME: propagate the failure code from the lower layers */
-               ret = -ENOMEM;
-               printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      av7110->dev->pci->vendor,
-                      av7110->dev->pci->device,
-                      av7110->dev->pci->subsystem_vendor,
-                      av7110->dev->pci->subsystem_device);
-       } else {
-               FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
-               FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
-
-               ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
-               if (ret < 0) {
-                       printk("av7110: Frontend registration failed!\n");
-                       dvb_frontend_detach(av7110->fe);
-                       av7110->fe = NULL;
-               }
-       }
-       return ret;
-}
-
-/* Budgetpatch note:
- * Original hardware design by Roberto Deza:
- * There is a DVB_Wiki at
- * http://www.linuxtv.org/
- *
- * New software triggering design by Emard that works on
- * original Roberto Deza's hardware:
- *
- * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
- * GPIO3 is in budget-patch hardware connectd to port B VSYNC
- * HS is an internal event of 7146, accessible with RPS
- * and temporarily raised high every n lines
- * (n in defined in the RPS_THRESH1 counter threshold)
- * I think HS is raised high on the beginning of the n-th line
- * and remains high until this n-th line that triggered
- * it is completely received. When the receiption of n-th line
- * ends, HS is lowered.
- *
- * To transmit data over DMA, 7146 needs changing state at
- * port B VSYNC pin. Any changing of port B VSYNC will
- * cause some DMA data transfer, with more or less packets loss.
- * It depends on the phase and frequency of VSYNC and
- * the way of 7146 is instructed to trigger on port B (defined
- * in DD1_INIT register, 3rd nibble from the right valid
- * numbers are 0-7, see datasheet)
- *
- * The correct triggering can minimize packet loss,
- * dvbtraffic should give this stable bandwidths:
- *   22k transponder = 33814 kbit/s
- * 27.5k transponder = 38045 kbit/s
- * by experiment it is found that the best results
- * (stable bandwidths and almost no packet loss)
- * are obtained using DD1_INIT triggering number 2
- * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
- * and a VSYNC phase that occurs in the middle of DMA transfer
- * (about byte 188*512=96256 in the DMA window).
- *
- * Phase of HS is still not clear to me how to control,
- * It just happens to be so. It can be seen if one enables
- * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
- * time RPS_INTERRUPT is called, the Event Counter 1 will
- * increment. That's how the 7146 is programmed to do event
- * counting in this budget-patch.c
- * I *think* HPS setting has something to do with the phase
- * of HS but I can't be 100% sure in that.
- *
- * hardware debug note: a working budget card (including budget patch)
- * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
- * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
- * and that means 3*25=75 Hz of interrupt freqency, as seen by
- * watch cat /proc/interrupts
- *
- * If this frequency is 3x lower (and data received in the DMA
- * buffer don't start with 0x47, but in the middle of packets,
- * whose lengths appear to be like 188 292 188 104 etc.
- * this means VSYNC line is not connected in the hardware.
- * (check soldering pcb and pins)
- * The same behaviour of missing VSYNC can be duplicated on budget
- * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
- */
-static int __devinit av7110_attach(struct saa7146_dev* dev,
-                                  struct saa7146_pci_extension_data *pci_ext)
-{
-       const int length = TS_WIDTH * TS_HEIGHT;
-       struct pci_dev *pdev = dev->pci;
-       struct av7110 *av7110;
-       struct task_struct *thread;
-       int ret, count = 0;
-
-       dprintk(4, "dev: %p\n", dev);
-
-       /* Set RPS_IRQ to 1 to track rps1 activity.
-        * Enabling this won't send any interrupt to PC CPU.
-        */
-#define RPS_IRQ 0
-
-       if (budgetpatch == 1) {
-               budgetpatch = 0;
-               /* autodetect the presence of budget patch
-                * this only works if saa7146 has been recently
-                * reset with with MASK_31 to MC1
-                *
-                * will wait for VBI_B event (vertical blank at port B)
-                * and will reset GPIO3 after VBI_B is detected.
-                * (GPIO3 should be raised high by CPU to
-                * test if GPIO3 will generate vertical blank signal
-                * in budget patch GPIO3 is connected to VSYNC_B
-                */
-
-               /* RESET SAA7146 */
-               saa7146_write(dev, MC1, MASK_31);
-               /* autodetection success seems to be time-dependend after reset */
-
-               /* Fix VSYNC level */
-               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-               /* set vsync_b triggering */
-               saa7146_write(dev, DD1_STREAM_B, 0);
-               /* port B VSYNC at rising edge */
-               saa7146_write(dev, DD1_INIT, 0x00000200);
-               saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
-               saa7146_write(dev, MC2,
-                             1 * (MASK_08 | MASK_24)  |   // BRS control
-                             0 * (MASK_09 | MASK_25)  |   // a
-                             1 * (MASK_10 | MASK_26)  |   // b
-                             0 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
-                             0 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
-                             0 * (MASK_01 | MASK_15)      // DEBI
-               );
-
-               /* start writing RPS1 code from beginning */
-               count = 0;
-               /* Disable RPS1 */
-               saa7146_write(dev, MC1, MASK_29);
-               /* RPS1 timeout disable */
-               saa7146_write(dev, RPS_TOV1, 0);
-               WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
-               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-               WRITE_RPS1(GPIO3_MSK);
-               WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
-               /* issue RPS1 interrupt to increment counter */
-               WRITE_RPS1(CMD_INTERRUPT);
-#endif
-               WRITE_RPS1(CMD_STOP);
-               /* Jump to begin of RPS program as safety measure               (p37) */
-               WRITE_RPS1(CMD_JUMP);
-               WRITE_RPS1(dev->d_rps1.dma_handle);
-
-#if RPS_IRQ
-               /* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
-                * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
-                * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
-                */
-               saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-               /* set event counter 1 threshold to maximum allowed value        (rEC p55) */
-               saa7146_write(dev, ECT1R,  0x3fff );
-#endif
-               /* Set RPS1 Address register to point to RPS code               (r108 p42) */
-               saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-               /* Enable RPS1,                                                 (rFC p33) */
-               saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
-
-               mdelay(10);
-               /* now send VSYNC_B to rps1 by rising GPIO3 */
-               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-               mdelay(10);
-               /* if rps1 responded by lowering the GPIO3,
-                * then we have budgetpatch hardware
-                */
-               if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
-                       budgetpatch = 1;
-                       printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
-               }
-               /* Disable RPS1 */
-               saa7146_write(dev, MC1, ( MASK_29 ));
-#if RPS_IRQ
-               printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
-#endif
-       }
-
-       /* prepare the av7110 device struct */
-       av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
-       if (!av7110) {
-               dprintk(1, "out of memory\n");
-               return -ENOMEM;
-       }
-
-       av7110->card_name = (char*) pci_ext->ext_priv;
-       av7110->dev = dev;
-       dev->ext_priv = av7110;
-
-       ret = get_firmware(av7110);
-       if (ret < 0)
-               goto err_kfree_0;
-
-       ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
-                                  THIS_MODULE, &dev->pci->dev, adapter_nr);
-       if (ret < 0)
-               goto err_put_firmware_1;
-
-       /* the Siemens DVB needs this if you want to have the i2c chips
-          get recognized before the main driver is fully loaded */
-       saa7146_write(dev, GPIO_CTRL, 0x500000);
-
-       strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
-
-       saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
-
-       ret = i2c_add_adapter(&av7110->i2c_adap);
-       if (ret < 0)
-               goto err_dvb_unregister_adapter_2;
-
-       ttpci_eeprom_parse_mac(&av7110->i2c_adap,
-                              av7110->dvb_adapter.proposed_mac);
-       ret = -ENOMEM;
-
-       /* full-ts mod? */
-       if (full_ts)
-               av7110->full_ts = true;
-
-       /* check for full-ts flag in eeprom */
-       if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) {
-               u8 flags = i2c_readreg(av7110, 0xaa, 2);
-               if (flags != 0xff && (flags & 0x01))
-                       av7110->full_ts = true;
-       }
-
-       if (av7110->full_ts) {
-               printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n");
-               spin_lock_init(&av7110->feedlock1);
-               av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
-                                                                &av7110->pt);
-               if (!av7110->grabbing)
-                       goto err_i2c_del_3;
-
-               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-               saa7146_write(dev, MC2, (MASK_10 | MASK_26));
-
-               saa7146_write(dev, DD1_INIT, 0x00000600);
-               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
-               saa7146_write(dev, BRS_CTRL, 0x60000000);
-               saa7146_write(dev, MC2, MASK_08 | MASK_24);
-
-               /* dma3 */
-               saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
-               saa7146_write(dev, BASE_ODD3, 0);
-               saa7146_write(dev, BASE_EVEN3, 0);
-               saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
-               saa7146_write(dev, PITCH3, TS_WIDTH);
-               saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
-               saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
-               saa7146_write(dev, MC2, MASK_04 | MASK_20);
-
-               tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
-
-       } else if (budgetpatch) {
-               spin_lock_init(&av7110->feedlock1);
-               av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
-                                                                &av7110->pt);
-               if (!av7110->grabbing)
-                       goto err_i2c_del_3;
-
-               saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
-               saa7146_write(dev, BCS_CTRL, 0x80400040);
-               /* set dd1 stream a & b */
-               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-               saa7146_write(dev, DD1_INIT, 0x03000200);
-               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-               saa7146_write(dev, BRS_CTRL, 0x60000000);
-               saa7146_write(dev, BASE_ODD3, 0);
-               saa7146_write(dev, BASE_EVEN3, 0);
-               saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
-               saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
-
-               saa7146_write(dev, PITCH3, TS_WIDTH);
-               saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
-
-               /* upload all */
-               saa7146_write(dev, MC2, 0x077c077c);
-               saa7146_write(dev, GPIO_CTRL, 0x000000);
-#if RPS_IRQ
-               /* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
-                * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
-                * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
-                */
-               saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-               /* set event counter 1 threshold to maximum allowed value        (rEC p55) */
-               saa7146_write(dev, ECT1R,  0x3fff );
-#endif
-               /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
-               count = 0;
-
-               /* Wait Source Line Counter Threshold                           (p36) */
-               WRITE_RPS1(CMD_PAUSE | EVT_HS);
-               /* Set GPIO3=1                                                  (p42) */
-               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-               WRITE_RPS1(GPIO3_MSK);
-               WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
-#if RPS_IRQ
-               /* issue RPS1 interrupt */
-               WRITE_RPS1(CMD_INTERRUPT);
-#endif
-               /* Wait reset Source Line Counter Threshold                     (p36) */
-               WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
-               /* Set GPIO3=0                                                  (p42) */
-               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-               WRITE_RPS1(GPIO3_MSK);
-               WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
-               /* issue RPS1 interrupt */
-               WRITE_RPS1(CMD_INTERRUPT);
-#endif
-               /* Jump to begin of RPS program                                 (p37) */
-               WRITE_RPS1(CMD_JUMP);
-               WRITE_RPS1(dev->d_rps1.dma_handle);
-
-               /* Fix VSYNC level */
-               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-               /* Set RPS1 Address register to point to RPS code               (r108 p42) */
-               saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-               /* Set Source Line Counter Threshold, using BRS                 (rCC p43)
-                * It generates HS event every TS_HEIGHT lines
-                * this is related to TS_WIDTH set in register
-                * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
-                * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
-                * then RPS_THRESH1 should be set to trigger
-                * every TS_HEIGHT (512) lines.
-                */
-               saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
-
-               /* Enable RPS1                                                  (rFC p33) */
-               saa7146_write(dev, MC1, (MASK_13 | MASK_29));
-
-               /* end of budgetpatch register initialization */
-               tasklet_init (&av7110->vpe_tasklet,  vpeirq,  (unsigned long) av7110);
-       } else {
-               saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
-               saa7146_write(dev, BCS_CTRL, 0x80400040);
-
-               /* set dd1 stream a & b */
-               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-               saa7146_write(dev, DD1_INIT, 0x03000000);
-               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
-               /* upload all */
-               saa7146_write(dev, MC2, 0x077c077c);
-               saa7146_write(dev, GPIO_CTRL, 0x000000);
-       }
-
-       tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
-       tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
-
-       mutex_init(&av7110->pid_mutex);
-
-       /* locks for data transfers from/to AV7110 */
-       spin_lock_init(&av7110->debilock);
-       mutex_init(&av7110->dcomlock);
-       av7110->debitype = -1;
-
-       /* default OSD window */
-       av7110->osdwin = 1;
-       mutex_init(&av7110->osd_mutex);
-
-       /* TV standard */
-       av7110->vidmode = tv_standard == 1 ? AV7110_VIDEO_MODE_NTSC
-                                          : AV7110_VIDEO_MODE_PAL;
-
-       /* ARM "watchdog" */
-       init_waitqueue_head(&av7110->arm_wait);
-       av7110->arm_thread = NULL;
-
-       /* allocate and init buffers */
-       av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
-       if (!av7110->debi_virt)
-               goto err_saa71466_vfree_4;
-
-
-       av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
-       if (!av7110->iobuf)
-               goto err_pci_free_5;
-
-       ret = av7110_av_init(av7110);
-       if (ret < 0)
-               goto err_iobuf_vfree_6;
-
-       /* init BMP buffer */
-       av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
-       init_waitqueue_head(&av7110->bmpq);
-
-       ret = av7110_ca_init(av7110);
-       if (ret < 0)
-               goto err_av7110_av_exit_7;
-
-       /* load firmware into AV7110 cards */
-       ret = av7110_bootarm(av7110);
-       if (ret < 0)
-               goto err_av7110_ca_exit_8;
-
-       ret = av7110_firmversion(av7110);
-       if (ret < 0)
-               goto err_stop_arm_9;
-
-       if (FW_VERSION(av7110->arm_app)<0x2501)
-               printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
-                       "System might be unstable!\n", FW_VERSION(av7110->arm_app));
-
-       thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
-       if (IS_ERR(thread)) {
-               ret = PTR_ERR(thread);
-               goto err_stop_arm_9;
-       }
-       av7110->arm_thread = thread;
-
-       /* set initial volume in mixer struct */
-       av7110->mixer.volume_left  = volume;
-       av7110->mixer.volume_right = volume;
-
-       ret = av7110_register(av7110);
-       if (ret < 0)
-               goto err_arm_thread_stop_10;
-
-       init_av7110_av(av7110);
-
-       /* special case DVB-C: these cards have an analog tuner
-          plus need some special handling, so we have separate
-          saa7146_ext_vv data for these... */
-       ret = av7110_init_v4l(av7110);
-       if (ret < 0)
-               goto err_av7110_unregister_11;
-
-       av7110->dvb_adapter.priv = av7110;
-       ret = frontend_init(av7110);
-       if (ret < 0)
-               goto err_av7110_exit_v4l_12;
-
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
-       av7110_ir_init(av7110);
-#endif
-       printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
-       av7110_num++;
-out:
-       return ret;
-
-err_av7110_exit_v4l_12:
-       av7110_exit_v4l(av7110);
-err_av7110_unregister_11:
-       dvb_unregister(av7110);
-err_arm_thread_stop_10:
-       av7110_arm_sync(av7110);
-err_stop_arm_9:
-       /* Nothing to do. Rejoice. */
-err_av7110_ca_exit_8:
-       av7110_ca_exit(av7110);
-err_av7110_av_exit_7:
-       av7110_av_exit(av7110);
-err_iobuf_vfree_6:
-       vfree(av7110->iobuf);
-err_pci_free_5:
-       pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
-err_saa71466_vfree_4:
-       if (av7110->grabbing)
-               saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
-err_i2c_del_3:
-       i2c_del_adapter(&av7110->i2c_adap);
-err_dvb_unregister_adapter_2:
-       dvb_unregister_adapter(&av7110->dvb_adapter);
-err_put_firmware_1:
-       put_firmware(av7110);
-err_kfree_0:
-       kfree(av7110);
-       goto out;
-}
-
-static int __devexit av7110_detach(struct saa7146_dev* saa)
-{
-       struct av7110 *av7110 = saa->ext_priv;
-       dprintk(4, "%p\n", av7110);
-
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
-       av7110_ir_exit(av7110);
-#endif
-       if (budgetpatch || av7110->full_ts) {
-               if (budgetpatch) {
-                       /* Disable RPS1 */
-                       saa7146_write(saa, MC1, MASK_29);
-                       /* VSYNC LOW (inactive) */
-                       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
-               }
-               saa7146_write(saa, MC1, MASK_20);       /* DMA3 off */
-               SAA7146_IER_DISABLE(saa, MASK_10);
-               SAA7146_ISR_CLEAR(saa, MASK_10);
-               msleep(50);
-               tasklet_kill(&av7110->vpe_tasklet);
-               saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
-       }
-       av7110_exit_v4l(av7110);
-
-       av7110_arm_sync(av7110);
-
-       tasklet_kill(&av7110->debi_tasklet);
-       tasklet_kill(&av7110->gpio_tasklet);
-
-       dvb_unregister(av7110);
-
-       SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
-       SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
-
-       av7110_ca_exit(av7110);
-       av7110_av_exit(av7110);
-
-       vfree(av7110->iobuf);
-       pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
-                           av7110->debi_bus);
-
-       i2c_del_adapter(&av7110->i2c_adap);
-
-       dvb_unregister_adapter (&av7110->dvb_adapter);
-
-       av7110_num--;
-
-       put_firmware(av7110);
-
-       kfree(av7110);
-
-       saa->ext_priv = NULL;
-
-       return 0;
-}
-
-
-static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
-{
-       struct av7110 *av7110 = dev->ext_priv;
-
-       //print_time("av7110_irq");
-
-       /* Note: Don't try to handle the DEBI error irq (MASK_18), in
-        * intel mode the timeout is asserted all the time...
-        */
-
-       if (*isr & MASK_19) {
-               //printk("av7110_irq: DEBI\n");
-               /* Note 1: The DEBI irq is level triggered: We must enable it
-                * only after we started a DMA xfer, and disable it here
-                * immediately, or it will be signalled all the time while
-                * DEBI is idle.
-                * Note 2: You would think that an irq which is masked is
-                * not signalled by the hardware. Not so for the SAA7146:
-                * An irq is signalled as long as the corresponding bit
-                * in the ISR is set, and disabling irqs just prevents the
-                * hardware from setting the ISR bit. This means a) that we
-                * must clear the ISR *after* disabling the irq (which is why
-                * we must do it here even though saa7146_core did it already),
-                * and b) that if we were to disable an edge triggered irq
-                * (like the gpio irqs sadly are) temporarily we would likely
-                * loose some. This sucks :-(
-                */
-               SAA7146_IER_DISABLE(av7110->dev, MASK_19);
-               SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
-               tasklet_schedule(&av7110->debi_tasklet);
-       }
-
-       if (*isr & MASK_03) {
-               //printk("av7110_irq: GPIO\n");
-               tasklet_schedule(&av7110->gpio_tasklet);
-       }
-
-       if (*isr & MASK_10)
-               tasklet_schedule(&av7110->vpe_tasklet);
-}
-
-
-static struct saa7146_extension av7110_extension_driver;
-
-#define MAKE_AV7110_INFO(x_var,x_name) \
-static struct saa7146_pci_extension_data x_var = { \
-       .ext_priv = x_name, \
-       .ext = &av7110_extension_driver }
-
-MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
-MAKE_AV7110_INFO(ttt_1_X,    "Technotrend/Hauppauge WinTV DVB-T rev1.X");
-MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
-MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
-MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
-MAKE_AV7110_INFO(tts_2_3,    "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
-MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
-MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
-MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
-MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
-MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");
-
-static struct pci_device_id pci_tbl[] = {
-       MAKE_EXTENSION_PCI(fsc,         0x110a, 0x0000),
-       MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
-       MAKE_EXTENSION_PCI(ttt_1_X,     0x13c2, 0x0001),
-       MAKE_EXTENSION_PCI(ttc_2_X,     0x13c2, 0x0002),
-       MAKE_EXTENSION_PCI(tts_2_X,     0x13c2, 0x0003),
-       MAKE_EXTENSION_PCI(gxs_1_3,     0x13c2, 0x0004),
-       MAKE_EXTENSION_PCI(fss,         0x13c2, 0x0006),
-       MAKE_EXTENSION_PCI(ttt,         0x13c2, 0x0008),
-       MAKE_EXTENSION_PCI(ttc_1_X,     0x13c2, 0x000a),
-       MAKE_EXTENSION_PCI(tts_2_3,     0x13c2, 0x000e),
-       MAKE_EXTENSION_PCI(tts_1_3se,   0x13c2, 0x1002),
-
-/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
-/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
-
-       {
-               .vendor    = 0,
-       }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-
-static struct saa7146_extension av7110_extension_driver = {
-       .name           = "av7110",
-       .flags          = SAA7146_USE_I2C_IRQ,
-
-       .module         = THIS_MODULE,
-       .pci_tbl        = &pci_tbl[0],
-       .attach         = av7110_attach,
-       .detach         = __devexit_p(av7110_detach),
-
-       .irq_mask       = MASK_19 | MASK_03 | MASK_10,
-       .irq_func       = av7110_irq,
-};
-
-
-static int __init av7110_init(void)
-{
-       int retval;
-       retval = saa7146_register_extension(&av7110_extension_driver);
-       return retval;
-}
-
-
-static void __exit av7110_exit(void)
-{
-       saa7146_unregister_extension(&av7110_extension_driver);
-}
-
-module_init(av7110_init);
-module_exit(av7110_exit);
-
-MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
-                  "Siemens, Technotrend, Hauppauge");
-MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
deleted file mode 100644 (file)
index 88b3b2d..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-#ifndef _AV7110_H_
-#define _AV7110_H_
-
-#include <linux/interrupt.h>
-#include <linux/socket.h>
-#include <linux/netdevice.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
-#include <linux/dvb/dmx.h>
-#include <linux/dvb/ca.h>
-#include <linux/dvb/osd.h>
-#include <linux/dvb/net.h>
-#include <linux/mutex.h>
-
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_frontend.h"
-#include "ves1820.h"
-#include "ves1x93.h"
-#include "stv0299.h"
-#include "tda8083.h"
-#include "sp8870.h"
-#include "stv0297.h"
-#include "l64781.h"
-
-#include <media/saa7146_vv.h>
-
-
-#define ANALOG_TUNER_VES1820 1
-#define ANALOG_TUNER_STV0297 2
-
-extern int av7110_debug;
-
-#define dprintk(level,args...) \
-           do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0)
-
-#define MAXFILT 32
-
-enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
-
-enum av7110_video_mode {
-       AV7110_VIDEO_MODE_PAL   = 0,
-       AV7110_VIDEO_MODE_NTSC  = 1
-};
-
-struct av7110_p2t {
-       u8                pes[TS_SIZE];
-       u8                counter;
-       long int          pos;
-       int               frags;
-       struct dvb_demux_feed *feed;
-};
-
-/* video MPEG decoder events: */
-/* (code copied from dvb_frontend.c, should maybe be factored out...) */
-#define MAX_VIDEO_EVENT 8
-struct dvb_video_events {
-       struct video_event        events[MAX_VIDEO_EVENT];
-       int                       eventw;
-       int                       eventr;
-       int                       overflow;
-       wait_queue_head_t         wait_queue;
-       spinlock_t                lock;
-};
-
-
-struct av7110;
-
-/* infrared remote control */
-struct infrared {
-       u16     key_map[256];
-       struct input_dev        *input_dev;
-       char                    input_phys[32];
-       struct timer_list       keyup_timer;
-       struct tasklet_struct   ir_tasklet;
-       void                    (*ir_handler)(struct av7110 *av7110, u32 ircom);
-       u32                     ir_command;
-       u32                     ir_config;
-       u32                     device_mask;
-       u8                      protocol;
-       u8                      inversion;
-       u16                     last_key;
-       u16                     last_toggle;
-       u8                      delay_timer_finished;
-};
-
-
-/* place to store all the necessary device information */
-struct av7110 {
-
-       /* devices */
-
-       struct dvb_device       dvb_dev;
-       struct dvb_net          dvb_net;
-
-       struct video_device     *v4l_dev;
-       struct video_device     *vbi_dev;
-
-       struct saa7146_dev      *dev;
-
-       struct i2c_adapter      i2c_adap;
-
-       char                    *card_name;
-
-       /* support for analog module of dvb-c */
-       int                     analog_tuner_flags;
-       int                     current_input;
-       u32                     current_freq;
-
-       struct tasklet_struct   debi_tasklet;
-       struct tasklet_struct   gpio_tasklet;
-
-       int adac_type;         /* audio DAC type */
-#define DVB_ADAC_TI      0
-#define DVB_ADAC_CRYSTAL  1
-#define DVB_ADAC_MSP34x0  2
-#define DVB_ADAC_MSP34x5  3
-#define DVB_ADAC_NONE   -1
-
-
-       /* buffers */
-
-       void                   *iobuf;   /* memory for all buffers */
-       struct dvb_ringbuffer   avout;   /* buffer for video or A/V mux */
-#define AVOUTLEN (128*1024)
-       struct dvb_ringbuffer   aout;    /* buffer for audio */
-#define AOUTLEN (64*1024)
-       void                   *bmpbuf;
-#define BMPLEN (8*32768+1024)
-
-       /* bitmap buffers and states */
-
-       int                     bmpp;
-       int                     bmplen;
-       volatile int            bmp_state;
-#define BMP_NONE     0
-#define BMP_LOADING  1
-#define BMP_LOADED   2
-       wait_queue_head_t       bmpq;
-
-
-       /* DEBI and polled command interface */
-
-       spinlock_t              debilock;
-       struct mutex            dcomlock;
-       volatile int            debitype;
-       volatile int            debilen;
-
-
-       /* Recording and playback flags */
-
-       int                     rec_mode;
-       int                     playing;
-#define RP_NONE  0
-#define RP_VIDEO 1
-#define RP_AUDIO 2
-#define RP_AV   3
-
-
-       /* OSD */
-
-       int                     osdwin;      /* currently active window */
-       u16                     osdbpp[8];
-       struct mutex            osd_mutex;
-
-       /* CA */
-
-       ca_slot_info_t          ci_slot[2];
-
-       enum av7110_video_mode  vidmode;
-       struct dmxdev           dmxdev;
-       struct dvb_demux        demux;
-
-       struct dmx_frontend     hw_frontend;
-       struct dmx_frontend     mem_frontend;
-
-       /* for budget mode demux1 */
-       struct dmxdev           dmxdev1;
-       struct dvb_demux        demux1;
-       struct dvb_net          dvb_net1;
-       spinlock_t              feedlock1;
-       int                     feeding1;
-       u32                     ttbp;
-       unsigned char           *grabbing;
-       struct saa7146_pgtable  pt;
-       struct tasklet_struct   vpe_tasklet;
-       bool                    full_ts;
-
-       int                     fe_synced;
-       struct mutex            pid_mutex;
-
-       int                     video_blank;
-       struct video_status     videostate;
-       u16                     display_panscan;
-       int                     display_ar;
-       int                     trickmode;
-#define TRICK_NONE   0
-#define TRICK_FAST   1
-#define TRICK_SLOW   2
-#define TRICK_FREEZE 3
-       struct audio_status     audiostate;
-
-       struct dvb_demux_filter *handle2filter[32];
-       struct av7110_p2t        p2t_filter[MAXFILT];
-       struct dvb_filter_pes2ts p2t[2];
-       struct ipack             ipack[2];
-       u8                      *kbuf[2];
-
-       int sinfo;
-       int feeding;
-
-       int arm_errors;
-       int registered;
-
-
-       /* AV711X */
-
-       u32                 arm_fw;
-       u32                 arm_rtsl;
-       u32                 arm_vid;
-       u32                 arm_app;
-       u32                 avtype;
-       int                 arm_ready;
-       struct task_struct *arm_thread;
-       wait_queue_head_t   arm_wait;
-       u16                 arm_loops;
-
-       void               *debi_virt;
-       dma_addr_t          debi_bus;
-
-       u16                 pids[DMX_PES_OTHER];
-
-       struct dvb_ringbuffer    ci_rbuffer;
-       struct dvb_ringbuffer    ci_wbuffer;
-
-       struct audio_mixer      mixer;
-
-       struct dvb_adapter       dvb_adapter;
-       struct dvb_device        *video_dev;
-       struct dvb_device        *audio_dev;
-       struct dvb_device        *ca_dev;
-       struct dvb_device        *osd_dev;
-
-       struct dvb_video_events  video_events;
-       video_size_t             video_size;
-
-       u16                     wssMode;
-       u16                     wssData;
-
-       struct infrared         ir;
-
-       /* firmware stuff */
-       unsigned char *bin_fw;
-       unsigned long size_fw;
-
-       unsigned char *bin_dpram;
-       unsigned long size_dpram;
-
-       unsigned char *bin_root;
-       unsigned long size_root;
-
-       struct dvb_frontend* fe;
-       fe_status_t fe_status;
-
-       /* crash recovery */
-       void                            (*recover)(struct av7110* av7110);
-       fe_sec_voltage_t                saved_voltage;
-       fe_sec_tone_mode_t              saved_tone;
-       struct dvb_diseqc_master_cmd    saved_master_cmd;
-       fe_sec_mini_cmd_t               saved_minicmd;
-
-       int (*fe_init)(struct dvb_frontend* fe);
-       int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
-       int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
-       int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
-       int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
-       int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
-       int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
-       int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
-       int (*fe_set_frontend)(struct dvb_frontend *fe);
-};
-
-
-extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
-                      u16 subpid, u16 pcrpid);
-
-extern int av7110_check_ir_config(struct av7110 *av7110, int force);
-extern int av7110_ir_init(struct av7110 *av7110);
-extern void av7110_ir_exit(struct av7110 *av7110);
-
-/* msp3400 i2c subaddresses */
-#define MSP_WR_DEM 0x10
-#define MSP_RD_DEM 0x11
-#define MSP_WR_DSP 0x12
-#define MSP_RD_DSP 0x13
-
-extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
-extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
-extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
-
-
-extern int av7110_init_analog_module(struct av7110 *av7110);
-extern int av7110_init_v4l(struct av7110 *av7110);
-extern int av7110_exit_v4l(struct av7110 *av7110);
-
-#endif /* _AV7110_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
deleted file mode 100644 (file)
index 952b33d..0000000
+++ /dev/null
@@ -1,1626 +0,0 @@
-/*
- * av7110_av.c: audio and video MPEG decoder stuff
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * originally based on code by:
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "av7110_av.h"
-#include "av7110_ipack.h"
-
-/* MPEG-2 (ISO 13818 / H.222.0) stream types */
-#define PROG_STREAM_MAP  0xBC
-#define PRIVATE_STREAM1  0xBD
-#define PADDING_STREAM  0xBE
-#define PRIVATE_STREAM2  0xBF
-#define AUDIO_STREAM_S  0xC0
-#define AUDIO_STREAM_E  0xDF
-#define VIDEO_STREAM_S  0xE0
-#define VIDEO_STREAM_E  0xEF
-#define ECM_STREAM      0xF0
-#define EMM_STREAM      0xF1
-#define DSM_CC_STREAM   0xF2
-#define ISO13522_STREAM  0xF3
-#define PROG_STREAM_DIR  0xFF
-
-#define PTS_DTS_FLAGS   0xC0
-
-//pts_dts flags
-#define PTS_ONLY        0x80
-#define PTS_DTS                 0xC0
-#define TS_SIZE                 188
-#define TRANS_ERROR     0x80
-#define PAY_START       0x40
-#define TRANS_PRIO      0x20
-#define PID_MASK_HI     0x1F
-//flags
-#define TRANS_SCRMBL1   0x80
-#define TRANS_SCRMBL2   0x40
-#define ADAPT_FIELD     0x20
-#define PAYLOAD                 0x10
-#define COUNT_MASK      0x0F
-
-// adaptation flags
-#define DISCON_IND      0x80
-#define RAND_ACC_IND    0x40
-#define ES_PRI_IND      0x20
-#define PCR_FLAG        0x10
-#define OPCR_FLAG       0x08
-#define SPLICE_FLAG     0x04
-#define TRANS_PRIV      0x02
-#define ADAP_EXT_FLAG   0x01
-
-// adaptation extension flags
-#define LTW_FLAG        0x80
-#define PIECE_RATE      0x40
-#define SEAM_SPLICE     0x20
-
-
-static void p_to_t(u8 const *buf, long int length, u16 pid,
-                  u8 *counter, struct dvb_demux_feed *feed);
-static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
-
-
-int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
-{
-       struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;
-
-       if (!(dvbdmxfeed->ts_type & TS_PACKET))
-               return 0;
-       if (buf[3] == 0xe0)      // video PES do not have a length in TS
-               buf[4] = buf[5] = 0;
-       if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
-               return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
-                                        &dvbdmxfeed->feed.ts, DMX_OK);
-       else
-               return dvb_filter_pes2ts(p2t, buf, len, 1);
-}
-
-static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
-{
-       struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
-
-       dvbdmxfeed->cb.ts(data, 188, NULL, 0,
-                         &dvbdmxfeed->feed.ts, DMX_OK);
-       return 0;
-}
-
-int av7110_av_start_record(struct av7110 *av7110, int av,
-                          struct dvb_demux_feed *dvbdmxfeed)
-{
-       int ret = 0;
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-
-       dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
-
-       if (av7110->playing || (av7110->rec_mode & av))
-               return -EBUSY;
-       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
-       dvbdmx->recording = 1;
-       av7110->rec_mode |= av;
-
-       switch (av7110->rec_mode) {
-       case RP_AUDIO:
-               dvb_filter_pes2ts_init(&av7110->p2t[0],
-                                      dvbdmx->pesfilter[0]->pid,
-                                      dvb_filter_pes2ts_cb,
-                                      (void *) dvbdmx->pesfilter[0]);
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
-               break;
-
-       case RP_VIDEO:
-               dvb_filter_pes2ts_init(&av7110->p2t[1],
-                                      dvbdmx->pesfilter[1]->pid,
-                                      dvb_filter_pes2ts_cb,
-                                      (void *) dvbdmx->pesfilter[1]);
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
-               break;
-
-       case RP_AV:
-               dvb_filter_pes2ts_init(&av7110->p2t[0],
-                                      dvbdmx->pesfilter[0]->pid,
-                                      dvb_filter_pes2ts_cb,
-                                      (void *) dvbdmx->pesfilter[0]);
-               dvb_filter_pes2ts_init(&av7110->p2t[1],
-                                      dvbdmx->pesfilter[1]->pid,
-                                      dvb_filter_pes2ts_cb,
-                                      (void *) dvbdmx->pesfilter[1]);
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
-               break;
-       }
-       return ret;
-}
-
-int av7110_av_start_play(struct av7110 *av7110, int av)
-{
-       int ret = 0;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (av7110->rec_mode)
-               return -EBUSY;
-       if (av7110->playing & av)
-               return -EBUSY;
-
-       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
-
-       if (av7110->playing == RP_NONE) {
-               av7110_ipack_reset(&av7110->ipack[0]);
-               av7110_ipack_reset(&av7110->ipack[1]);
-       }
-
-       av7110->playing |= av;
-       switch (av7110->playing) {
-       case RP_AUDIO:
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
-               break;
-       case RP_VIDEO:
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
-               av7110->sinfo = 0;
-               break;
-       case RP_AV:
-               av7110->sinfo = 0;
-               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
-               break;
-       }
-       return ret;
-}
-
-int av7110_av_stop(struct av7110 *av7110, int av)
-{
-       int ret = 0;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (!(av7110->playing & av) && !(av7110->rec_mode & av))
-               return 0;
-       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
-       if (av7110->playing) {
-               av7110->playing &= ~av;
-               switch (av7110->playing) {
-               case RP_AUDIO:
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
-                       break;
-               case RP_VIDEO:
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
-                       break;
-               case RP_NONE:
-                       ret = av7110_set_vidmode(av7110, av7110->vidmode);
-                       break;
-               }
-       } else {
-               av7110->rec_mode &= ~av;
-               switch (av7110->rec_mode) {
-               case RP_AUDIO:
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
-                       break;
-               case RP_VIDEO:
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
-                       break;
-               case RP_NONE:
-                       break;
-               }
-       }
-       return ret;
-}
-
-
-int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
-{
-       int len;
-       u32 sync;
-       u16 blen;
-
-       if (!dlen) {
-               wake_up(&buf->queue);
-               return -1;
-       }
-       while (1) {
-               len = dvb_ringbuffer_avail(buf);
-               if (len < 6) {
-                       wake_up(&buf->queue);
-                       return -1;
-               }
-               sync =  DVB_RINGBUFFER_PEEK(buf, 0) << 24;
-               sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16;
-               sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
-               sync |= DVB_RINGBUFFER_PEEK(buf, 3);
-
-               if (((sync &~ 0x0f) == 0x000001e0) ||
-                   ((sync &~ 0x1f) == 0x000001c0) ||
-                   (sync == 0x000001bd))
-                       break;
-               printk("resync\n");
-               DVB_RINGBUFFER_SKIP(buf, 1);
-       }
-       blen =  DVB_RINGBUFFER_PEEK(buf, 4) << 8;
-       blen |= DVB_RINGBUFFER_PEEK(buf, 5);
-       blen += 6;
-       if (len < blen || blen > dlen) {
-               //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
-               wake_up(&buf->queue);
-               return -1;
-       }
-
-       dvb_ringbuffer_read(buf, dest, (size_t) blen);
-
-       dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
-              (unsigned long) buf->pread, (unsigned long) buf->pwrite);
-       wake_up(&buf->queue);
-       return blen;
-}
-
-
-int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
-{
-       int err, vol, val, balance = 0;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       av7110->mixer.volume_left = volleft;
-       av7110->mixer.volume_right = volright;
-
-       switch (av7110->adac_type) {
-       case DVB_ADAC_TI:
-               volleft = (volleft * 256) / 1036;
-               volright = (volright * 256) / 1036;
-               if (volleft > 0x3f)
-                       volleft = 0x3f;
-               if (volright > 0x3f)
-                       volright = 0x3f;
-               if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
-                       return err;
-               return SendDAC(av7110, 4, volright);
-
-       case DVB_ADAC_CRYSTAL:
-               volleft = 127 - volleft / 2;
-               volright = 127 - volright / 2;
-               i2c_writereg(av7110, 0x20, 0x03, volleft);
-               i2c_writereg(av7110, 0x20, 0x04, volright);
-               return 0;
-
-       case DVB_ADAC_MSP34x0:
-               vol  = (volleft > volright) ? volleft : volright;
-               val     = (vol * 0x73 / 255) << 8;
-               if (vol > 0)
-                      balance = ((volright - volleft) * 127) / vol;
-               msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
-               msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
-               msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
-               return 0;
-
-       case DVB_ADAC_MSP34x5:
-               vol = (volleft > volright) ? volleft : volright;
-               val = (vol * 0x73 / 255) << 8;
-               if (vol > 0)
-                       balance = ((volright - volleft) * 127) / vol;
-               msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
-               msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
-               return 0;
-       }
-
-       return 0;
-}
-
-int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
-{
-       int ret;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
-
-       if (!ret && !av7110->playing) {
-               ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
-                          av7110->pids[DMX_PES_AUDIO],
-                          av7110->pids[DMX_PES_TELETEXT],
-                          0, av7110->pids[DMX_PES_PCR]);
-               if (!ret)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
-       }
-       return ret;
-}
-
-
-static enum av7110_video_mode sw2mode[16] = {
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
-       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
-       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC,
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
-       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
-};
-
-static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
-{
-       int i;
-       int hsize, vsize;
-       int sw;
-       u8 *p;
-       int ret = 0;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (av7110->sinfo)
-               return 0;
-       for (i = 7; i < count - 10; i++) {
-               p = buf + i;
-               if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
-                       continue;
-               p += 4;
-               hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
-               vsize = ((p[1] &0x0F) << 8) | (p[2]);
-               sw = (p[3] & 0x0F);
-               ret = av7110_set_vidmode(av7110, sw2mode[sw]);
-               if (!ret) {
-                       dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
-                       av7110->sinfo = 1;
-               }
-               break;
-       }
-       return ret;
-}
-
-
-/****************************************************************************
- * I/O buffer management and control
- ****************************************************************************/
-
-static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
-                                        const u8 *buf, unsigned long count)
-{
-       unsigned long todo = count;
-       int free;
-
-       while (todo > 0) {
-               if (dvb_ringbuffer_free(rbuf) < 2048) {
-                       if (wait_event_interruptible(rbuf->queue,
-                                                    (dvb_ringbuffer_free(rbuf) >= 2048)))
-                               return count - todo;
-               }
-               free = dvb_ringbuffer_free(rbuf);
-               if (free > todo)
-                       free = todo;
-               dvb_ringbuffer_write(rbuf, buf, free);
-               todo -= free;
-               buf += free;
-       }
-
-       return count - todo;
-}
-
-static void play_video_cb(u8 *buf, int count, void *priv)
-{
-       struct av7110 *av7110 = (struct av7110 *) priv;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if ((buf[3] & 0xe0) == 0xe0) {
-               get_video_format(av7110, buf, count);
-               aux_ring_buffer_write(&av7110->avout, buf, count);
-       } else
-               aux_ring_buffer_write(&av7110->aout, buf, count);
-}
-
-static void play_audio_cb(u8 *buf, int count, void *priv)
-{
-       struct av7110 *av7110 = (struct av7110 *) priv;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       aux_ring_buffer_write(&av7110->aout, buf, count);
-}
-
-
-#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
-
-static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
-                      unsigned long count, int nonblock, int type)
-{
-       struct dvb_ringbuffer *rb;
-       u8 *kb;
-       unsigned long todo = count;
-
-       dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
-
-       rb = (type) ? &av7110->avout : &av7110->aout;
-       kb = av7110->kbuf[type];
-
-       if (!kb)
-               return -ENOBUFS;
-
-       if (nonblock && !FREE_COND_TS)
-               return -EWOULDBLOCK;
-
-       while (todo >= TS_SIZE) {
-               if (!FREE_COND_TS) {
-                       if (nonblock)
-                               return count - todo;
-                       if (wait_event_interruptible(rb->queue, FREE_COND_TS))
-                               return count - todo;
-               }
-               if (copy_from_user(kb, buf, TS_SIZE))
-                       return -EFAULT;
-               write_ts_to_decoder(av7110, type, kb, TS_SIZE);
-               todo -= TS_SIZE;
-               buf += TS_SIZE;
-       }
-
-       return count - todo;
-}
-
-
-#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
-                  dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
-
-static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf,
-                       unsigned long count, int nonblock, int type)
-{
-       unsigned long todo = count, n;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (!av7110->kbuf[type])
-               return -ENOBUFS;
-
-       if (nonblock && !FREE_COND)
-               return -EWOULDBLOCK;
-
-       while (todo > 0) {
-               if (!FREE_COND) {
-                       if (nonblock)
-                               return count - todo;
-                       if (wait_event_interruptible(av7110->avout.queue,
-                                                    FREE_COND))
-                               return count - todo;
-               }
-               n = todo;
-               if (n > IPACKS * 2)
-                       n = IPACKS * 2;
-               if (copy_from_user(av7110->kbuf[type], buf, n))
-                       return -EFAULT;
-               av7110_ipack_instant_repack(av7110->kbuf[type], n,
-                                           &av7110->ipack[type]);
-               todo -= n;
-               buf += n;
-       }
-       return count - todo;
-}
-
-static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
-                       unsigned long count, int nonblock, int type)
-{
-       unsigned long todo = count, n;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (!av7110->kbuf[type])
-               return -ENOBUFS;
-
-       if (nonblock && !FREE_COND)
-               return -EWOULDBLOCK;
-
-       while (todo > 0) {
-               if (!FREE_COND) {
-                       if (nonblock)
-                               return count - todo;
-                       if (wait_event_interruptible(av7110->avout.queue,
-                                                    FREE_COND))
-                               return count - todo;
-               }
-               n = todo;
-               if (n > IPACKS * 2)
-                       n = IPACKS * 2;
-               av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]);
-               todo -= n;
-               buf += n;
-       }
-       return count - todo;
-}
-
-static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf,
-                        unsigned long count, int nonblock, int type)
-{
-       unsigned long todo = count, n;
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (!av7110->kbuf[type])
-               return -ENOBUFS;
-       if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024)
-               return -EWOULDBLOCK;
-
-       while (todo > 0) {
-               if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) {
-                       if (nonblock)
-                               return count - todo;
-                       if (wait_event_interruptible(av7110->aout.queue,
-                                       (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
-                               return count-todo;
-               }
-               n = todo;
-               if (n > IPACKS * 2)
-                       n = IPACKS * 2;
-               if (copy_from_user(av7110->kbuf[type], buf, n))
-                       return -EFAULT;
-               av7110_ipack_instant_repack(av7110->kbuf[type], n,
-                                           &av7110->ipack[type]);
-               todo -= n;
-               buf += n;
-       }
-       return count - todo;
-}
-
-void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed)
-{
-       memset(p->pes, 0, TS_SIZE);
-       p->counter = 0;
-       p->pos = 0;
-       p->frags = 0;
-       if (feed)
-               p->feed = feed;
-}
-
-static void clear_p2t(struct av7110_p2t *p)
-{
-       memset(p->pes, 0, TS_SIZE);
-//     p->counter = 0;
-       p->pos = 0;
-       p->frags = 0;
-}
-
-
-static int find_pes_header(u8 const *buf, long int length, int *frags)
-{
-       int c = 0;
-       int found = 0;
-
-       *frags = 0;
-
-       while (c < length - 3 && !found) {
-               if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
-                   buf[c + 2] == 0x01) {
-                       switch ( buf[c + 3] ) {
-                       case PROG_STREAM_MAP:
-                       case PRIVATE_STREAM2:
-                       case PROG_STREAM_DIR:
-                       case ECM_STREAM     :
-                       case EMM_STREAM     :
-                       case PADDING_STREAM :
-                       case DSM_CC_STREAM  :
-                       case ISO13522_STREAM:
-                       case PRIVATE_STREAM1:
-                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-                               found = 1;
-                               break;
-
-                       default:
-                               c++;
-                               break;
-                       }
-               } else
-                       c++;
-       }
-       if (c == length - 3 && !found) {
-               if (buf[length - 1] == 0x00)
-                       *frags = 1;
-               if (buf[length - 2] == 0x00 &&
-                   buf[length - 1] == 0x00)
-                       *frags = 2;
-               if (buf[length - 3] == 0x00 &&
-                   buf[length - 2] == 0x00 &&
-                   buf[length - 1] == 0x01)
-                       *frags = 3;
-               return -1;
-       }
-
-       return c;
-}
-
-void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
-{
-       int c, c2, l, add;
-       int check, rest;
-
-       c = 0;
-       c2 = 0;
-       if (p->frags){
-               check = 0;
-               switch(p->frags) {
-               case 1:
-                       if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
-                               check = 1;
-                               c += 2;
-                       }
-                       break;
-               case 2:
-                       if (buf[c] == 0x01) {
-                               check = 1;
-                               c++;
-                       }
-                       break;
-               case 3:
-                       check = 1;
-               }
-               if (check) {
-                       switch (buf[c]) {
-                       case PROG_STREAM_MAP:
-                       case PRIVATE_STREAM2:
-                       case PROG_STREAM_DIR:
-                       case ECM_STREAM     :
-                       case EMM_STREAM     :
-                       case PADDING_STREAM :
-                       case DSM_CC_STREAM  :
-                       case ISO13522_STREAM:
-                       case PRIVATE_STREAM1:
-                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-                               p->pes[0] = 0x00;
-                               p->pes[1] = 0x00;
-                               p->pes[2] = 0x01;
-                               p->pes[3] = buf[c];
-                               p->pos = 4;
-                               memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos);
-                               c += (TS_SIZE - 4) - p->pos;
-                               p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed);
-                               clear_p2t(p);
-                               break;
-
-                       default:
-                               c = 0;
-                               break;
-                       }
-               }
-               p->frags = 0;
-       }
-
-       if (p->pos) {
-               c2 = find_pes_header(buf + c, length - c, &p->frags);
-               if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
-                       l = c2+c;
-               else
-                       l = (TS_SIZE - 4) - p->pos;
-               memcpy(p->pes + p->pos, buf, l);
-               c += l;
-               p->pos += l;
-               p_to_t(p->pes, p->pos, pid, &p->counter, p->feed);
-               clear_p2t(p);
-       }
-
-       add = 0;
-       while (c < length) {
-               c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
-               if (c2 >= 0) {
-                       c2 += c + add;
-                       if (c2 > c){
-                               p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
-                               c = c2;
-                               clear_p2t(p);
-                               add = 0;
-                       } else
-                               add = 1;
-               } else {
-                       l = length - c;
-                       rest = l % (TS_SIZE - 4);
-                       l -= rest;
-                       p_to_t(buf + c, l, pid, &p->counter, p->feed);
-                       memcpy(p->pes, buf + c + l, rest);
-                       p->pos = rest;
-                       c = length;
-               }
-       }
-}
-
-
-static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
-{
-       int i;
-       int c = 0;
-       int fill;
-       u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 };
-
-       fill = (TS_SIZE - 4) - length;
-       if (pes_start)
-               tshead[1] = 0x40;
-       if (fill)
-               tshead[3] = 0x30;
-       tshead[1] |= (u8)((pid & 0x1F00) >> 8);
-       tshead[2] |= (u8)(pid & 0x00FF);
-       tshead[3] |= ((*counter)++ & 0x0F);
-       memcpy(buf, tshead, 4);
-       c += 4;
-
-       if (fill) {
-               buf[4] = fill - 1;
-               c++;
-               if (fill > 1) {
-                       buf[5] = 0x00;
-                       c++;
-               }
-               for (i = 6; i < fill + 4; i++) {
-                       buf[i] = 0xFF;
-                       c++;
-               }
-       }
-
-       return c;
-}
-
-
-static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
-                  struct dvb_demux_feed *feed)
-{
-       int l, pes_start;
-       u8 obuf[TS_SIZE];
-       long c = 0;
-
-       pes_start = 0;
-       if (length > 3 &&
-            buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
-               switch (buf[3]) {
-                       case PROG_STREAM_MAP:
-                       case PRIVATE_STREAM2:
-                       case PROG_STREAM_DIR:
-                       case ECM_STREAM     :
-                       case EMM_STREAM     :
-                       case PADDING_STREAM :
-                       case DSM_CC_STREAM  :
-                       case ISO13522_STREAM:
-                       case PRIVATE_STREAM1:
-                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-                               pes_start = 1;
-                               break;
-
-                       default:
-                               break;
-               }
-
-       while (c < length) {
-               memset(obuf, 0, TS_SIZE);
-               if (length - c >= (TS_SIZE - 4)){
-                       l = write_ts_header2(pid, counter, pes_start,
-                                            obuf, (TS_SIZE - 4));
-                       memcpy(obuf + l, buf + c, TS_SIZE - l);
-                       c += TS_SIZE - l;
-               } else {
-                       l = write_ts_header2(pid, counter, pes_start,
-                                            obuf, length - c);
-                       memcpy(obuf + l, buf + c, TS_SIZE - l);
-                       c = length;
-               }
-               feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
-               pes_start = 0;
-       }
-}
-
-
-static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
-{
-       struct ipack *ipack = &av7110->ipack[type];
-
-       if (buf[1] & TRANS_ERROR) {
-               av7110_ipack_reset(ipack);
-               return -1;
-       }
-
-       if (!(buf[3] & PAYLOAD))
-               return -1;
-
-       if (buf[1] & PAY_START)
-               av7110_ipack_flush(ipack);
-
-       if (buf[3] & ADAPT_FIELD) {
-               len -= buf[4] + 1;
-               buf += buf[4] + 1;
-               if (!len)
-                       return 0;
-       }
-
-       av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
-       return 0;
-}
-
-
-int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct av7110 *av7110 = (struct av7110 *) demux->priv;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
-               return 0;
-
-       switch (feed->pes_type) {
-       case 0:
-               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
-                       return -EINVAL;
-               break;
-       case 1:
-               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
-                       return -EINVAL;
-               break;
-       default:
-               return -1;
-       }
-
-       return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
-}
-
-
-
-/******************************************************************************
- * Video MPEG decoder events
- ******************************************************************************/
-void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
-{
-       struct dvb_video_events *events = &av7110->video_events;
-       int wp;
-
-       spin_lock_bh(&events->lock);
-
-       wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
-       if (wp == events->eventr) {
-               events->overflow = 1;
-               events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
-       }
-
-       //FIXME: timestamp?
-       memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
-       events->eventw = wp;
-
-       spin_unlock_bh(&events->lock);
-
-       wake_up_interruptible(&events->wait_queue);
-}
-
-
-static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
-{
-       struct dvb_video_events *events = &av7110->video_events;
-
-       if (events->overflow) {
-               events->overflow = 0;
-               return -EOVERFLOW;
-       }
-       if (events->eventw == events->eventr) {
-               int ret;
-
-               if (flags & O_NONBLOCK)
-                       return -EWOULDBLOCK;
-
-               ret = wait_event_interruptible(events->wait_queue,
-                                              events->eventw != events->eventr);
-               if (ret < 0)
-                       return ret;
-       }
-
-       spin_lock_bh(&events->lock);
-
-       memcpy(event, &events->events[events->eventr],
-              sizeof(struct video_event));
-       events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
-
-       spin_unlock_bh(&events->lock);
-
-       return 0;
-}
-
-
-/******************************************************************************
- * DVB device file operations
- ******************************************************************************/
-
-static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned int mask = 0;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY)
-               poll_wait(file, &av7110->avout.queue, wait);
-
-       poll_wait(file, &av7110->video_events.wait_queue, wait);
-
-       if (av7110->video_events.eventw != av7110->video_events.eventr)
-               mask = POLLPRI;
-
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-               if (av7110->playing) {
-                       if (FREE_COND)
-                               mask |= (POLLOUT | POLLWRNORM);
-                       } else /* if not playing: may play if asked for */
-                               mask |= (POLLOUT | POLLWRNORM);
-       }
-
-       return mask;
-}
-
-static ssize_t dvb_video_write(struct file *file, const char __user *buf,
-                              size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned char c;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-               return -EPERM;
-
-       if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
-               return -EPERM;
-
-       if (get_user(c, buf))
-               return -EFAULT;
-       if (c == 0x47 && count % TS_SIZE == 0)
-               return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
-       else
-               return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
-}
-
-static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned int mask = 0;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       poll_wait(file, &av7110->aout.queue, wait);
-
-       if (av7110->playing) {
-               if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
-                       mask |= (POLLOUT | POLLWRNORM);
-       } else /* if not playing: may play if asked for */
-               mask = (POLLOUT | POLLWRNORM);
-
-       return mask;
-}
-
-static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
-                              size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned char c;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
-               printk(KERN_ERR "not audio source memory\n");
-               return -EPERM;
-       }
-
-       if (get_user(c, buf))
-               return -EFAULT;
-       if (c == 0x47 && count % TS_SIZE == 0)
-               return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
-       else
-               return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
-}
-
-static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
-
-#define MIN_IFRAME 400000
-
-static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
-{
-       unsigned i, n;
-       int progressive = 0;
-       int match = 0;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (!(av7110->playing & RP_VIDEO)) {
-               if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
-                       return -EBUSY;
-       }
-
-       /* search in buf for instances of 00 00 01 b5 1? */
-       for (i = 0; i < len; i++) {
-               unsigned char c;
-               if (get_user(c, buf + i))
-                       return -EFAULT;
-               if (match == 5) {
-                       progressive = c & 0x08;
-                       match = 0;
-               }
-               if (c == 0x00) {
-                       match = (match == 1 || match == 2) ? 2 : 1;
-                       continue;
-               }
-               switch (match++) {
-               case 2: if (c == 0x01)
-                               continue;
-                       break;
-               case 3: if (c == 0xb5)
-                               continue;
-                       break;
-               case 4: if ((c & 0xf0) == 0x10)
-                               continue;
-                       break;
-               }
-               match = 0;
-       }
-
-       /* setting n always > 1, fixes problems when playing stillframes
-          consisting of I- and P-Frames */
-       n = MIN_IFRAME / len + 1;
-
-       /* FIXME: nonblock? */
-       dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1);
-
-       for (i = 0; i < n; i++)
-               dvb_play(av7110, buf, len, 0, 1);
-
-       av7110_ipack_flush(&av7110->ipack[1]);
-
-       if (progressive)
-               return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
-       else
-               return 0;
-}
-
-
-static int dvb_video_ioctl(struct file *file,
-                          unsigned int cmd, void *parg)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned long arg = (unsigned long) parg;
-       int ret = 0;
-
-       dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
-
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
-               if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
-                    cmd != VIDEO_GET_SIZE ) {
-                       return -EPERM;
-               }
-       }
-
-       switch (cmd) {
-       case VIDEO_STOP:
-               av7110->videostate.play_state = VIDEO_STOPPED;
-               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
-                       ret = av7110_av_stop(av7110, RP_VIDEO);
-               else
-                       ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
-                              av7110->videostate.video_blank ? 0 : 1);
-               if (!ret)
-                       av7110->trickmode = TRICK_NONE;
-               break;
-
-       case VIDEO_PLAY:
-               av7110->trickmode = TRICK_NONE;
-               if (av7110->videostate.play_state == VIDEO_FREEZED) {
-                       av7110->videostate.play_state = VIDEO_PLAYING;
-                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
-                       if (ret)
-                               break;
-               }
-               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
-                       if (av7110->playing == RP_AV) {
-                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
-                               if (ret)
-                                       break;
-                               av7110->playing &= ~RP_VIDEO;
-                       }
-                       ret = av7110_av_start_play(av7110, RP_VIDEO);
-               }
-               if (!ret)
-                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
-               if (!ret)
-                       av7110->videostate.play_state = VIDEO_PLAYING;
-               break;
-
-       case VIDEO_FREEZE:
-               av7110->videostate.play_state = VIDEO_FREEZED;
-               if (av7110->playing & RP_VIDEO)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
-               else
-                       ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
-               if (!ret)
-                       av7110->trickmode = TRICK_FREEZE;
-               break;
-
-       case VIDEO_CONTINUE:
-               if (av7110->playing & RP_VIDEO)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
-               if (!ret)
-                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
-               if (!ret) {
-                       av7110->videostate.play_state = VIDEO_PLAYING;
-                       av7110->trickmode = TRICK_NONE;
-               }
-               break;
-
-       case VIDEO_SELECT_SOURCE:
-               av7110->videostate.stream_source = (video_stream_source_t) arg;
-               break;
-
-       case VIDEO_SET_BLANK:
-               av7110->videostate.video_blank = (int) arg;
-               break;
-
-       case VIDEO_GET_STATUS:
-               memcpy(parg, &av7110->videostate, sizeof(struct video_status));
-               break;
-
-       case VIDEO_GET_EVENT:
-               ret = dvb_video_get_event(av7110, parg, file->f_flags);
-               break;
-
-       case VIDEO_GET_SIZE:
-               memcpy(parg, &av7110->video_size, sizeof(video_size_t));
-               break;
-
-       case VIDEO_SET_DISPLAY_FORMAT:
-       {
-               video_displayformat_t format = (video_displayformat_t) arg;
-               switch (format) {
-               case VIDEO_PAN_SCAN:
-                       av7110->display_panscan = VID_PAN_SCAN_PREF;
-                       break;
-               case VIDEO_LETTER_BOX:
-                       av7110->display_panscan = VID_VC_AND_PS_PREF;
-                       break;
-               case VIDEO_CENTER_CUT_OUT:
-                       av7110->display_panscan = VID_CENTRE_CUT_PREF;
-                       break;
-               default:
-                       ret = -EINVAL;
-               }
-               if (ret < 0)
-                       break;
-               av7110->videostate.display_format = format;
-               ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
-                                   1, av7110->display_panscan);
-               break;
-       }
-
-       case VIDEO_SET_FORMAT:
-               if (arg > 1) {
-                       ret = -EINVAL;
-                       break;
-               }
-               av7110->display_ar = arg;
-               ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
-                                   1, (u16) arg);
-               break;
-
-       case VIDEO_STILLPICTURE:
-       {
-               struct video_still_picture *pic =
-                       (struct video_still_picture *) parg;
-               av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
-               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
-               ret = play_iframe(av7110, pic->iFrame, pic->size,
-                                 file->f_flags & O_NONBLOCK);
-               break;
-       }
-
-       case VIDEO_FAST_FORWARD:
-               //note: arg is ignored by firmware
-               if (av7110->playing & RP_VIDEO)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-                                           __Scan_I, 2, AV_PES, 0);
-               else
-                       ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg);
-               if (!ret) {
-                       av7110->trickmode = TRICK_FAST;
-                       av7110->videostate.play_state = VIDEO_PLAYING;
-               }
-               break;
-
-       case VIDEO_SLOWMOTION:
-               if (av7110->playing&RP_VIDEO) {
-                       if (av7110->trickmode != TRICK_SLOW)
-                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
-                       if (!ret)
-                               ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
-               } else {
-                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
-                       if (!ret)
-                               ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0);
-                       if (!ret)
-                               ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
-               }
-               if (!ret) {
-                       av7110->trickmode = TRICK_SLOW;
-                       av7110->videostate.play_state = VIDEO_PLAYING;
-               }
-               break;
-
-       case VIDEO_GET_CAPABILITIES:
-               *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |
-                       VIDEO_CAP_SYS | VIDEO_CAP_PROG;
-               break;
-
-       case VIDEO_CLEAR_BUFFER:
-               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
-               av7110_ipack_reset(&av7110->ipack[1]);
-               if (av7110->playing == RP_AV) {
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-                                           __Play, 2, AV_PES, 0);
-                       if (ret)
-                               break;
-                       if (av7110->trickmode == TRICK_FAST)
-                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-                                                   __Scan_I, 2, AV_PES, 0);
-                       if (av7110->trickmode == TRICK_SLOW) {
-                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-                                                   __Slow, 2, 0, 0);
-                               if (!ret)
-                                       ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
-                       }
-                       if (av7110->trickmode == TRICK_FREEZE)
-                               ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1);
-               }
-               break;
-
-       case VIDEO_SET_STREAMTYPE:
-               break;
-
-       default:
-               ret = -ENOIOCTLCMD;
-               break;
-       }
-
-       return ret;
-}
-
-static int dvb_audio_ioctl(struct file *file,
-                          unsigned int cmd, void *parg)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned long arg = (unsigned long) parg;
-       int ret = 0;
-
-       dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
-
-       if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
-           (cmd != AUDIO_GET_STATUS))
-               return -EPERM;
-
-       switch (cmd) {
-       case AUDIO_STOP:
-               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
-                       ret = av7110_av_stop(av7110, RP_AUDIO);
-               else
-                       ret = audcom(av7110, AUDIO_CMD_MUTE);
-               if (!ret)
-                       av7110->audiostate.play_state = AUDIO_STOPPED;
-               break;
-
-       case AUDIO_PLAY:
-               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
-                       ret = av7110_av_start_play(av7110, RP_AUDIO);
-               if (!ret)
-                       ret = audcom(av7110, AUDIO_CMD_UNMUTE);
-               if (!ret)
-                       av7110->audiostate.play_state = AUDIO_PLAYING;
-               break;
-
-       case AUDIO_PAUSE:
-               ret = audcom(av7110, AUDIO_CMD_MUTE);
-               if (!ret)
-                       av7110->audiostate.play_state = AUDIO_PAUSED;
-               break;
-
-       case AUDIO_CONTINUE:
-               if (av7110->audiostate.play_state == AUDIO_PAUSED) {
-                       av7110->audiostate.play_state = AUDIO_PLAYING;
-                       ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
-               }
-               break;
-
-       case AUDIO_SELECT_SOURCE:
-               av7110->audiostate.stream_source = (audio_stream_source_t) arg;
-               break;
-
-       case AUDIO_SET_MUTE:
-       {
-               ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
-               if (!ret)
-                       av7110->audiostate.mute_state = (int) arg;
-               break;
-       }
-
-       case AUDIO_SET_AV_SYNC:
-               av7110->audiostate.AV_sync_state = (int) arg;
-               ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
-               break;
-
-       case AUDIO_SET_BYPASS_MODE:
-               if (FW_VERSION(av7110->arm_app) < 0x2621)
-                       ret = -EINVAL;
-               av7110->audiostate.bypass_mode = (int)arg;
-               break;
-
-       case AUDIO_CHANNEL_SELECT:
-               av7110->audiostate.channel_select = (audio_channel_select_t) arg;
-               switch(av7110->audiostate.channel_select) {
-               case AUDIO_STEREO:
-                       ret = audcom(av7110, AUDIO_CMD_STEREO);
-                       if (!ret) {
-                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-                                       i2c_writereg(av7110, 0x20, 0x02, 0x49);
-                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
-                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220);
-                       }
-                       break;
-               case AUDIO_MONO_LEFT:
-                       ret = audcom(av7110, AUDIO_CMD_MONO_L);
-                       if (!ret) {
-                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-                                       i2c_writereg(av7110, 0x20, 0x02, 0x4a);
-                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
-                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200);
-                       }
-                       break;
-               case AUDIO_MONO_RIGHT:
-                       ret = audcom(av7110, AUDIO_CMD_MONO_R);
-                       if (!ret) {
-                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-                                       i2c_writereg(av7110, 0x20, 0x02, 0x45);
-                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
-                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210);
-                       }
-                       break;
-               default:
-                       ret = -EINVAL;
-                       break;
-               }
-               break;
-
-       case AUDIO_GET_STATUS:
-               memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
-               break;
-
-       case AUDIO_GET_CAPABILITIES:
-               if (FW_VERSION(av7110->arm_app) < 0x2621)
-                       *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
-               else
-                       *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 |
-                                               AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
-               break;
-
-       case AUDIO_CLEAR_BUFFER:
-               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
-               av7110_ipack_reset(&av7110->ipack[0]);
-               if (av7110->playing == RP_AV)
-                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-                                           __Play, 2, AV_PES, 0);
-               break;
-
-       case AUDIO_SET_ID:
-               break;
-
-       case AUDIO_SET_MIXER:
-       {
-               struct audio_mixer *amix = (struct audio_mixer *)parg;
-               ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
-               break;
-       }
-
-       case AUDIO_SET_STREAMTYPE:
-               break;
-
-       default:
-               ret = -ENOIOCTLCMD;
-       }
-
-       return ret;
-}
-
-
-static int dvb_video_open(struct inode *inode, struct file *file)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       int err;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if ((err = dvb_generic_open(inode, file)) < 0)
-               return err;
-
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
-               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
-               av7110->video_blank = 1;
-               av7110->audiostate.AV_sync_state = 1;
-               av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
-
-               /*  empty event queue */
-               av7110->video_events.eventr = av7110->video_events.eventw = 0;
-       }
-
-       return 0;
-}
-
-static int dvb_video_release(struct inode *inode, struct file *file)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-               av7110_av_stop(av7110, RP_VIDEO);
-       }
-
-       return dvb_generic_release(inode, file);
-}
-
-static int dvb_audio_open(struct inode *inode, struct file *file)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       int err = dvb_generic_open(inode, file);
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       if (err < 0)
-               return err;
-       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
-       av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
-       return 0;
-}
-
-static int dvb_audio_release(struct inode *inode, struct file *file)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-
-       dprintk(2, "av7110:%p, \n", av7110);
-
-       av7110_av_stop(av7110, RP_AUDIO);
-       return dvb_generic_release(inode, file);
-}
-
-
-
-/******************************************************************************
- * driver registration
- ******************************************************************************/
-
-static const struct file_operations dvb_video_fops = {
-       .owner          = THIS_MODULE,
-       .write          = dvb_video_write,
-       .unlocked_ioctl = dvb_generic_ioctl,
-       .open           = dvb_video_open,
-       .release        = dvb_video_release,
-       .poll           = dvb_video_poll,
-       .llseek         = noop_llseek,
-};
-
-static struct dvb_device dvbdev_video = {
-       .priv           = NULL,
-       .users          = 6,
-       .readers        = 5,    /* arbitrary */
-       .writers        = 1,
-       .fops           = &dvb_video_fops,
-       .kernel_ioctl   = dvb_video_ioctl,
-};
-
-static const struct file_operations dvb_audio_fops = {
-       .owner          = THIS_MODULE,
-       .write          = dvb_audio_write,
-       .unlocked_ioctl = dvb_generic_ioctl,
-       .open           = dvb_audio_open,
-       .release        = dvb_audio_release,
-       .poll           = dvb_audio_poll,
-       .llseek         = noop_llseek,
-};
-
-static struct dvb_device dvbdev_audio = {
-       .priv           = NULL,
-       .users          = 1,
-       .writers        = 1,
-       .fops           = &dvb_audio_fops,
-       .kernel_ioctl   = dvb_audio_ioctl,
-};
-
-
-int av7110_av_register(struct av7110 *av7110)
-{
-       av7110->audiostate.AV_sync_state = 0;
-       av7110->audiostate.mute_state = 0;
-       av7110->audiostate.play_state = AUDIO_STOPPED;
-       av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
-       av7110->audiostate.channel_select = AUDIO_STEREO;
-       av7110->audiostate.bypass_mode = 0;
-
-       av7110->videostate.video_blank = 0;
-       av7110->videostate.play_state = VIDEO_STOPPED;
-       av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
-       av7110->videostate.video_format = VIDEO_FORMAT_4_3;
-       av7110->videostate.display_format = VIDEO_LETTER_BOX;
-       av7110->display_ar = VIDEO_FORMAT_4_3;
-       av7110->display_panscan = VID_VC_AND_PS_PREF;
-
-       init_waitqueue_head(&av7110->video_events.wait_queue);
-       spin_lock_init(&av7110->video_events.lock);
-       av7110->video_events.eventw = av7110->video_events.eventr = 0;
-       av7110->video_events.overflow = 0;
-       memset(&av7110->video_size, 0, sizeof (video_size_t));
-
-       dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
-                           &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
-
-       dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
-                           &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
-
-       return 0;
-}
-
-void av7110_av_unregister(struct av7110 *av7110)
-{
-       dvb_unregister_device(av7110->audio_dev);
-       dvb_unregister_device(av7110->video_dev);
-}
-
-int av7110_av_init(struct av7110 *av7110)
-{
-       void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
-       int i, ret;
-
-       for (i = 0; i < 2; i++) {
-               struct ipack *ipack = av7110->ipack + i;
-
-               ret = av7110_ipack_init(ipack, IPACKS, play[i]);
-               if (ret < 0) {
-                       if (i)
-                               av7110_ipack_free(--ipack);
-                       goto out;
-               }
-               ipack->data = av7110;
-       }
-
-       dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
-       dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);
-
-       av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);
-       av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;
-out:
-       return ret;
-}
-
-void av7110_av_exit(struct av7110 *av7110)
-{
-       av7110_ipack_free(&av7110->ipack[0]);
-       av7110_ipack_free(&av7110->ipack[1]);
-}
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
deleted file mode 100644 (file)
index 5f02ef8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _AV7110_AV_H_
-#define _AV7110_AV_H_
-
-struct av7110;
-
-extern int av7110_set_vidmode(struct av7110 *av7110,
-                             enum av7110_video_mode mode);
-
-extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
-extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
-extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
-
-extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
-extern int av7110_av_stop(struct av7110 *av7110, int av);
-extern int av7110_av_start_record(struct av7110 *av7110, int av,
-                         struct dvb_demux_feed *dvbdmxfeed);
-extern int av7110_av_start_play(struct av7110 *av7110, int av);
-
-extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
-
-extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
-extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
-
-extern int av7110_av_register(struct av7110 *av7110);
-extern void av7110_av_unregister(struct av7110 *av7110);
-extern int av7110_av_init(struct av7110 *av7110);
-extern void av7110_av_exit(struct av7110 *av7110);
-
-
-#endif /* _AV7110_AV_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
deleted file mode 100644 (file)
index 9fc1dd0..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * av7110_ca.c: CA and CI stuff
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * originally based on code by:
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/timer.h>
-#include <linux/poll.h>
-#include <linux/gfp.h>
-
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "av7110_ca.h"
-
-
-void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
-{
-       dprintk(8, "av7110:%p\n",av7110);
-
-       if (len < 3)
-               return;
-       switch (data[0]) {
-       case CI_MSG_CI_INFO:
-               if (data[2] != 1 && data[2] != 2)
-                       break;
-               switch (data[1]) {
-               case 0:
-                       av7110->ci_slot[data[2] - 1].flags = 0;
-                       break;
-               case 1:
-                       av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT;
-                       break;
-               case 2:
-                       av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY;
-                       break;
-               }
-               break;
-       case CI_SWITCH_PRG_REPLY:
-               //av7110->ci_stat=data[1];
-               break;
-       default:
-               break;
-       }
-}
-
-
-void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
-{
-       if (dvb_ringbuffer_free(cibuf) < len + 2)
-               return;
-
-       DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8);
-       DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff);
-       dvb_ringbuffer_write(cibuf, data, len);
-       wake_up_interruptible(&cibuf->queue);
-}
-
-
-/******************************************************************************
- * CI link layer file ops
- ******************************************************************************/
-
-static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
-{
-       struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p;
-       void *data;
-
-       for (p = tab; *p; p++) {
-               data = vmalloc(size);
-               if (!data) {
-                       while (p-- != tab) {
-                               vfree(p[0]->data);
-                               p[0]->data = NULL;
-                       }
-                       return -ENOMEM;
-               }
-               dvb_ringbuffer_init(*p, data, size);
-       }
-       return 0;
-}
-
-static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
-{
-       dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
-       dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
-}
-
-static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
-{
-       vfree(cirbuf->data);
-       cirbuf->data = NULL;
-       vfree(ciwbuf->data);
-       ciwbuf->data = NULL;
-}
-
-static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
-                      int slots, ca_slot_info_t *slot)
-{
-       int i;
-       int len = 0;
-       u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 };
-
-       for (i = 0; i < 2; i++) {
-               if (slots & (1 << i))
-                       len += 8;
-       }
-
-       if (dvb_ringbuffer_free(cibuf) < len)
-               return -EBUSY;
-
-       for (i = 0; i < 2; i++) {
-               if (slots & (1 << i)) {
-                       msg[2] = i;
-                       dvb_ringbuffer_write(cibuf, msg, 8);
-                       slot[i].flags = 0;
-               }
-       }
-
-       return 0;
-}
-
-static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file,
-                          const char __user *buf, size_t count, loff_t *ppos)
-{
-       int free;
-       int non_blocking = file->f_flags & O_NONBLOCK;
-       u8 *page = (u8 *)__get_free_page(GFP_USER);
-       int res;
-
-       if (!page)
-               return -ENOMEM;
-
-       res = -EINVAL;
-       if (count > 2048)
-               goto out;
-
-       res = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out;
-
-       free = dvb_ringbuffer_free(cibuf);
-       if (count + 2 > free) {
-               res = -EWOULDBLOCK;
-               if (non_blocking)
-                       goto out;
-               res = -ERESTARTSYS;
-               if (wait_event_interruptible(cibuf->queue,
-                                            (dvb_ringbuffer_free(cibuf) >= count + 2)))
-                       goto out;
-       }
-
-       DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8);
-       DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff);
-
-       res = dvb_ringbuffer_write(cibuf, page, count);
-out:
-       free_page((unsigned long)page);
-       return res;
-}
-
-static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
-                         char __user *buf, size_t count, loff_t *ppos)
-{
-       int avail;
-       int non_blocking = file->f_flags & O_NONBLOCK;
-       ssize_t len;
-
-       if (!cibuf->data || !count)
-               return 0;
-       if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
-               return -EWOULDBLOCK;
-       if (wait_event_interruptible(cibuf->queue,
-                                    !dvb_ringbuffer_empty(cibuf)))
-               return -ERESTARTSYS;
-       avail = dvb_ringbuffer_avail(cibuf);
-       if (avail < 4)
-               return 0;
-       len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
-       len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
-       if (avail < len + 2 || count < len)
-               return -EINVAL;
-       DVB_RINGBUFFER_SKIP(cibuf, 2);
-
-       return dvb_ringbuffer_read_user(cibuf, buf, len);
-}
-
-static int dvb_ca_open(struct inode *inode, struct file *file)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       int err = dvb_generic_open(inode, file);
-
-       dprintk(8, "av7110:%p\n",av7110);
-
-       if (err < 0)
-               return err;
-       ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
-       return 0;
-}
-
-static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
-       struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
-       unsigned int mask = 0;
-
-       dprintk(8, "av7110:%p\n",av7110);
-
-       poll_wait(file, &rbuf->queue, wait);
-       poll_wait(file, &wbuf->queue, wait);
-
-       if (!dvb_ringbuffer_empty(rbuf))
-               mask |= (POLLIN | POLLRDNORM);
-
-       if (dvb_ringbuffer_free(wbuf) > 1024)
-               mask |= (POLLOUT | POLLWRNORM);
-
-       return mask;
-}
-
-static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-       unsigned long arg = (unsigned long) parg;
-
-       dprintk(8, "av7110:%p\n",av7110);
-
-       switch (cmd) {
-       case CA_RESET:
-               return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]);
-               break;
-       case CA_GET_CAP:
-       {
-               ca_caps_t cap;
-
-               cap.slot_num = 2;
-               cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ?
-                                CA_CI_LINK : CA_CI) | CA_DESCR;
-               cap.descr_num = 16;
-               cap.descr_type = CA_ECD;
-               memcpy(parg, &cap, sizeof(cap));
-               break;
-       }
-
-       case CA_GET_SLOT_INFO:
-       {
-               ca_slot_info_t *info=(ca_slot_info_t *)parg;
-
-               if (info->num < 0 || info->num > 1)
-                       return -EINVAL;
-               av7110->ci_slot[info->num].num = info->num;
-               av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
-                                                       CA_CI_LINK : CA_CI;
-               memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
-               break;
-       }
-
-       case CA_GET_MSG:
-               break;
-
-       case CA_SEND_MSG:
-               break;
-
-       case CA_GET_DESCR_INFO:
-       {
-               ca_descr_info_t info;
-
-               info.num = 16;
-               info.type = CA_ECD;
-               memcpy(parg, &info, sizeof (info));
-               break;
-       }
-
-       case CA_SET_DESCR:
-       {
-               ca_descr_t *descr = (ca_descr_t*) parg;
-
-               if (descr->index >= 16)
-                       return -EINVAL;
-               if (descr->parity > 1)
-                       return -EINVAL;
-               av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
-                             (descr->index<<8)|descr->parity,
-                             (descr->cw[0]<<8)|descr->cw[1],
-                             (descr->cw[2]<<8)|descr->cw[3],
-                             (descr->cw[4]<<8)|descr->cw[5],
-                             (descr->cw[6]<<8)|descr->cw[7]);
-               break;
-       }
-
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
-                           size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-
-       dprintk(8, "av7110:%p\n",av7110);
-       return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
-}
-
-static ssize_t dvb_ca_read(struct file *file, char __user *buf,
-                          size_t count, loff_t *ppos)
-{
-       struct dvb_device *dvbdev = file->private_data;
-       struct av7110 *av7110 = dvbdev->priv;
-
-       dprintk(8, "av7110:%p\n",av7110);
-       return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
-}
-
-static const struct file_operations dvb_ca_fops = {
-       .owner          = THIS_MODULE,
-       .read           = dvb_ca_read,
-       .write          = dvb_ca_write,
-       .unlocked_ioctl = dvb_generic_ioctl,
-       .open           = dvb_ca_open,
-       .release        = dvb_generic_release,
-       .poll           = dvb_ca_poll,
-       .llseek         = default_llseek,
-};
-
-static struct dvb_device dvbdev_ca = {
-       .priv           = NULL,
-       .users          = 1,
-       .writers        = 1,
-       .fops           = &dvb_ca_fops,
-       .kernel_ioctl   = dvb_ca_ioctl,
-};
-
-
-int av7110_ca_register(struct av7110 *av7110)
-{
-       return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
-                                  &dvbdev_ca, av7110, DVB_DEVICE_CA);
-}
-
-void av7110_ca_unregister(struct av7110 *av7110)
-{
-       dvb_unregister_device(av7110->ca_dev);
-}
-
-int av7110_ca_init(struct av7110* av7110)
-{
-       return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
-}
-
-void av7110_ca_exit(struct av7110* av7110)
-{
-       ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
-}
diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/dvb/ttpci/av7110_ca.h
deleted file mode 100644 (file)
index 70ee855..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _AV7110_CA_H_
-#define _AV7110_CA_H_
-
-struct av7110;
-
-extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
-extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
-
-extern int av7110_ca_register(struct av7110 *av7110);
-extern void av7110_ca_unregister(struct av7110 *av7110);
-extern int av7110_ca_init(struct av7110* av7110);
-extern void av7110_ca_exit(struct av7110* av7110);
-
-#endif /* _AV7110_CA_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
deleted file mode 100644 (file)
index f1cbfe5..0000000
+++ /dev/null
@@ -1,1208 +0,0 @@
-/*
- * av7110_hw.c: av7110 low level hardware access and firmware interface
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * originally based on code by:
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-/* for debugging ARM communication: */
-//#define COM_DEBUG
-
-#include <stdarg.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-
-#include "av7110.h"
-#include "av7110_hw.h"
-
-#define _NOHANDSHAKE
-
-/****************************************************************************
- * DEBI functions
- ****************************************************************************/
-
-/* This DEBI code is based on the Stradis driver
-   by Nathan Laredo <laredo@gnu.org> */
-
-int av7110_debiwrite(struct av7110 *av7110, u32 config,
-                    int addr, u32 val, int count)
-{
-       struct saa7146_dev *dev = av7110->dev;
-
-       if (count <= 0 || count > 32764) {
-               printk("%s: invalid count %d\n", __func__, count);
-               return -1;
-       }
-       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
-               printk("%s: wait_for_debi_done failed\n", __func__);
-               return -1;
-       }
-       saa7146_write(dev, DEBI_CONFIG, config);
-       if (count <= 4)         /* immediate transfer */
-               saa7146_write(dev, DEBI_AD, val);
-       else                    /* block transfer */
-               saa7146_write(dev, DEBI_AD, av7110->debi_bus);
-       saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
-       saa7146_write(dev, MC2, (2 << 16) | 2);
-       return 0;
-}
-
-u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
-{
-       struct saa7146_dev *dev = av7110->dev;
-       u32 result = 0;
-
-       if (count > 32764 || count <= 0) {
-               printk("%s: invalid count %d\n", __func__, count);
-               return 0;
-       }
-       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
-               printk("%s: wait_for_debi_done #1 failed\n", __func__);
-               return 0;
-       }
-       saa7146_write(dev, DEBI_AD, av7110->debi_bus);
-       saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
-
-       saa7146_write(dev, DEBI_CONFIG, config);
-       saa7146_write(dev, MC2, (2 << 16) | 2);
-       if (count > 4)
-               return count;
-       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
-               printk("%s: wait_for_debi_done #2 failed\n", __func__);
-               return 0;
-       }
-
-       result = saa7146_read(dev, DEBI_AD);
-       result &= (0xffffffffUL >> ((4 - count) * 8));
-       return result;
-}
-
-
-
-/* av7110 ARM core boot stuff */
-#if 0
-void av7110_reset_arm(struct av7110 *av7110)
-{
-       saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
-
-       /* Disable DEBI and GPIO irq */
-       SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
-       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
-
-       saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
-       msleep(30);     /* the firmware needs some time to initialize */
-
-       ARM_ResetMailBox(av7110);
-
-       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
-       SAA7146_IER_ENABLE(av7110->dev, MASK_03);
-
-       av7110->arm_ready = 1;
-       dprintk(1, "reset ARM\n");
-}
-#endif  /*  0  */
-
-static int waitdebi(struct av7110 *av7110, int adr, int state)
-{
-       int k;
-
-       dprintk(4, "%p\n", av7110);
-
-       for (k = 0; k < 100; k++) {
-               if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
-                       return 0;
-               udelay(5);
-       }
-       return -ETIMEDOUT;
-}
-
-static int load_dram(struct av7110 *av7110, u32 *data, int len)
-{
-       int i;
-       int blocks, rest;
-       u32 base, bootblock = AV7110_BOOT_BLOCK;
-
-       dprintk(4, "%p\n", av7110);
-
-       blocks = len / AV7110_BOOT_MAX_SIZE;
-       rest = len % AV7110_BOOT_MAX_SIZE;
-       base = DRAM_START_CODE;
-
-       for (i = 0; i < blocks; i++) {
-               if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
-                       printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
-                       return -ETIMEDOUT;
-               }
-               dprintk(4, "writing DRAM block %d\n", i);
-               mwdebi(av7110, DEBISWAB, bootblock,
-                      ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE);
-               bootblock ^= 0x1400;
-               iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
-               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2);
-               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
-               base += AV7110_BOOT_MAX_SIZE;
-       }
-
-       if (rest > 0) {
-               if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
-                       printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
-                       return -ETIMEDOUT;
-               }
-               if (rest > 4)
-                       mwdebi(av7110, DEBISWAB, bootblock,
-                              ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest);
-               else
-                       mwdebi(av7110, DEBISWAB, bootblock,
-                              ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4);
-
-               iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
-               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2);
-               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
-       }
-       if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
-               printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
-               return -ETIMEDOUT;
-       }
-       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2);
-       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
-       if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) {
-               printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
-               return -ETIMEDOUT;
-       }
-       return 0;
-}
-
-
-/* we cannot write av7110 DRAM directly, so load a bootloader into
- * the DPRAM which implements a simple boot protocol */
-int av7110_bootarm(struct av7110 *av7110)
-{
-       const struct firmware *fw;
-       const char *fw_name = "av7110/bootcode.bin";
-       struct saa7146_dev *dev = av7110->dev;
-       u32 ret;
-       int i;
-
-       dprintk(4, "%p\n", av7110);
-
-       av7110->arm_ready = 0;
-
-       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
-
-       /* Disable DEBI and GPIO irq */
-       SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
-       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
-
-       /* enable DEBI */
-       saa7146_write(av7110->dev, MC1, 0x08800880);
-       saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
-       saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
-       /* test DEBI */
-       iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
-       /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
-       iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
-
-       if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
-               printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
-                      "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
-                      ret, 0x10325476);
-               return -1;
-       }
-       for (i = 0; i < 8192; i += 4)
-               iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
-       dprintk(2, "debi test OK\n");
-
-       /* boot */
-       dprintk(1, "load boot code\n");
-       saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
-       //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
-       //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
-
-       ret = request_firmware(&fw, fw_name, &dev->pci->dev);
-       if (ret) {
-               printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
-                       fw_name);
-               return ret;
-       }
-
-       mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
-       release_firmware(fw);
-       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
-
-       if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
-               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
-                      "saa7146_wait_for_debi_done() timed out\n");
-               return -ETIMEDOUT;
-       }
-       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
-       mdelay(1);
-
-       dprintk(1, "load dram code\n");
-       if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
-               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
-                      "load_dram() failed\n");
-               return -1;
-       }
-
-       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
-       mdelay(1);
-
-       dprintk(1, "load dpram code\n");
-       mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
-
-       if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
-               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
-                      "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
-               return -ETIMEDOUT;
-       }
-       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
-       msleep(30);     /* the firmware needs some time to initialize */
-
-       //ARM_ClearIrq(av7110);
-       ARM_ResetMailBox(av7110);
-       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
-       SAA7146_IER_ENABLE(av7110->dev, MASK_03);
-
-       av7110->arm_errors = 0;
-       av7110->arm_ready = 1;
-       return 0;
-}
-MODULE_FIRMWARE("av7110/bootcode.bin");
-
-/****************************************************************************
- * DEBI command polling
- ****************************************************************************/
-
-int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
-{
-       unsigned long start;
-       u32 stat;
-       int err;
-
-       if (FW_VERSION(av7110->arm_app) <= 0x261c) {
-               /* not supported by old firmware */
-               msleep(50);
-               return 0;
-       }
-
-       /* new firmware */
-       start = jiffies;
-       for (;;) {
-               err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (mutex_lock_interruptible(&av7110->dcomlock))
-                       return -ERESTARTSYS;
-               stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-               mutex_unlock(&av7110->dcomlock);
-               if ((stat & flags) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
-                               __func__, stat & flags);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-       return 0;
-}
-
-static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
-{
-       int i;
-       unsigned long start;
-       char *type = NULL;
-       u16 flags[2] = {0, 0};
-       u32 stat;
-       int err;
-
-//     dprintk(4, "%p\n", av7110);
-
-       if (!av7110->arm_ready) {
-               dprintk(1, "arm not ready.\n");
-               return -ENXIO;
-       }
-
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
-                       av7110->arm_errors++;
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-
-       if (FW_VERSION(av7110->arm_app) <= 0x261f)
-               wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
-
-#ifndef _NOHANDSHAKE
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
-               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-#endif
-
-       switch ((buf[0] >> 8) & 0xff) {
-       case COMTYPE_PIDFILTER:
-       case COMTYPE_ENCODER:
-       case COMTYPE_REC_PLAY:
-       case COMTYPE_MPEGDECODER:
-               type = "MSG";
-               flags[0] = GPMQOver;
-               flags[1] = GPMQFull;
-               break;
-       case COMTYPE_OSD:
-               type = "OSD";
-               flags[0] = OSDQOver;
-               flags[1] = OSDQFull;
-               break;
-       case COMTYPE_MISC:
-               if (FW_VERSION(av7110->arm_app) >= 0x261d) {
-                       type = "MSG";
-                       flags[0] = GPMQOver;
-                       flags[1] = GPMQBusy;
-               }
-               break;
-       default:
-               break;
-       }
-
-       if (type != NULL) {
-               /* non-immediate COMMAND type */
-               start = jiffies;
-               for (;;) {
-                       err = time_after(jiffies, start + ARM_WAIT_FREE);
-                       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-                       if (stat & flags[0]) {
-                               printk(KERN_ERR "%s: %s QUEUE overflow\n",
-                                       __func__, type);
-                               return -1;
-                       }
-                       if ((stat & flags[1]) == 0)
-                               break;
-                       if (err) {
-                               printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
-                                       __func__, type);
-                               av7110->arm_errors++;
-                               return -ETIMEDOUT;
-                       }
-                       msleep(1);
-               }
-       }
-
-       for (i = 2; i < length; i++)
-               wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
-
-       if (length)
-               wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
-       else
-               wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
-
-       wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
-
-       if (FW_VERSION(av7110->arm_app) <= 0x261f)
-               wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
-
-#ifdef COM_DEBUG
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
-                              __func__, (buf[0] >> 8) & 0xff);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-
-       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-       if (stat & GPMQOver) {
-               printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__);
-               return -ENOSPC;
-       }
-       else if (stat & OSDQOver) {
-               printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__);
-               return -ENOSPC;
-       }
-#endif
-
-       return 0;
-}
-
-static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
-{
-       int ret;
-
-//     dprintk(4, "%p\n", av7110);
-
-       if (!av7110->arm_ready) {
-               dprintk(1, "arm not ready.\n");
-               return -1;
-       }
-       if (mutex_lock_interruptible(&av7110->dcomlock))
-               return -ERESTARTSYS;
-
-       ret = __av7110_send_fw_cmd(av7110, buf, length);
-       mutex_unlock(&av7110->dcomlock);
-       if (ret && ret!=-ERESTARTSYS)
-               printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
-                      __func__, ret);
-       return ret;
-}
-
-int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
-{
-       va_list args;
-       u16 buf[num + 2];
-       int i, ret;
-
-//     dprintk(4, "%p\n", av7110);
-
-       buf[0] = ((type << 8) | com);
-       buf[1] = num;
-
-       if (num) {
-               va_start(args, num);
-               for (i = 0; i < num; i++)
-                       buf[i + 2] = va_arg(args, u32);
-               va_end(args);
-       }
-
-       ret = av7110_send_fw_cmd(av7110, buf, num + 2);
-       if (ret && ret != -ERESTARTSYS)
-               printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
-       return ret;
-}
-
-#if 0
-int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
-{
-       int i, ret;
-       u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
-               16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-       dprintk(4, "%p\n", av7110);
-
-       for(i = 0; i < len && i < 32; i++)
-       {
-               if(i % 2 == 0)
-                       cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
-               else
-                       cmd[(i / 2) + 2] |= buf[i];
-       }
-
-       ret = av7110_send_fw_cmd(av7110, cmd, 18);
-       if (ret && ret != -ERESTARTSYS)
-               printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
-       return ret;
-}
-#endif  /*  0  */
-
-int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
-                     int request_buf_len, u16 *reply_buf, int reply_buf_len)
-{
-       int err;
-       s16 i;
-       unsigned long start;
-#ifdef COM_DEBUG
-       u32 stat;
-#endif
-
-       dprintk(4, "%p\n", av7110);
-
-       if (!av7110->arm_ready) {
-               dprintk(1, "arm not ready.\n");
-               return -1;
-       }
-
-       if (mutex_lock_interruptible(&av7110->dcomlock))
-               return -ERESTARTSYS;
-
-       if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
-               mutex_unlock(&av7110->dcomlock);
-               printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
-               return err;
-       }
-
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
-                       mutex_unlock(&av7110->dcomlock);
-                       return -ETIMEDOUT;
-               }
-#ifdef _NOHANDSHAKE
-               msleep(1);
-#endif
-       }
-
-#ifndef _NOHANDSHAKE
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
-               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
-                       mutex_unlock(&av7110->dcomlock);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-#endif
-
-#ifdef COM_DEBUG
-       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-       if (stat & GPMQOver) {
-               printk(KERN_ERR "%s: GPMQOver\n", __func__);
-               mutex_unlock(&av7110->dcomlock);
-               return -1;
-       }
-       else if (stat & OSDQOver) {
-               printk(KERN_ERR "%s: OSDQOver\n", __func__);
-               mutex_unlock(&av7110->dcomlock);
-               return -1;
-       }
-#endif
-
-       for (i = 0; i < reply_buf_len; i++)
-               reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
-
-       mutex_unlock(&av7110->dcomlock);
-       return 0;
-}
-
-static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
-{
-       int ret;
-       ret = av7110_fw_request(av7110, &tag, 0, buf, length);
-       if (ret)
-               printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
-       return ret;
-}
-
-
-/****************************************************************************
- * Firmware commands
- ****************************************************************************/
-
-/* get version of the firmware ROM, RTSL, video ucode and ARM application  */
-int av7110_firmversion(struct av7110 *av7110)
-{
-       u16 buf[20];
-       u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
-
-       dprintk(4, "%p\n", av7110);
-
-       if (av7110_fw_query(av7110, tag, buf, 16)) {
-               printk("dvb-ttpci: failed to boot firmware @ card %d\n",
-                      av7110->dvb_adapter.num);
-               return -EIO;
-       }
-
-       av7110->arm_fw = (buf[0] << 16) + buf[1];
-       av7110->arm_rtsl = (buf[2] << 16) + buf[3];
-       av7110->arm_vid = (buf[4] << 16) + buf[5];
-       av7110->arm_app = (buf[6] << 16) + buf[7];
-       av7110->avtype = (buf[8] << 16) + buf[9];
-
-       printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
-              av7110->dvb_adapter.num, av7110->arm_fw,
-              av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
-
-       /* print firmware capabilities */
-       if (FW_CI_LL_SUPPORT(av7110->arm_app))
-               printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
-                      av7110->dvb_adapter.num);
-       else
-               printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
-                      av7110->dvb_adapter.num);
-
-       return 0;
-}
-
-
-int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
-{
-       int i, ret;
-       u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
-                       16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-       dprintk(4, "%p\n", av7110);
-
-       if (len > 10)
-               len = 10;
-
-       buf[1] = len + 2;
-       buf[2] = len;
-
-       if (burst != -1)
-               buf[3] = burst ? 0x01 : 0x00;
-       else
-               buf[3] = 0xffff;
-
-       for (i = 0; i < len; i++)
-               buf[i + 4] = msg[i];
-
-       ret = av7110_send_fw_cmd(av7110, buf, 18);
-       if (ret && ret!=-ERESTARTSYS)
-               printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
-       return ret;
-}
-
-
-#ifdef CONFIG_DVB_AV7110_OSD
-
-static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
-}
-
-static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
-                    enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
-                            windownr, colordepth, index, blending);
-}
-
-static inline int SetColor_(struct av7110 *av7110, u8 windownr,
-                    enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
-                            windownr, colordepth, index, colorhi, colorlo);
-}
-
-static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
-                         u16 colorfg, u16 colorbg)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
-                            windownr, fontsize, colorfg, colorbg);
-}
-
-static int FlushText(struct av7110 *av7110)
-{
-       unsigned long start;
-       int err;
-
-       if (mutex_lock_interruptible(&av7110->dcomlock))
-               return -ERESTARTSYS;
-       start = jiffies;
-       while (1) {
-               err = time_after(jiffies, start + ARM_WAIT_OSD);
-               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
-                       break;
-               if (err) {
-                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
-                              __func__);
-                       mutex_unlock(&av7110->dcomlock);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-       mutex_unlock(&av7110->dcomlock);
-       return 0;
-}
-
-static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
-{
-       int i, ret;
-       unsigned long start;
-       int length = strlen(buf) + 1;
-       u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
-
-       if (mutex_lock_interruptible(&av7110->dcomlock))
-               return -ERESTARTSYS;
-
-       start = jiffies;
-       while (1) {
-               ret = time_after(jiffies, start + ARM_WAIT_OSD);
-               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
-                       break;
-               if (ret) {
-                       printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
-                              __func__);
-                       mutex_unlock(&av7110->dcomlock);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-#ifndef _NOHANDSHAKE
-       start = jiffies;
-       while (1) {
-               ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
-               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
-                       break;
-               if (ret) {
-                       printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
-                              __func__);
-                       mutex_unlock(&av7110->dcomlock);
-                       return -ETIMEDOUT;
-               }
-               msleep(1);
-       }
-#endif
-       for (i = 0; i < length / 2; i++)
-               wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
-                     swab16(*(u16 *)(buf + 2 * i)), 2);
-       if (length & 1)
-               wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
-       ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
-       mutex_unlock(&av7110->dcomlock);
-       if (ret && ret!=-ERESTARTSYS)
-               printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
-       return ret;
-}
-
-static inline int DrawLine(struct av7110 *av7110, u8 windownr,
-                          u16 x, u16 y, u16 dx, u16 dy, u16 color)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
-                            windownr, x, y, dx, dy, color);
-}
-
-static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
-                           u16 x, u16 y, u16 dx, u16 dy, u16 color)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
-                            windownr, x, y, dx, dy, color);
-}
-
-static inline int HideWindow(struct av7110 *av7110, u8 windownr)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
-}
-
-static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
-}
-
-static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
-}
-
-static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
-}
-
-static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
-                                 osd_raw_window_t disptype,
-                                 u16 width, u16 height)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
-                            windownr, disptype, width, height);
-}
-
-
-static enum av7110_osd_palette_type bpp2pal[8] = {
-       Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
-};
-static osd_raw_window_t bpp2bit[8] = {
-       OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
-};
-
-static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
-{
-       int ret = wait_event_timeout(av7110->bmpq,
-                               av7110->bmp_state != BMP_LOADING, 10*HZ);
-       if (ret == 0) {
-               printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
-                      ret, av7110->bmp_state);
-               av7110->bmp_state = BMP_NONE;
-               return -ETIMEDOUT;
-       }
-       return 0;
-}
-
-static inline int LoadBitmap(struct av7110 *av7110,
-                            u16 dx, u16 dy, int inc, u8 __user * data)
-{
-       u16 format;
-       int bpp;
-       int i;
-       int d, delta;
-       u8 c;
-       int ret;
-
-       dprintk(4, "%p\n", av7110);
-
-       format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
-
-       av7110->bmp_state = BMP_LOADING;
-       if      (format == OSD_BITMAP8) {
-               bpp=8; delta = 1;
-       } else if (format == OSD_BITMAP4) {
-               bpp=4; delta = 2;
-       } else if (format == OSD_BITMAP2) {
-               bpp=2; delta = 4;
-       } else if (format == OSD_BITMAP1) {
-               bpp=1; delta = 8;
-       } else {
-               av7110->bmp_state = BMP_NONE;
-               return -EINVAL;
-       }
-       av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
-       av7110->bmpp = 0;
-       if (av7110->bmplen > 32768) {
-               av7110->bmp_state = BMP_NONE;
-               return -EINVAL;
-       }
-       for (i = 0; i < dy; i++) {
-               if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
-                       av7110->bmp_state = BMP_NONE;
-                       return -EINVAL;
-               }
-       }
-       if (format != OSD_BITMAP8) {
-               for (i = 0; i < dx * dy / delta; i++) {
-                       c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
-                       for (d = delta - 2; d >= 0; d--) {
-                               c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
-                                     << ((delta - d - 1) * bpp));
-                               ((u8 *)av7110->bmpbuf)[1024 + i] = c;
-                       }
-               }
-       }
-       av7110->bmplen += 1024;
-       dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
-       ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
-       if (!ret)
-               ret = WaitUntilBmpLoaded(av7110);
-       return ret;
-}
-
-static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
-{
-       dprintk(4, "%p\n", av7110);
-
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
-}
-
-static inline int ReleaseBitmap(struct av7110 *av7110)
-{
-       dprintk(4, "%p\n", av7110);
-
-       if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
-               return -1;
-       if (av7110->bmp_state == BMP_LOADING)
-               dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
-       av7110->bmp_state = BMP_NONE;
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
-}
-
-static u32 RGB2YUV(u16 R, u16 G, u16 B)
-{
-       u16 y, u, v;
-       u16 Y, Cr, Cb;
-
-       y = R * 77 + G * 150 + B * 29;  /* Luma=0.299R+0.587G+0.114B 0..65535 */
-       u = 2048 + B * 8 -(y >> 5);     /* Cr 0..4095 */
-       v = 2048 + R * 8 -(y >> 5);     /* Cb 0..4095 */
-
-       Y = y / 256;
-       Cb = u / 16;
-       Cr = v / 16;
-
-       return Cr | (Cb << 16) | (Y << 8);
-}
-
-static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
-{
-       int ret;
-
-       u16 ch, cl;
-       u32 yuv;
-
-       yuv = blend ? RGB2YUV(r,g,b) : 0;
-       cl = (yuv & 0xffff);
-       ch = ((yuv >> 16) & 0xffff);
-       ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
-                       color, ch, cl);
-       if (!ret)
-               ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
-                               color, ((blend >> 4) & 0x0f));
-       return ret;
-}
-
-static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
-{
-       int i;
-       int length = last - first + 1;
-
-       if (length * 4 > DATA_BUFF3_SIZE)
-               return -EINVAL;
-
-       for (i = 0; i < length; i++) {
-               u32 color, blend, yuv;
-
-               if (get_user(color, colors + i))
-                       return -EFAULT;
-               blend = (color & 0xF0000000) >> 4;
-               yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
-                                    (color >> 16) & 0xFF) | blend : 0;
-               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
-               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
-       }
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
-                           av7110->osdwin,
-                           bpp2pal[av7110->osdbpp[av7110->osdwin]],
-                           first, last);
-}
-
-static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
-                      int x1, int y1, int inc, u8 __user * data)
-{
-       uint w, h, bpp, bpl, size, lpb, bnum, brest;
-       int i;
-       int rc,release_rc;
-
-       w = x1 - x0 + 1;
-       h = y1 - y0 + 1;
-       if (inc <= 0)
-               inc = w;
-       if (w <= 0 || w > 720 || h <= 0 || h > 576)
-               return -EINVAL;
-       bpp = av7110->osdbpp[av7110->osdwin] + 1;
-       bpl = ((w * bpp + 7) & ~7) / 8;
-       size = h * bpl;
-       lpb = (32 * 1024) / bpl;
-       bnum = size / (lpb * bpl);
-       brest = size - bnum * lpb * bpl;
-
-       if (av7110->bmp_state == BMP_LOADING) {
-               /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
-               BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
-               rc = WaitUntilBmpLoaded(av7110);
-               if (rc)
-                       return rc;
-               /* just continue. This should work for all fw versions
-                * if bnum==1 && !brest && LoadBitmap was successful
-                */
-       }
-
-       rc = 0;
-       for (i = 0; i < bnum; i++) {
-               rc = LoadBitmap(av7110, w, lpb, inc, data);
-               if (rc)
-                       break;
-               rc = BlitBitmap(av7110, x0, y0 + i * lpb);
-               if (rc)
-                       break;
-               data += lpb * inc;
-       }
-       if (!rc && brest) {
-               rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
-               if (!rc)
-                       rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
-       }
-       release_rc = ReleaseBitmap(av7110);
-       if (!rc)
-               rc = release_rc;
-       if (rc)
-               dprintk(1,"returns %d\n",rc);
-       return rc;
-}
-
-int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&av7110->osd_mutex))
-               return -ERESTARTSYS;
-
-       switch (dc->cmd) {
-       case OSD_Close:
-               ret = DestroyOSDWindow(av7110, av7110->osdwin);
-               break;
-       case OSD_Open:
-               av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
-               ret = CreateOSDWindow(av7110, av7110->osdwin,
-                               bpp2bit[av7110->osdbpp[av7110->osdwin]],
-                               dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
-               if (ret)
-                       break;
-               if (!dc->data) {
-                       ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-                       if (ret)
-                               break;
-                       ret = SetColorBlend(av7110, av7110->osdwin);
-               }
-               break;
-       case OSD_Show:
-               ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
-               break;
-       case OSD_Hide:
-               ret = HideWindow(av7110, av7110->osdwin);
-               break;
-       case OSD_Clear:
-               ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
-               break;
-       case OSD_Fill:
-               ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
-               break;
-       case OSD_SetColor:
-               ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
-               break;
-       case OSD_SetPalette:
-               if (FW_VERSION(av7110->arm_app) >= 0x2618)
-                       ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
-               else {
-                       int i, len = dc->x0-dc->color+1;
-                       u8 __user *colors = (u8 __user *)dc->data;
-                       u8 r, g = 0, b = 0, blend = 0;
-                       ret = 0;
-                       for (i = 0; i<len; i++) {
-                               if (get_user(r, colors + i * 4) ||
-                                   get_user(g, colors + i * 4 + 1) ||
-                                   get_user(b, colors + i * 4 + 2) ||
-                                   get_user(blend, colors + i * 4 + 3)) {
-                                       ret = -EFAULT;
-                                       break;
-                                   }
-                               ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
-                               if (ret)
-                                       break;
-                       }
-               }
-               break;
-       case OSD_SetPixel:
-               ret = DrawLine(av7110, av7110->osdwin,
-                        dc->x0, dc->y0, 0, 0, dc->color);
-               break;
-       case OSD_SetRow:
-               dc->y1 = dc->y0;
-               /* fall through */
-       case OSD_SetBlock:
-               ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
-               break;
-       case OSD_FillRow:
-               ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
-                         dc->x1-dc->x0+1, dc->y1, dc->color);
-               break;
-       case OSD_FillBlock:
-               ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
-                         dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
-               break;
-       case OSD_Line:
-               ret = DrawLine(av7110, av7110->osdwin,
-                        dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
-               break;
-       case OSD_Text:
-       {
-               char textbuf[240];
-
-               if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
-                       ret = -EFAULT;
-                       break;
-               }
-               textbuf[239] = 0;
-               if (dc->x1 > 3)
-                       dc->x1 = 3;
-               ret = SetFont(av7110, av7110->osdwin, dc->x1,
-                       (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
-               if (!ret)
-                       ret = FlushText(av7110);
-               if (!ret)
-                       ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
-               break;
-       }
-       case OSD_SetWindow:
-               if (dc->x0 < 1 || dc->x0 > 7)
-                       ret = -EINVAL;
-               else {
-                       av7110->osdwin = dc->x0;
-                       ret = 0;
-               }
-               break;
-       case OSD_MoveWindow:
-               ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-               if (!ret)
-                       ret = SetColorBlend(av7110, av7110->osdwin);
-               break;
-       case OSD_OpenRaw:
-               if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
-                       ret = -EINVAL;
-                       break;
-               }
-               if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
-                       av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
-               else
-                       av7110->osdbpp[av7110->osdwin] = 0;
-               ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
-                               dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
-               if (ret)
-                       break;
-               if (!dc->data) {
-                       ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-                       if (!ret)
-                               ret = SetColorBlend(av7110, av7110->osdwin);
-               }
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-
-       mutex_unlock(&av7110->osd_mutex);
-       if (ret==-ERESTARTSYS)
-               dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
-       else if (ret)
-               dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
-
-       return ret;
-}
-
-int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
-{
-       switch (cap->cmd) {
-       case OSD_CAP_MEMSIZE:
-               if (FW_4M_SDRAM(av7110->arm_app))
-                       cap->val = 1000000;
-               else
-                       cap->val = 92000;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-#endif /* CONFIG_DVB_AV7110_OSD */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
deleted file mode 100644 (file)
index 1634aba..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-#ifndef _AV7110_HW_H_
-#define _AV7110_HW_H_
-
-#include "av7110.h"
-
-/* DEBI transfer mode defs */
-
-#define DEBINOSWAP 0x000e0000
-#define DEBISWAB   0x001e0000
-#define DEBISWAP   0x002e0000
-
-#define ARM_WAIT_FREE  (HZ)
-#define ARM_WAIT_SHAKE (HZ/5)
-#define ARM_WAIT_OSD (HZ)
-
-
-enum av7110_bootstate
-{
-       BOOTSTATE_BUFFER_EMPTY  = 0,
-       BOOTSTATE_BUFFER_FULL   = 1,
-       BOOTSTATE_AV7110_BOOT_COMPLETE  = 2
-};
-
-enum av7110_type_rec_play_format
-{      RP_None,
-       AudioPES,
-       AudioMp2,
-       AudioPCM,
-       VideoPES,
-       AV_PES
-};
-
-enum av7110_osd_palette_type
-{
-       NoPalet =  0,      /* No palette */
-       Pal1Bit =  2,      /* 2 colors for 1 Bit Palette    */
-       Pal2Bit =  4,      /* 4 colors for 2 bit palette    */
-       Pal4Bit =  16,     /* 16 colors for 4 bit palette   */
-       Pal8Bit =  256     /* 256 colors for 16 bit palette */
-};
-
-/* switch defines */
-#define SB_GPIO 3
-#define SB_OFF SAA7146_GPIO_OUTLO  /* SlowBlank off (TV-Mode) */
-#define SB_ON  SAA7146_GPIO_INPUT  /* SlowBlank on  (AV-Mode) */
-#define SB_WIDE SAA7146_GPIO_OUTHI  /* SlowBlank 6V  (16/9-Mode) (not implemented) */
-
-#define FB_GPIO 1
-#define FB_OFF SAA7146_GPIO_LO     /* FastBlank off (CVBS-Mode) */
-#define FB_ON  SAA7146_GPIO_OUTHI  /* FastBlank on  (RGB-Mode) */
-#define FB_LOOP        SAA7146_GPIO_INPUT  /* FastBlank loop-through (PC graphics ???) */
-
-enum av7110_video_output_mode
-{
-       NO_OUT       = 0,               /* disable analog output */
-       CVBS_RGB_OUT = 1,
-       CVBS_YC_OUT  = 2,
-       YC_OUT       = 3
-};
-
-/* firmware internal msg q status: */
-#define GPMQFull       0x0001          /* Main Message Queue Full */
-#define GPMQOver       0x0002          /* Main Message Queue Overflow */
-#define HPQFull                0x0004          /* High Priority Msg Queue Full */
-#define HPQOver                0x0008
-#define OSDQFull       0x0010          /* OSD Queue Full */
-#define OSDQOver       0x0020
-#define GPMQBusy       0x0040          /* Queue not empty, FW >= 261d */
-#define HPQBusy                0x0080
-#define OSDQBusy       0x0100
-
-/* hw section filter flags */
-#define        SECTION_EIT             0x01
-#define        SECTION_SINGLE          0x00
-#define        SECTION_CYCLE           0x02
-#define        SECTION_CONTINUOS       0x04
-#define        SECTION_MODE            0x06
-#define SECTION_IPMPE          0x0C    /* size up to 4k */
-#define SECTION_HIGH_SPEED     0x1C    /* larger buffer */
-#define DATA_PIPING_FLAG       0x20    /* for Data Piping Filter */
-
-#define        PBUFSIZE_NONE 0x0000
-#define        PBUFSIZE_1P   0x0100
-#define        PBUFSIZE_2P   0x0200
-#define        PBUFSIZE_1K   0x0300
-#define        PBUFSIZE_2K   0x0400
-#define        PBUFSIZE_4K   0x0500
-#define        PBUFSIZE_8K   0x0600
-#define PBUFSIZE_16K  0x0700
-#define PBUFSIZE_32K  0x0800
-
-
-/* firmware command codes */
-enum av7110_osd_command {
-       WCreate,
-       WDestroy,
-       WMoveD,
-       WMoveA,
-       WHide,
-       WTop,
-       DBox,
-       DLine,
-       DText,
-       Set_Font,
-       SetColor,
-       SetBlend,
-       SetWBlend,
-       SetCBlend,
-       SetNonBlend,
-       LoadBmp,
-       BlitBmp,
-       ReleaseBmp,
-       SetWTrans,
-       SetWNoTrans,
-       Set_Palette
-};
-
-enum av7110_pid_command {
-       MultiPID,
-       VideoPID,
-       AudioPID,
-       InitFilt,
-       FiltError,
-       NewVersion,
-       CacheError,
-       AddPIDFilter,
-       DelPIDFilter,
-       Scan,
-       SetDescr,
-       SetIR,
-       FlushTSQueue
-};
-
-enum av7110_mpeg_command {
-       SelAudChannels
-};
-
-enum av7110_audio_command {
-       AudioDAC,
-       CabADAC,
-       ON22K,
-       OFF22K,
-       MainSwitch,
-       ADSwitch,
-       SendDiSEqC,
-       SetRegister,
-       SpdifSwitch
-};
-
-enum av7110_request_command {
-       AudioState,
-       AudioBuffState,
-       VideoState1,
-       VideoState2,
-       VideoState3,
-       CrashCounter,
-       ReqVersion,
-       ReqVCXO,
-       ReqRegister,
-       ReqSecFilterError,
-       ReqSTC
-};
-
-enum av7110_encoder_command {
-       SetVidMode,
-       SetTestMode,
-       LoadVidCode,
-       SetMonitorType,
-       SetPanScanType,
-       SetFreezeMode,
-       SetWSSConfig
-};
-
-enum av7110_rec_play_state {
-       __Record,
-       __Stop,
-       __Play,
-       __Pause,
-       __Slow,
-       __FF_IP,
-       __Scan_I,
-       __Continue
-};
-
-enum av7110_fw_cmd_misc {
-       AV7110_FW_VIDEO_ZOOM = 1,
-       AV7110_FW_VIDEO_COMMAND,
-       AV7110_FW_AUDIO_COMMAND
-};
-
-enum av7110_command_type {
-       COMTYPE_NOCOM,
-       COMTYPE_PIDFILTER,
-       COMTYPE_MPEGDECODER,
-       COMTYPE_OSD,
-       COMTYPE_BMP,
-       COMTYPE_ENCODER,
-       COMTYPE_AUDIODAC,
-       COMTYPE_REQUEST,
-       COMTYPE_SYSTEM,
-       COMTYPE_REC_PLAY,
-       COMTYPE_COMMON_IF,
-       COMTYPE_PID_FILTER,
-       COMTYPE_PES,
-       COMTYPE_TS,
-       COMTYPE_VIDEO,
-       COMTYPE_AUDIO,
-       COMTYPE_CI_LL,
-       COMTYPE_MISC = 0x80
-};
-
-#define VID_NONE_PREF          0x00    /* No aspect ration processing preferred */
-#define VID_PAN_SCAN_PREF      0x01    /* Pan and Scan Display preferred */
-#define VID_VERT_COMP_PREF     0x02    /* Vertical compression display preferred */
-#define VID_VC_AND_PS_PREF     0x03    /* PanScan and vertical Compression if allowed */
-#define VID_CENTRE_CUT_PREF    0x05    /* PanScan with zero vector */
-
-/* MPEG video decoder commands */
-#define AV_VIDEO_CMD_STOP      0x000e
-#define AV_VIDEO_CMD_PLAY      0x000d
-#define AV_VIDEO_CMD_FREEZE    0x0102
-#define AV_VIDEO_CMD_FFWD      0x0016
-#define AV_VIDEO_CMD_SLOW      0x0022
-
-/* MPEG audio decoder commands */
-#define AUDIO_CMD_MUTE         0x0001
-#define AUDIO_CMD_UNMUTE       0x0002
-#define AUDIO_CMD_PCM16                0x0010
-#define AUDIO_CMD_STEREO       0x0080
-#define AUDIO_CMD_MONO_L       0x0100
-#define AUDIO_CMD_MONO_R       0x0200
-#define AUDIO_CMD_SYNC_OFF     0x000e
-#define AUDIO_CMD_SYNC_ON      0x000f
-
-/* firmware data interface codes */
-#define DATA_NONE               0x00
-#define DATA_FSECTION           0x01
-#define DATA_IPMPE              0x02
-#define DATA_MPEG_RECORD        0x03
-#define DATA_DEBUG_MESSAGE      0x04
-#define DATA_COMMON_INTERFACE   0x05
-#define DATA_MPEG_PLAY          0x06
-#define DATA_BMP_LOAD           0x07
-#define DATA_IRCOMMAND          0x08
-#define DATA_PIPING             0x09
-#define DATA_STREAMING          0x0a
-#define DATA_CI_GET             0x0b
-#define DATA_CI_PUT             0x0c
-#define DATA_MPEG_VIDEO_EVENT   0x0d
-
-#define DATA_PES_RECORD                 0x10
-#define DATA_PES_PLAY           0x11
-#define DATA_TS_RECORD          0x12
-#define DATA_TS_PLAY            0x13
-
-/* ancient CI command codes, only two are actually still used
- * by the link level CI firmware */
-#define CI_CMD_ERROR            0x00
-#define CI_CMD_ACK              0x01
-#define CI_CMD_SYSTEM_READY     0x02
-#define CI_CMD_KEYPRESS                 0x03
-#define CI_CMD_ON_TUNED                 0x04
-#define CI_CMD_ON_SWITCH_PROGRAM 0x05
-#define CI_CMD_SECTION_ARRIVED  0x06
-#define CI_CMD_SECTION_TIMEOUT  0x07
-#define CI_CMD_TIME             0x08
-#define CI_CMD_ENTER_MENU       0x09
-#define CI_CMD_FAST_PSI                 0x0a
-#define CI_CMD_GET_SLOT_INFO    0x0b
-
-#define CI_MSG_NONE             0x00
-#define CI_MSG_CI_INFO          0x01
-#define CI_MSG_MENU             0x02
-#define CI_MSG_LIST             0x03
-#define CI_MSG_TEXT             0x04
-#define CI_MSG_REQUEST_INPUT    0x05
-#define CI_MSG_INPUT_COMPLETE   0x06
-#define CI_MSG_LIST_MORE        0x07
-#define CI_MSG_MENU_MORE        0x08
-#define CI_MSG_CLOSE_MMI_IMM    0x09
-#define CI_MSG_SECTION_REQUEST  0x0a
-#define CI_MSG_CLOSE_FILTER     0x0b
-#define CI_PSI_COMPLETE                 0x0c
-#define CI_MODULE_READY                 0x0d
-#define CI_SWITCH_PRG_REPLY     0x0e
-#define CI_MSG_TEXT_MORE        0x0f
-
-#define CI_MSG_CA_PMT           0xe0
-#define CI_MSG_ERROR            0xf0
-
-
-/* base address of the dual ported RAM which serves as communication
- * area between PCI bus and av7110,
- * as seen by the DEBI bus of the saa7146 */
-#define        DPRAM_BASE 0x4000
-
-/* boot protocol area */
-#define AV7110_BOOT_STATE      (DPRAM_BASE + 0x3F8)
-#define AV7110_BOOT_SIZE       (DPRAM_BASE + 0x3FA)
-#define AV7110_BOOT_BASE       (DPRAM_BASE + 0x3FC)
-#define AV7110_BOOT_BLOCK      (DPRAM_BASE + 0x400)
-#define AV7110_BOOT_MAX_SIZE   0xc00
-
-/* firmware command protocol area */
-#define IRQ_STATE      (DPRAM_BASE + 0x0F4)
-#define IRQ_STATE_EXT  (DPRAM_BASE + 0x0F6)
-#define MSGSTATE       (DPRAM_BASE + 0x0F8)
-#define COMMAND                (DPRAM_BASE + 0x0FC)
-#define COM_BUFF       (DPRAM_BASE + 0x100)
-#define COM_BUFF_SIZE  0x20
-
-/* various data buffers */
-#define BUFF1_BASE     (DPRAM_BASE + 0x120)
-#define BUFF1_SIZE     0xE0
-
-#define DATA_BUFF0_BASE        (DPRAM_BASE + 0x200)
-#define DATA_BUFF0_SIZE        0x0800
-
-#define DATA_BUFF1_BASE        (DATA_BUFF0_BASE+DATA_BUFF0_SIZE)
-#define DATA_BUFF1_SIZE        0x0800
-
-#define DATA_BUFF2_BASE        (DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
-#define DATA_BUFF2_SIZE        0x0800
-
-#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
-#define DATA_BUFF3_SIZE 0x0400
-
-#define Reserved       (DPRAM_BASE + 0x1E00)
-#define Reserved_SIZE  0x1C0
-
-
-/* firmware status area */
-#define STATUS_BASE    (DPRAM_BASE + 0x1FC0)
-#define STATUS_LOOPS   (STATUS_BASE + 0x08)
-
-#define STATUS_MPEG_WIDTH     (STATUS_BASE + 0x0C)
-/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */
-#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E)
-
-/* firmware data protocol area */
-#define RX_TYPE                (DPRAM_BASE + 0x1FE8)
-#define RX_LEN         (DPRAM_BASE + 0x1FEA)
-#define TX_TYPE                (DPRAM_BASE + 0x1FEC)
-#define TX_LEN         (DPRAM_BASE + 0x1FEE)
-
-#define RX_BUFF                (DPRAM_BASE + 0x1FF4)
-#define TX_BUFF                (DPRAM_BASE + 0x1FF6)
-
-#define HANDSHAKE_REG  (DPRAM_BASE + 0x1FF8)
-#define COM_IF_LOCK    (DPRAM_BASE + 0x1FFA)
-
-#define IRQ_RX         (DPRAM_BASE + 0x1FFC)
-#define IRQ_TX         (DPRAM_BASE + 0x1FFE)
-
-/* used by boot protocol to load firmware into av7110 DRAM */
-#define DRAM_START_CODE                0x2e000404
-#define DRAM_MAX_CODE_SIZE     0x00100000
-
-/* saa7146 gpio lines */
-#define RESET_LINE             2
-#define DEBI_DONE_LINE         1
-#define ARM_IRQ_LINE           0
-
-
-
-extern int av7110_bootarm(struct av7110 *av7110);
-extern int av7110_firmversion(struct av7110 *av7110);
-#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
-#define FW_4M_SDRAM(arm_app)      ((arm_app) & 0x40000000)
-#define FW_VERSION(arm_app)      ((arm_app) & 0x0000FFFF)
-
-extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
-extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
-extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
-                            int request_buf_len, u16 *reply_buf, int reply_buf_len);
-
-
-/* DEBI (saa7146 data extension bus interface) access */
-extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
-                           int addr, u32 val, int count);
-extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
-                          int addr, int count);
-
-
-/* DEBI during interrupt */
-/* single word writes */
-static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
-{
-       av7110_debiwrite(av7110, config, addr, val, count);
-}
-
-/* buffer writes */
-static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
-                         const u8 *val, int count)
-{
-       memcpy(av7110->debi_virt, val, count);
-       av7110_debiwrite(av7110, config, addr, 0, count);
-}
-
-static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
-{
-       u32 res;
-
-       res=av7110_debiread(av7110, config, addr, count);
-       if (count<=4)
-               memcpy(av7110->debi_virt, (char *) &res, count);
-       return res;
-}
-
-/* DEBI outside interrupts, only for count <= 4! */
-static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&av7110->debilock, flags);
-       av7110_debiwrite(av7110, config, addr, val, count);
-       spin_unlock_irqrestore(&av7110->debilock, flags);
-}
-
-static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
-{
-       unsigned long flags;
-       u32 res;
-
-       spin_lock_irqsave(&av7110->debilock, flags);
-       res=av7110_debiread(av7110, config, addr, count);
-       spin_unlock_irqrestore(&av7110->debilock, flags);
-       return res;
-}
-
-/* handle mailbox registers of the dual ported RAM */
-static inline void ARM_ResetMailBox(struct av7110 *av7110)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&av7110->debilock, flags);
-       av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
-       av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
-       spin_unlock_irqrestore(&av7110->debilock, flags);
-}
-
-static inline void ARM_ClearMailBox(struct av7110 *av7110)
-{
-       iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
-}
-
-static inline void ARM_ClearIrq(struct av7110 *av7110)
-{
-       irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
-}
-
-/****************************************************************************
- * Firmware commands
- ****************************************************************************/
-
-static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
-}
-
-static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
-}
-
-static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
-                            (com>>16), (com&0xffff),
-                            (arg>>16), (arg&0xffff));
-}
-
-static inline int audcom(struct av7110 *av7110, u32 com)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
-                            (com>>16), (com&0xffff));
-}
-
-static inline int Set22K(struct av7110 *av7110, int state)
-{
-       return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
-}
-
-
-extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
-
-
-#ifdef CONFIG_DVB_AV7110_OSD
-extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
-extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
-#endif /* CONFIG_DVB_AV7110_OSD */
-
-
-
-#endif /* _AV7110_HW_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
deleted file mode 100644 (file)
index 699ef8b..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-#include "dvb_filter.h"
-#include "av7110_ipack.h"
-#include <linux/string.h>      /* for memcpy() */
-#include <linux/vmalloc.h>
-
-
-void av7110_ipack_reset(struct ipack *p)
-{
-       p->found = 0;
-       p->cid = 0;
-       p->plength = 0;
-       p->flag1 = 0;
-       p->flag2 = 0;
-       p->hlength = 0;
-       p->mpeg = 0;
-       p->check = 0;
-       p->which = 0;
-       p->done = 0;
-       p->count = 0;
-}
-
-
-int av7110_ipack_init(struct ipack *p, int size,
-                     void (*func)(u8 *buf, int size, void *priv))
-{
-       if (!(p->buf = vmalloc(size*sizeof(u8)))) {
-               printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
-               return -ENOMEM;
-       }
-       p->size = size;
-       p->func = func;
-       p->repack_subids = 0;
-       av7110_ipack_reset(p);
-       return 0;
-}
-
-
-void av7110_ipack_free(struct ipack *p)
-{
-       vfree(p->buf);
-}
-
-
-static void send_ipack(struct ipack *p)
-{
-       int off;
-       struct dvb_audio_info ai;
-       int ac3_off = 0;
-       int streamid = 0;
-       int nframes = 0;
-       int f = 0;
-
-       switch (p->mpeg) {
-       case 2:
-               if (p->count < 10)
-                       return;
-               p->buf[3] = p->cid;
-               p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
-               p->buf[5] = (u8)((p->count - 6) & 0x00ff);
-               if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
-                       off = 9 + p->buf[8];
-                       streamid = p->buf[off];
-                       if ((streamid & 0xf8) == 0x80) {
-                               ai.off = 0;
-                               ac3_off = ((p->buf[off + 2] << 8)|
-                                          p->buf[off + 3]);
-                               if (ac3_off < p->count)
-                                       f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
-                                                                  p->count - ac3_off, &ai, 0);
-                               if (!f) {
-                                       nframes = (p->count - off - 3 - ac3_off) /
-                                               ai.framesize + 1;
-                                       p->buf[off + 2] = (ac3_off >> 8) & 0xff;
-                                       p->buf[off + 3] = (ac3_off) & 0xff;
-                                       p->buf[off + 1] = nframes;
-                                       ac3_off +=  nframes * ai.framesize - p->count;
-                               }
-                       }
-               }
-               p->func(p->buf, p->count, p->data);
-
-               p->buf[6] = 0x80;
-               p->buf[7] = 0x00;
-               p->buf[8] = 0x00;
-               p->count = 9;
-               if (p->repack_subids && p->cid == PRIVATE_STREAM1
-                   && (streamid & 0xf8) == 0x80) {
-                       p->count += 4;
-                       p->buf[9] = streamid;
-                       p->buf[10] = (ac3_off >> 8) & 0xff;
-                       p->buf[11] = (ac3_off) & 0xff;
-                       p->buf[12] = 0;
-               }
-               break;
-
-       case 1:
-               if (p->count < 8)
-                       return;
-               p->buf[3] = p->cid;
-               p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
-               p->buf[5] = (u8)((p->count - 6) & 0x00ff);
-               p->func(p->buf, p->count, p->data);
-
-               p->buf[6] = 0x0f;
-               p->count = 7;
-               break;
-       }
-}
-
-
-void av7110_ipack_flush(struct ipack *p)
-{
-       if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
-               return;
-       p->plength = p->found - 6;
-       p->found = 0;
-       send_ipack(p);
-       av7110_ipack_reset(p);
-}
-
-
-static void write_ipack(struct ipack *p, const u8 *data, int count)
-{
-       u8 headr[3] = { 0x00, 0x00, 0x01 };
-
-       if (p->count < 6) {
-               memcpy(p->buf, headr, 3);
-               p->count = 6;
-       }
-
-       if (p->count + count < p->size){
-               memcpy(p->buf+p->count, data, count);
-               p->count += count;
-       } else {
-               int rest = p->size - p->count;
-               memcpy(p->buf+p->count, data, rest);
-               p->count += rest;
-               send_ipack(p);
-               if (count - rest > 0)
-                       write_ipack(p, data + rest, count - rest);
-       }
-}
-
-
-int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
-{
-       int l;
-       int c = 0;
-
-       while (c < count && (p->mpeg == 0 ||
-                            (p->mpeg == 1 && p->found < 7) ||
-                            (p->mpeg == 2 && p->found < 9))
-              &&  (p->found < 5 || !p->done)) {
-               switch (p->found) {
-               case 0:
-               case 1:
-                       if (buf[c] == 0x00)
-                               p->found++;
-                       else
-                               p->found = 0;
-                       c++;
-                       break;
-               case 2:
-                       if (buf[c] == 0x01)
-                               p->found++;
-                       else if (buf[c] == 0)
-                               p->found = 2;
-                       else
-                               p->found = 0;
-                       c++;
-                       break;
-               case 3:
-                       p->cid = 0;
-                       switch (buf[c]) {
-                       case PROG_STREAM_MAP:
-                       case PRIVATE_STREAM2:
-                       case PROG_STREAM_DIR:
-                       case ECM_STREAM     :
-                       case EMM_STREAM     :
-                       case PADDING_STREAM :
-                       case DSM_CC_STREAM  :
-                       case ISO13522_STREAM:
-                               p->done = 1;
-                               /* fall through */
-                       case PRIVATE_STREAM1:
-                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-                               p->found++;
-                               p->cid = buf[c];
-                               c++;
-                               break;
-                       default:
-                               p->found = 0;
-                               break;
-                       }
-                       break;
-
-               case 4:
-                       if (count-c > 1) {
-                               p->plen[0] = buf[c];
-                               c++;
-                               p->plen[1] = buf[c];
-                               c++;
-                               p->found += 2;
-                               p->plength = (p->plen[0] << 8) | p->plen[1];
-                       } else {
-                               p->plen[0] = buf[c];
-                               p->found++;
-                               return count;
-                       }
-                       break;
-               case 5:
-                       p->plen[1] = buf[c];
-                       c++;
-                       p->found++;
-                       p->plength = (p->plen[0] << 8) | p->plen[1];
-                       break;
-               case 6:
-                       if (!p->done) {
-                               p->flag1 = buf[c];
-                               c++;
-                               p->found++;
-                               if ((p->flag1 & 0xc0) == 0x80)
-                                       p->mpeg = 2;
-                               else {
-                                       p->hlength = 0;
-                                       p->which = 0;
-                                       p->mpeg = 1;
-                                       p->flag2 = 0;
-                               }
-                       }
-                       break;
-
-               case 7:
-                       if (!p->done && p->mpeg == 2) {
-                               p->flag2 = buf[c];
-                               c++;
-                               p->found++;
-                       }
-                       break;
-
-               case 8:
-                       if (!p->done && p->mpeg == 2) {
-                               p->hlength = buf[c];
-                               c++;
-                               p->found++;
-                       }
-                       break;
-               }
-       }
-
-       if (c == count)
-               return count;
-
-       if (!p->plength)
-               p->plength = MMAX_PLENGTH - 6;
-
-       if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
-                       (p->mpeg == 1 && p->found >= 7))) {
-               switch (p->cid) {
-               case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-               case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-               case PRIVATE_STREAM1:
-                       if (p->mpeg == 2 && p->found == 9) {
-                               write_ipack(p, &p->flag1, 1);
-                               write_ipack(p, &p->flag2, 1);
-                               write_ipack(p, &p->hlength, 1);
-                       }
-
-                       if (p->mpeg == 1 && p->found == 7)
-                               write_ipack(p, &p->flag1, 1);
-
-                       if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
-                           p->found < 14) {
-                               while (c < count && p->found < 14) {
-                                       p->pts[p->found - 9] = buf[c];
-                                       write_ipack(p, buf + c, 1);
-                                       c++;
-                                       p->found++;
-                               }
-                               if (c == count)
-                                       return count;
-                       }
-
-                       if (p->mpeg == 1 && p->which < 2000) {
-
-                               if (p->found == 7) {
-                                       p->check = p->flag1;
-                                       p->hlength = 1;
-                               }
-
-                               while (!p->which && c < count &&
-                                      p->check == 0xff){
-                                       p->check = buf[c];
-                                       write_ipack(p, buf + c, 1);
-                                       c++;
-                                       p->found++;
-                                       p->hlength++;
-                               }
-
-                               if (c == count)
-                                       return count;
-
-                               if ((p->check & 0xc0) == 0x40 && !p->which) {
-                                       p->check = buf[c];
-                                       write_ipack(p, buf + c, 1);
-                                       c++;
-                                       p->found++;
-                                       p->hlength++;
-
-                                       p->which = 1;
-                                       if (c == count)
-                                               return count;
-                                       p->check = buf[c];
-                                       write_ipack(p, buf + c, 1);
-                                       c++;
-                                       p->found++;
-                                       p->hlength++;
-                                       p->which = 2;
-                                       if (c == count)
-                                               return count;
-                               }
-
-                               if (p->which == 1) {
-                                       p->check = buf[c];
-                                       write_ipack(p, buf + c, 1);
-                                       c++;
-                                       p->found++;
-                                       p->hlength++;
-                                       p->which = 2;
-                                       if (c == count)
-                                               return count;
-                               }
-
-                               if ((p->check & 0x30) && p->check != 0xff) {
-                                       p->flag2 = (p->check & 0xf0) << 2;
-                                       p->pts[0] = p->check;
-                                       p->which = 3;
-                               }
-
-                               if (c == count)
-                                       return count;
-                               if (p->which > 2){
-                                       if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
-                                               while (c < count && p->which < 7) {
-                                                       p->pts[p->which - 2] = buf[c];
-                                                       write_ipack(p, buf + c, 1);
-                                                       c++;
-                                                       p->found++;
-                                                       p->which++;
-                                                       p->hlength++;
-                                               }
-                                               if (c == count)
-                                                       return count;
-                                       } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
-                                               while (c < count && p->which < 12) {
-                                                       if (p->which < 7)
-                                                               p->pts[p->which - 2] = buf[c];
-                                                       write_ipack(p, buf + c, 1);
-                                                       c++;
-                                                       p->found++;
-                                                       p->which++;
-                                                       p->hlength++;
-                                               }
-                                               if (c == count)
-                                                       return count;
-                                       }
-                                       p->which = 2000;
-                               }
-
-                       }
-
-                       while (c < count && p->found < p->plength + 6) {
-                               l = count - c;
-                               if (l + p->found > p->plength + 6)
-                                       l = p->plength + 6 - p->found;
-                               write_ipack(p, buf + c, l);
-                               p->found += l;
-                               c += l;
-                       }
-                       break;
-               }
-
-
-               if (p->done) {
-                       if (p->found + count - c < p->plength + 6) {
-                               p->found += count - c;
-                               c = count;
-                       } else {
-                               c += p->plength + 6 - p->found;
-                               p->found = p->plength + 6;
-                       }
-               }
-
-               if (p->plength && p->found == p->plength + 6) {
-                       send_ipack(p);
-                       av7110_ipack_reset(p);
-                       if (c < count)
-                               av7110_ipack_instant_repack(buf + c, count - c, p);
-               }
-       }
-       return count;
-}
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h
deleted file mode 100644 (file)
index becf94d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _AV7110_IPACK_H_
-#define _AV7110_IPACK_H_
-
-extern int av7110_ipack_init(struct ipack *p, int size,
-                            void (*func)(u8 *buf,  int size, void *priv));
-
-extern void av7110_ipack_reset(struct ipack *p);
-extern int  av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
-extern void av7110_ipack_free(struct ipack * p);
-extern void av7110_ipack_flush(struct ipack *p);
-
-#endif
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
deleted file mode 100644 (file)
index 908f272..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Driver for the remote control of SAA7146 based AV7110 cards
- *
- * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
- * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-
-#include "av7110.h"
-#include "av7110_hw.h"
-
-
-#define AV_CNT         4
-
-#define IR_RC5         0
-#define IR_RCMM                1
-#define IR_RC5_EXT     2 /* internal only */
-
-#define IR_ALL         0xffffffff
-
-#define UP_TIMEOUT     (HZ*7/25)
-
-
-/* Note: enable ir debugging by or'ing debug with 16 */
-
-static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM};
-module_param_array(ir_protocol, int, NULL, 0644);
-MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)");
-
-static int ir_inversion[AV_CNT];
-module_param_array(ir_inversion, int, NULL, 0644);
-MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted");
-
-static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL };
-module_param_array(ir_device_mask, uint, NULL, 0644);
-MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)");
-
-
-static int av_cnt;
-static struct av7110 *av_list[AV_CNT];
-
-static u16 default_key_map [256] = {
-       KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
-       KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
-       KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
-       0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
-       KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
-       KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
-       KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
-       0, 0, 0, 0, KEY_EPG, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
-};
-
-
-/* key-up timer */
-static void av7110_emit_keyup(unsigned long parm)
-{
-       struct infrared *ir = (struct infrared *) parm;
-
-       if (!ir || !test_bit(ir->last_key, ir->input_dev->key))
-               return;
-
-       input_report_key(ir->input_dev, ir->last_key, 0);
-       input_sync(ir->input_dev);
-}
-
-
-/* tasklet */
-static void av7110_emit_key(unsigned long parm)
-{
-       struct infrared *ir = (struct infrared *) parm;
-       u32 ircom = ir->ir_command;
-       u8 data;
-       u8 addr;
-       u16 toggle;
-       u16 keycode;
-
-       /* extract device address and data */
-       switch (ir->protocol) {
-       case IR_RC5: /* RC5: 5 bits device address, 6 bits data */
-               data = ircom & 0x3f;
-               addr = (ircom >> 6) & 0x1f;
-               toggle = ircom & 0x0800;
-               break;
-
-       case IR_RCMM: /* RCMM: ? bits device address, ? bits data */
-               data = ircom & 0xff;
-               addr = (ircom >> 8) & 0x1f;
-               toggle = ircom & 0x8000;
-               break;
-
-       case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */
-               data = ircom & 0x3f;
-               addr = (ircom >> 6) & 0x1f;
-               /* invert 7th data bit for backward compatibility with RC5 keymaps */
-               if (!(ircom & 0x1000))
-                       data |= 0x40;
-               toggle = ircom & 0x0800;
-               break;
-
-       default:
-               printk("%s invalid protocol %x\n", __func__, ir->protocol);
-               return;
-       }
-
-       input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data);
-       input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
-
-       keycode = ir->key_map[data];
-
-       dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n",
-               __func__, ircom, addr, data, keycode);
-
-       /* check device address */
-       if (!(ir->device_mask & (1 << addr)))
-               return;
-
-       if (!keycode) {
-               printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n",
-                       __func__, ircom, addr, data);
-               return;
-       }
-
-       if (timer_pending(&ir->keyup_timer)) {
-               del_timer(&ir->keyup_timer);
-               if (ir->last_key != keycode || toggle != ir->last_toggle) {
-                       ir->delay_timer_finished = 0;
-                       input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
-                       input_event(ir->input_dev, EV_KEY, keycode, 1);
-                       input_sync(ir->input_dev);
-               } else if (ir->delay_timer_finished) {
-                       input_event(ir->input_dev, EV_KEY, keycode, 2);
-                       input_sync(ir->input_dev);
-               }
-       } else {
-               ir->delay_timer_finished = 0;
-               input_event(ir->input_dev, EV_KEY, keycode, 1);
-               input_sync(ir->input_dev);
-       }
-
-       ir->last_key = keycode;
-       ir->last_toggle = toggle;
-
-       ir->keyup_timer.expires = jiffies + UP_TIMEOUT;
-       add_timer(&ir->keyup_timer);
-
-}
-
-
-/* register with input layer */
-static void input_register_keys(struct infrared *ir)
-{
-       int i;
-
-       set_bit(EV_KEY, ir->input_dev->evbit);
-       set_bit(EV_REP, ir->input_dev->evbit);
-       set_bit(EV_MSC, ir->input_dev->evbit);
-
-       set_bit(MSC_RAW, ir->input_dev->mscbit);
-       set_bit(MSC_SCAN, ir->input_dev->mscbit);
-
-       memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
-
-       for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) {
-               if (ir->key_map[i] > KEY_MAX)
-                       ir->key_map[i] = 0;
-               else if (ir->key_map[i] > KEY_RESERVED)
-                       set_bit(ir->key_map[i], ir->input_dev->keybit);
-       }
-
-       ir->input_dev->keycode = ir->key_map;
-       ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
-       ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
-}
-
-
-/* called by the input driver after rep[REP_DELAY] ms */
-static void input_repeat_key(unsigned long parm)
-{
-       struct infrared *ir = (struct infrared *) parm;
-
-       ir->delay_timer_finished = 1;
-}
-
-
-/* check for configuration changes */
-int av7110_check_ir_config(struct av7110 *av7110, int force)
-{
-       int i;
-       int modified = force;
-       int ret = -ENODEV;
-
-       for (i = 0; i < av_cnt; i++)
-               if (av7110 == av_list[i])
-                       break;
-
-       if (i < av_cnt && av7110) {
-               if ((av7110->ir.protocol & 1) != ir_protocol[i] ||
-                   av7110->ir.inversion != ir_inversion[i])
-                       modified = true;
-
-               if (modified) {
-                       /* protocol */
-                       if (ir_protocol[i]) {
-                               ir_protocol[i] = 1;
-                               av7110->ir.protocol = IR_RCMM;
-                               av7110->ir.ir_config = 0x0001;
-                       } else if (FW_VERSION(av7110->arm_app) >= 0x2620) {
-                               av7110->ir.protocol = IR_RC5_EXT;
-                               av7110->ir.ir_config = 0x0002;
-                       } else {
-                               av7110->ir.protocol = IR_RC5;
-                               av7110->ir.ir_config = 0x0000;
-                       }
-                       /* inversion */
-                       if (ir_inversion[i]) {
-                               ir_inversion[i] = 1;
-                               av7110->ir.ir_config |= 0x8000;
-                       }
-                       av7110->ir.inversion = ir_inversion[i];
-                       /* update ARM */
-                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
-                                               av7110->ir.ir_config);
-               } else
-                       ret = 0;
-
-               /* address */
-               if (av7110->ir.device_mask != ir_device_mask[i])
-                       av7110->ir.device_mask = ir_device_mask[i];
-       }
-
-       return ret;
-}
-
-
-/* /proc/av7110_ir interface */
-static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
-                                   size_t count, loff_t *pos)
-{
-       char *page;
-       u32 ir_config;
-       int size = sizeof ir_config + sizeof av_list[0]->ir.key_map;
-       int i;
-
-       if (count < size)
-               return -EINVAL;
-
-       page = vmalloc(size);
-       if (!page)
-               return -ENOMEM;
-
-       if (copy_from_user(page, buffer, size)) {
-               vfree(page);
-               return -EFAULT;
-       }
-
-       memcpy(&ir_config, page, sizeof ir_config);
-
-       for (i = 0; i < av_cnt; i++) {
-               /* keymap */
-               memcpy(av_list[i]->ir.key_map, page + sizeof ir_config,
-                       sizeof(av_list[i]->ir.key_map));
-               /* protocol, inversion, address */
-               ir_protocol[i] = ir_config & 0x0001;
-               ir_inversion[i] = ir_config & 0x8000 ? 1 : 0;
-               if (ir_config & 0x4000)
-                       ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f);
-               else
-                       ir_device_mask[i] = IR_ALL;
-               /* update configuration */
-               av7110_check_ir_config(av_list[i], false);
-               input_register_keys(&av_list[i]->ir);
-       }
-       vfree(page);
-       return count;
-}
-
-static const struct file_operations av7110_ir_proc_fops = {
-       .owner          = THIS_MODULE,
-       .write          = av7110_ir_proc_write,
-       .llseek         = noop_llseek,
-};
-
-/* interrupt handler */
-static void ir_handler(struct av7110 *av7110, u32 ircom)
-{
-       dprintk(4, "ir command = %08x\n", ircom);
-       av7110->ir.ir_command = ircom;
-       tasklet_schedule(&av7110->ir.ir_tasklet);
-}
-
-
-int __devinit av7110_ir_init(struct av7110 *av7110)
-{
-       struct input_dev *input_dev;
-       static struct proc_dir_entry *e;
-       int err;
-
-       if (av_cnt >= ARRAY_SIZE(av_list))
-               return -ENOSPC;
-
-       av_list[av_cnt++] = av7110;
-       av7110_check_ir_config(av7110, true);
-
-       init_timer(&av7110->ir.keyup_timer);
-       av7110->ir.keyup_timer.function = av7110_emit_keyup;
-       av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir;
-
-       input_dev = input_allocate_device();
-       if (!input_dev)
-               return -ENOMEM;
-
-       av7110->ir.input_dev = input_dev;
-       snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
-               "pci-%s/ir0", pci_name(av7110->dev->pci));
-
-       input_dev->name = "DVB on-card IR receiver";
-
-       input_dev->phys = av7110->ir.input_phys;
-       input_dev->id.bustype = BUS_PCI;
-       input_dev->id.version = 2;
-       if (av7110->dev->pci->subsystem_vendor) {
-               input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
-               input_dev->id.product = av7110->dev->pci->subsystem_device;
-       } else {
-               input_dev->id.vendor = av7110->dev->pci->vendor;
-               input_dev->id.product = av7110->dev->pci->device;
-       }
-       input_dev->dev.parent = &av7110->dev->pci->dev;
-       /* initial keymap */
-       memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map);
-       input_register_keys(&av7110->ir);
-       err = input_register_device(input_dev);
-       if (err) {
-               input_free_device(input_dev);
-               return err;
-       }
-       input_dev->timer.function = input_repeat_key;
-       input_dev->timer.data = (unsigned long) &av7110->ir;
-
-       if (av_cnt == 1) {
-               e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
-               if (e)
-                       e->size = 4 + 256 * sizeof(u16);
-       }
-
-       tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
-       av7110->ir.ir_handler = ir_handler;
-
-       return 0;
-}
-
-
-void __devexit av7110_ir_exit(struct av7110 *av7110)
-{
-       int i;
-
-       if (av_cnt == 0)
-               return;
-
-       del_timer_sync(&av7110->ir.keyup_timer);
-       av7110->ir.ir_handler = NULL;
-       tasklet_kill(&av7110->ir.ir_tasklet);
-
-       for (i = 0; i < av_cnt; i++)
-               if (av_list[i] == av7110) {
-                       av_list[i] = av_list[av_cnt-1];
-                       av_list[av_cnt-1] = NULL;
-                       break;
-               }
-
-       if (av_cnt == 1)
-               remove_proc_entry("av7110_ir", NULL);
-
-       input_unregister_device(av7110->ir.input_dev);
-
-       av_cnt--;
-}
-
-//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
-//MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
deleted file mode 100644 (file)
index 1b2d151..0000000
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * originally based on code by:
- * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/timer.h>
-#include <linux/poll.h>
-
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "av7110_av.h"
-
-int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
-{
-       u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
-       struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg };
-
-       switch (av7110->adac_type) {
-       case DVB_ADAC_MSP34x0:
-               msgs.addr = 0x40;
-               break;
-       case DVB_ADAC_MSP34x5:
-               msgs.addr = 0x42;
-               break;
-       default:
-               return 0;
-       }
-
-       if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
-               dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
-                      av7110->dvb_adapter.num, reg, val);
-               return -EIO;
-       }
-       return 0;
-}
-
-static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
-{
-       u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
-       u8 msg2[2];
-       struct i2c_msg msgs[2] = {
-               { .flags = 0       , .len = 3, .buf = msg1 },
-               { .flags = I2C_M_RD, .len = 2, .buf = msg2 }
-       };
-
-       switch (av7110->adac_type) {
-       case DVB_ADAC_MSP34x0:
-               msgs[0].addr = 0x40;
-               msgs[1].addr = 0x40;
-               break;
-       case DVB_ADAC_MSP34x5:
-               msgs[0].addr = 0x42;
-               msgs[1].addr = 0x42;
-               break;
-       default:
-               return 0;
-       }
-
-       if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
-               dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
-                      av7110->dvb_adapter.num, reg);
-               return -EIO;
-       }
-       *val = (msg2[0] << 8) | msg2[1];
-       return 0;
-}
-
-static struct v4l2_input inputs[4] = {
-       {
-               .index          = 0,
-               .name           = "DVB",
-               .type           = V4L2_INPUT_TYPE_CAMERA,
-               .audioset       = 1,
-               .tuner          = 0, /* ignored */
-               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
-               .status         = 0,
-               .capabilities   = V4L2_IN_CAP_STD,
-       }, {
-               .index          = 1,
-               .name           = "Television",
-               .type           = V4L2_INPUT_TYPE_TUNER,
-               .audioset       = 1,
-               .tuner          = 0,
-               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
-               .status         = 0,
-               .capabilities   = V4L2_IN_CAP_STD,
-       }, {
-               .index          = 2,
-               .name           = "Video",
-               .type           = V4L2_INPUT_TYPE_CAMERA,
-               .audioset       = 0,
-               .tuner          = 0,
-               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
-               .status         = 0,
-               .capabilities   = V4L2_IN_CAP_STD,
-       }, {
-               .index          = 3,
-               .name           = "Y/C",
-               .type           = V4L2_INPUT_TYPE_CAMERA,
-               .audioset       = 0,
-               .tuner          = 0,
-               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
-               .status         = 0,
-               .capabilities   = V4L2_IN_CAP_STD,
-       }
-};
-
-static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
-{
-       struct av7110 *av7110 = dev->ext_priv;
-       u8 buf[] = { 0x00, reg, data };
-       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
-
-       dprintk(4, "dev: %p\n", dev);
-
-       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
-               return -1;
-       return 0;
-}
-
-static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
-{
-       struct av7110 *av7110 = dev->ext_priv;
-       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
-
-       dprintk(4, "dev: %p\n", dev);
-
-       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
-               return -1;
-       return 0;
-}
-
-static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
-{
-       u32 div;
-       u8 config;
-       u8 buf[4];
-
-       dprintk(4, "freq: 0x%08x\n", freq);
-
-       /* magic number: 614. tuning with the frequency given by v4l2
-          is always off by 614*62.5 = 38375 kHz...*/
-       div = freq + 614;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x8e;
-
-       if (freq < (u32) (16 * 168.25))
-               config = 0xa0;
-       else if (freq < (u32) (16 * 447.25))
-               config = 0x90;
-       else
-               config = 0x30;
-       config &= ~0x02;
-
-       buf[3] = config;
-
-       return tuner_write(dev, 0x61, buf);
-}
-
-static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
-{
-       struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
-       u32 div;
-       u8 data[4];
-
-       div = (freq + 38900000 + 31250) / 62500;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0xce;
-
-       if (freq < 45000000)
-               return -EINVAL;
-       else if (freq < 137000000)
-               data[3] = 0x01;
-       else if (freq < 403000000)
-               data[3] = 0x02;
-       else if (freq < 860000000)
-               data[3] = 0x04;
-       else
-               return -EINVAL;
-
-       if (av7110->fe->ops.i2c_gate_ctrl)
-               av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1);
-       return tuner_write(dev, 0x63, data);
-}
-
-
-
-static struct saa7146_standard analog_standard[];
-static struct saa7146_standard dvb_standard[];
-static struct saa7146_standard standard[];
-
-static struct v4l2_audio msp3400_v4l2_audio = {
-       .index = 0,
-       .name = "Television",
-       .capability = V4L2_AUDCAP_STEREO
-};
-
-static int av7110_dvb_c_switch(struct saa7146_fh *fh)
-{
-       struct saa7146_dev *dev = fh->dev;
-       struct saa7146_vv *vv = dev->vv_data;
-       struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
-       u16 adswitch;
-       int source, sync, err;
-
-       dprintk(4, "%p\n", av7110);
-
-       if ((vv->video_status & STATUS_OVERLAY) != 0) {
-               vv->ov_suspend = vv->video_fh;
-               err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
-               if (err != 0) {
-                       dprintk(2, "suspending video failed\n");
-                       vv->ov_suspend = NULL;
-               }
-       }
-
-       if (0 != av7110->current_input) {
-               dprintk(1, "switching to analog TV:\n");
-               adswitch = 1;
-               source = SAA7146_HPS_SOURCE_PORT_B;
-               sync = SAA7146_HPS_SYNC_PORT_B;
-               memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
-
-               switch (av7110->current_input) {
-               case 1:
-                       dprintk(1, "switching SAA7113 to Analog Tuner Input\n");
-                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
-                       msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
-                       msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
-                       msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
-                       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
-                       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
-
-                       if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
-                               if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
-                                       dprintk(1, "setting band in demodulator failed\n");
-                       } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-                               saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD)
-                               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF)
-                       }
-                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
-                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
-                       break;
-               case 2:
-                       dprintk(1, "switching SAA7113 to Video AV CVBS Input\n");
-                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
-                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
-                       break;
-               case 3:
-                       dprintk(1, "switching SAA7113 to Video AV Y/C Input\n");
-                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
-                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
-                       break;
-               default:
-                       dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input\n");
-               }
-       } else {
-               adswitch = 0;
-               source = SAA7146_HPS_SOURCE_PORT_A;
-               sync = SAA7146_HPS_SYNC_PORT_A;
-               memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
-               dprintk(1, "switching DVB mode\n");
-               msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
-               msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
-               msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
-               msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
-               msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
-               msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
-
-               if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
-                       if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
-                               dprintk(1, "setting band in demodulator failed\n");
-               } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
-                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
-               }
-       }
-
-       /* hmm, this does not do anything!? */
-       if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
-               dprintk(1, "ADSwitch error\n");
-
-       saa7146_set_hps_source_and_sync(dev, source, sync);
-
-       if (vv->ov_suspend != NULL) {
-               saa7146_start_preview(vv->ov_suspend);
-               vv->ov_suspend = NULL;
-       }
-
-       return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-       u16 stereo_det;
-       s8 stereo;
-
-       dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
-
-       if (!av7110->analog_tuner_flags || t->index != 0)
-               return -EINVAL;
-
-       memset(t, 0, sizeof(*t));
-       strcpy((char *)t->name, "Television");
-
-       t->type = V4L2_TUNER_ANALOG_TV;
-       t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
-               V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-       t->rangelow = 772;      /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
-       t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
-       /* FIXME: add the real signal strength here */
-       t->signal = 0xffff;
-       t->afc = 0;
-
-       /* FIXME: standard / stereo detection is still broken */
-       msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
-       dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
-       msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
-       dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
-       stereo = (s8)(stereo_det >> 8);
-       if (stereo > 0x10) {
-               /* stereo */
-               t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
-               t->audmode = V4L2_TUNER_MODE_STEREO;
-       } else if (stereo < -0x10) {
-               /* bilingual */
-               t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-               t->audmode = V4L2_TUNER_MODE_LANG1;
-       } else /* mono */
-               t->rxsubchans = V4L2_TUNER_SUB_MONO;
-
-       return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-       u16 fm_matrix, src;
-       dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
-
-       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-               return -EINVAL;
-
-       switch (t->audmode) {
-       case V4L2_TUNER_MODE_STEREO:
-               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
-               fm_matrix = 0x3001; /* stereo */
-               src = 0x0020;
-               break;
-       case V4L2_TUNER_MODE_LANG1_LANG2:
-               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
-               fm_matrix = 0x3000; /* bilingual */
-               src = 0x0020;
-               break;
-       case V4L2_TUNER_MODE_LANG1:
-               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
-               fm_matrix = 0x3000; /* mono */
-               src = 0x0000;
-               break;
-       case V4L2_TUNER_MODE_LANG2:
-               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
-               fm_matrix = 0x3000; /* mono */
-               src = 0x0010;
-               break;
-       default: /* case V4L2_TUNER_MODE_MONO: */
-               dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
-               fm_matrix = 0x3000; /* mono */
-               src = 0x0030;
-               break;
-       }
-       msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
-       msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
-       msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
-       msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
-       return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency);
-
-       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-               return -EINVAL;
-
-       memset(f, 0, sizeof(*f));
-       f->type = V4L2_TUNER_ANALOG_TV;
-       f->frequency =  av7110->current_freq;
-       return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency);
-
-       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-               return -EINVAL;
-
-       if (V4L2_TUNER_ANALOG_TV != f->type)
-               return -EINVAL;
-
-       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
-       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
-
-       /* tune in desired frequency */
-       if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
-               ves1820_set_tv_freq(dev, f->frequency);
-       else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
-               stv0297_set_tv_freq(dev, f->frequency);
-       av7110->current_freq = f->frequency;
-
-       msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
-       msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
-       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
-       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
-       return 0;
-}
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
-
-       if (av7110->analog_tuner_flags) {
-               if (i->index >= 4)
-                       return -EINVAL;
-       } else {
-               if (i->index != 0)
-                       return -EINVAL;
-       }
-
-       memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
-
-       return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       *input = av7110->current_input;
-       dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
-       return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
-
-       if (!av7110->analog_tuner_flags)
-               return input ? -EINVAL : 0;
-
-       if (input >= 4)
-               return -EINVAL;
-
-       av7110->current_input = input;
-       return av7110_dvb_c_switch(fh);
-}
-
-static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
-{
-       dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
-       if (a->index != 0)
-               return -EINVAL;
-       *a = msp3400_v4l2_audio;
-       return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
-       if (a->index != 0)
-               return -EINVAL;
-       if (av7110->current_input >= 2)
-               return -EINVAL;
-       *a = msp3400_v4l2_audio;
-       return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
-       if (av7110->current_input >= 2)
-               return -EINVAL;
-       return a->index ? -EINVAL : 0;
-}
-
-static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
-                                       struct v4l2_sliced_vbi_cap *cap)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
-       if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
-               return -EINVAL;
-       if (FW_VERSION(av7110->arm_app) >= 0x2623) {
-               cap->service_set = V4L2_SLICED_WSS_625;
-               cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
-       }
-       return 0;
-}
-
-static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
-                                       struct v4l2_format *f)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_G_FMT:\n");
-       if (FW_VERSION(av7110->arm_app) < 0x2623)
-               return -EINVAL;
-       memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
-       if (av7110->wssMode) {
-               f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
-               f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
-               f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
-       }
-       return 0;
-}
-
-static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
-                                       struct v4l2_format *f)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
-
-       dprintk(2, "VIDIOC_S_FMT\n");
-       if (FW_VERSION(av7110->arm_app) < 0x2623)
-               return -EINVAL;
-       if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
-           f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
-               memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
-               /* WSS controlled by firmware */
-               av7110->wssMode = 0;
-               av7110->wssData = 0;
-               return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
-                                    SetWSSConfig, 1, 0);
-       } else {
-               memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
-               f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
-               f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
-               f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
-               /* WSS controlled by userspace */
-               av7110->wssMode = 1;
-               av7110->wssData = 0;
-       }
-       return 0;
-}
-
-static int av7110_vbi_reset(struct file *file)
-{
-       struct saa7146_fh *fh = file->private_data;
-       struct saa7146_dev *dev = fh->dev;
-       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
-
-       dprintk(2, "%s\n", __func__);
-       av7110->wssMode = 0;
-       av7110->wssData = 0;
-       if (FW_VERSION(av7110->arm_app) < 0x2623)
-               return 0;
-       else
-               return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
-}
-
-static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
-{
-       struct saa7146_fh *fh = file->private_data;
-       struct saa7146_dev *dev = fh->dev;
-       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
-       struct v4l2_sliced_vbi_data d;
-       int rc;
-
-       dprintk(2, "%s\n", __func__);
-       if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
-               return -EINVAL;
-       if (copy_from_user(&d, data, count))
-               return -EFAULT;
-       if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
-               return -EINVAL;
-       if (d.id)
-               av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
-       else
-               av7110->wssData = 0x8000;
-       rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData);
-       return (rc < 0) ? rc : count;
-}
-
-/****************************************************************************
- * INITIALIZATION
- ****************************************************************************/
-
-static u8 saa7113_init_regs[] = {
-       0x02, 0xd0,
-       0x03, 0x23,
-       0x04, 0x00,
-       0x05, 0x00,
-       0x06, 0xe9,
-       0x07, 0x0d,
-       0x08, 0x98,
-       0x09, 0x02,
-       0x0a, 0x80,
-       0x0b, 0x40,
-       0x0c, 0x40,
-       0x0d, 0x00,
-       0x0e, 0x01,
-       0x0f, 0x7c,
-       0x10, 0x48,
-       0x11, 0x0c,
-       0x12, 0x8b,
-       0x13, 0x1a,
-       0x14, 0x00,
-       0x15, 0x00,
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1b, 0x00,
-       0x1c, 0x00,
-       0x1d, 0x00,
-       0x1e, 0x00,
-
-       0x41, 0x77,
-       0x42, 0x77,
-       0x43, 0x77,
-       0x44, 0x77,
-       0x45, 0x77,
-       0x46, 0x77,
-       0x47, 0x77,
-       0x48, 0x77,
-       0x49, 0x77,
-       0x4a, 0x77,
-       0x4b, 0x77,
-       0x4c, 0x77,
-       0x4d, 0x77,
-       0x4e, 0x77,
-       0x4f, 0x77,
-       0x50, 0x77,
-       0x51, 0x77,
-       0x52, 0x77,
-       0x53, 0x77,
-       0x54, 0x77,
-       0x55, 0x77,
-       0x56, 0x77,
-       0x57, 0xff,
-
-       0xff
-};
-
-
-static struct saa7146_ext_vv av7110_vv_data_st;
-static struct saa7146_ext_vv av7110_vv_data_c;
-
-int av7110_init_analog_module(struct av7110 *av7110)
-{
-       u16 version1, version2;
-
-       if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 &&
-           i2c_writereg(av7110, 0x80, 0x0, 0) == 1) {
-               pr_info("DVB-C analog module @ card %d detected, initializing MSP3400\n",
-                       av7110->dvb_adapter.num);
-               av7110->adac_type = DVB_ADAC_MSP34x0;
-       } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 &&
-                  i2c_writereg(av7110, 0x84, 0x0, 0) == 1) {
-               pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n",
-                       av7110->dvb_adapter.num);
-               av7110->adac_type = DVB_ADAC_MSP34x5;
-       } else
-               return -ENODEV;
-
-       msleep(100); // the probing above resets the msp...
-       msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
-       msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
-       dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n",
-               av7110->dvb_adapter.num, version1, version2);
-       msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
-       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
-       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
-       msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
-       msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
-       msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
-       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
-       msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART
-
-       if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
-               pr_info("saa7113 not accessible\n");
-       } else {
-               u8 *i = saa7113_init_regs;
-
-               if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
-                       /* Fujitsu/Siemens DVB-Cable */
-                       av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
-               } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
-                       /* Hauppauge/TT DVB-C premium */
-                       av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
-               } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
-                       /* Hauppauge/TT DVB-C premium */
-                       av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
-               }
-
-               /* setup for DVB by default */
-               if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
-                       if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
-                               dprintk(1, "setting band in demodulator failed\n");
-               } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-                       saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
-                       saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
-               }
-
-               /* init the saa7113 */
-               while (*i != 0xff) {
-                       if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
-                               dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
-                               break;
-                       }
-                       i += 2;
-               }
-               /* setup msp for analog sound: B/G Dual-FM */
-               msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
-               msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
-               msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
-               msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
-               msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
-               msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
-               msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
-       }
-
-       memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
-       /* set dd1 stream a & b */
-       saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
-       saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
-       saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
-       return 0;
-}
-
-int av7110_init_v4l(struct av7110 *av7110)
-{
-       struct saa7146_dev* dev = av7110->dev;
-       struct saa7146_ext_vv *vv_data;
-       int ret;
-
-       /* special case DVB-C: these cards have an analog tuner
-          plus need some special handling, so we have separate
-          saa7146_ext_vv data for these... */
-       if (av7110->analog_tuner_flags)
-               vv_data = &av7110_vv_data_c;
-       else
-               vv_data = &av7110_vv_data_st;
-       ret = saa7146_vv_init(dev, vv_data);
-
-       if (ret) {
-               ERR("cannot init capture device. skipping\n");
-               return -ENODEV;
-       }
-       vv_data->vid_ops.vidioc_enum_input = vidioc_enum_input;
-       vv_data->vid_ops.vidioc_g_input = vidioc_g_input;
-       vv_data->vid_ops.vidioc_s_input = vidioc_s_input;
-       vv_data->vid_ops.vidioc_g_tuner = vidioc_g_tuner;
-       vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner;
-       vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency;
-       vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency;
-       vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio;
-       vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio;
-       vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio;
-       vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL;
-
-       vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner;
-       vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner;
-       vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency;
-       vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency;
-       vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL;
-       vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
-       vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
-       vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
-
-       if (FW_VERSION(av7110->arm_app) < 0x2623)
-               vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
-
-       if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
-               ERR("cannot register capture device. skipping\n");
-               saa7146_vv_release(dev);
-               return -ENODEV;
-       }
-       if (FW_VERSION(av7110->arm_app) >= 0x2623) {
-               if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
-                       ERR("cannot register vbi v4l2 device. skipping\n");
-       }
-       return 0;
-}
-
-int av7110_exit_v4l(struct av7110 *av7110)
-{
-       struct saa7146_dev* dev = av7110->dev;
-
-       saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
-       saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
-
-       saa7146_vv_release(dev);
-
-       return 0;
-}
-
-
-
-/* FIXME: these values are experimental values that look better than the
-   values from the latest "official" driver -- at least for me... (MiHu) */
-static struct saa7146_standard standard[] = {
-       {
-               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
-               .v_offset       = 0x15, .v_field        = 288,
-               .h_offset       = 0x48, .h_pixels       = 708,
-               .v_max_out      = 576,  .h_max_out      = 768,
-       }, {
-               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
-               .v_offset       = 0x10, .v_field        = 244,
-               .h_offset       = 0x40, .h_pixels       = 708,
-               .v_max_out      = 480,  .h_max_out      = 640,
-       }
-};
-
-static struct saa7146_standard analog_standard[] = {
-       {
-               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
-               .v_offset       = 0x1b, .v_field        = 288,
-               .h_offset       = 0x08, .h_pixels       = 708,
-               .v_max_out      = 576,  .h_max_out      = 768,
-       }, {
-               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
-               .v_offset       = 0x10, .v_field        = 244,
-               .h_offset       = 0x40, .h_pixels       = 708,
-               .v_max_out      = 480,  .h_max_out      = 640,
-       }
-};
-
-static struct saa7146_standard dvb_standard[] = {
-       {
-               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
-               .v_offset       = 0x14, .v_field        = 288,
-               .h_offset       = 0x48, .h_pixels       = 708,
-               .v_max_out      = 576,  .h_max_out      = 768,
-       }, {
-               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
-               .v_offset       = 0x10, .v_field        = 244,
-               .h_offset       = 0x40, .h_pixels       = 708,
-               .v_max_out      = 480,  .h_max_out      = 640,
-       }
-};
-
-static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
-{
-       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
-
-       if (std->id & V4L2_STD_PAL) {
-               av7110->vidmode = AV7110_VIDEO_MODE_PAL;
-               av7110_set_vidmode(av7110, av7110->vidmode);
-       }
-       else if (std->id & V4L2_STD_NTSC) {
-               av7110->vidmode = AV7110_VIDEO_MODE_NTSC;
-               av7110_set_vidmode(av7110, av7110->vidmode);
-       }
-       else
-               return -1;
-
-       return 0;
-}
-
-
-static struct saa7146_ext_vv av7110_vv_data_st = {
-       .inputs         = 1,
-       .audios         = 1,
-       .capabilities   = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
-       .flags          = 0,
-
-       .stds           = &standard[0],
-       .num_stds       = ARRAY_SIZE(standard),
-       .std_callback   = &std_callback,
-
-       .vbi_fops.open  = av7110_vbi_reset,
-       .vbi_fops.release = av7110_vbi_reset,
-       .vbi_fops.write = av7110_vbi_write,
-};
-
-static struct saa7146_ext_vv av7110_vv_data_c = {
-       .inputs         = 1,
-       .audios         = 1,
-       .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
-       .flags          = SAA7146_USE_PORT_B_FOR_VBI,
-
-       .stds           = &standard[0],
-       .num_stds       = ARRAY_SIZE(standard),
-       .std_callback   = &std_callback,
-
-       .vbi_fops.open  = av7110_vbi_reset,
-       .vbi_fops.release = av7110_vbi_reset,
-       .vbi_fops.write = av7110_vbi_write,
-};
-
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
deleted file mode 100644 (file)
index 12ddb53..0000000
+++ /dev/null
@@ -1,1640 +0,0 @@
-/*
- * budget-av.c: driver for the SAA7146 based Budget DVB cards
- *              with analog video in
- *
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
- *                               Andrew de Quincey <adq_dvb@lidskialf.net>
- *
- * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "budget.h"
-#include "stv0299.h"
-#include "stb0899_drv.h"
-#include "stb0899_reg.h"
-#include "stb0899_cfg.h"
-#include "tda8261.h"
-#include "tda8261_cfg.h"
-#include "tda1002x.h"
-#include "tda1004x.h"
-#include "tua6100.h"
-#include "dvb-pll.h"
-#include <media/saa7146_vv.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/spinlock.h>
-
-#include "dvb_ca_en50221.h"
-
-#define DEBICICAM              0x02420000
-
-#define SLOTSTATUS_NONE         1
-#define SLOTSTATUS_PRESENT      2
-#define SLOTSTATUS_RESET        4
-#define SLOTSTATUS_READY        8
-#define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct budget_av {
-       struct budget budget;
-       struct video_device *vd;
-       int cur_input;
-       int has_saa7113;
-       struct tasklet_struct ciintf_irq_tasklet;
-       int slot_status;
-       struct dvb_ca_en50221 ca;
-       u8 reinitialise_demod:1;
-};
-
-static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
-
-
-/* GPIO Connections:
- * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
- * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
- * 2 - CI Card Enable (Active Low)
- * 3 - CI Card Detect
- */
-
-/****************************************************************************
- * INITIALIZATION
- ****************************************************************************/
-
-static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
-{
-       u8 mm1[] = { 0x00 };
-       u8 mm2[] = { 0x00 };
-       struct i2c_msg msgs[2];
-
-       msgs[0].flags = 0;
-       msgs[1].flags = I2C_M_RD;
-       msgs[0].addr = msgs[1].addr = id / 2;
-       mm1[0] = reg;
-       msgs[0].len = 1;
-       msgs[1].len = 1;
-       msgs[0].buf = mm1;
-       msgs[1].buf = mm2;
-
-       i2c_transfer(i2c, msgs, 2);
-
-       return mm2[0];
-}
-
-static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
-{
-       u8 mm1[] = { reg };
-       struct i2c_msg msgs[2] = {
-               {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
-               {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
-       };
-
-       if (i2c_transfer(i2c, msgs, 2) != 2)
-               return -EIO;
-
-       return 0;
-}
-
-static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
-{
-       u8 msg[2] = { reg, val };
-       struct i2c_msg msgs;
-
-       msgs.flags = 0;
-       msgs.addr = id / 2;
-       msgs.len = 2;
-       msgs.buf = msg;
-       return i2c_transfer(i2c, &msgs, 1);
-}
-
-static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       int result;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
-       udelay(1);
-
-       result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
-       if (result == -ETIMEDOUT) {
-               ciintf_slot_shutdown(ca, slot);
-               pr_info("cam ejected 1\n");
-       }
-       return result;
-}
-
-static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       int result;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
-       udelay(1);
-
-       result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
-       if (result == -ETIMEDOUT) {
-               ciintf_slot_shutdown(ca, slot);
-               pr_info("cam ejected 2\n");
-       }
-       return result;
-}
-
-static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       int result;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
-       udelay(1);
-
-       result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
-       if (result == -ETIMEDOUT) {
-               ciintf_slot_shutdown(ca, slot);
-               pr_info("cam ejected 3\n");
-               return -ETIMEDOUT;
-       }
-       return result;
-}
-
-static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       int result;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
-       udelay(1);
-
-       result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
-       if (result == -ETIMEDOUT) {
-               ciintf_slot_shutdown(ca, slot);
-               pr_info("cam ejected 5\n");
-       }
-       return result;
-}
-
-static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       struct saa7146_dev *saa = budget_av->budget.dev;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       dprintk(1, "ciintf_slot_reset\n");
-       budget_av->slot_status = SLOTSTATUS_RESET;
-
-       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
-
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
-       msleep(2);
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
-       msleep(20); /* 20 ms Vcc settling time */
-
-       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
-       msleep(20);
-
-       /* reinitialise the frontend if necessary */
-       if (budget_av->reinitialise_demod)
-               dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
-
-       return 0;
-}
-
-static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       struct saa7146_dev *saa = budget_av->budget.dev;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       dprintk(1, "ciintf_slot_shutdown\n");
-
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
-       budget_av->slot_status = SLOTSTATUS_NONE;
-
-       return 0;
-}
-
-static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       struct saa7146_dev *saa = budget_av->budget.dev;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
-
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
-
-       return 0;
-}
-
-static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-       struct budget_av *budget_av = (struct budget_av *) ca->data;
-       struct saa7146_dev *saa = budget_av->budget.dev;
-       int result;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       /* test the card detect line - needs to be done carefully
-        * since it never goes high for some CAMs on this interface (e.g. topuptv) */
-       if (budget_av->slot_status == SLOTSTATUS_NONE) {
-               saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
-               udelay(1);
-               if (saa7146_read(saa, PSR) & MASK_06) {
-                       if (budget_av->slot_status == SLOTSTATUS_NONE) {
-                               budget_av->slot_status = SLOTSTATUS_PRESENT;
-                               pr_info("cam inserted A\n");
-                       }
-               }
-               saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
-       }
-
-       /* We also try and read from IO memory to work round the above detection bug. If
-        * there is no CAM, we will get a timeout. Only done if there is no cam
-        * present, since this test actually breaks some cams :(
-        *
-        * if the CI interface is not open, we also do the above test since we
-        * don't care if the cam has problems - we'll be resetting it on open() anyway */
-       if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
-               saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
-               result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
-               if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
-                       budget_av->slot_status = SLOTSTATUS_PRESENT;
-                       pr_info("cam inserted B\n");
-               } else if (result < 0) {
-                       if (budget_av->slot_status != SLOTSTATUS_NONE) {
-                               ciintf_slot_shutdown(ca, slot);
-                               pr_info("cam ejected 5\n");
-                               return 0;
-                       }
-               }
-       }
-
-       /* read from attribute memory in reset/ready state to know when the CAM is ready */
-       if (budget_av->slot_status == SLOTSTATUS_RESET) {
-               result = ciintf_read_attribute_mem(ca, slot, 0);
-               if (result == 0x1d) {
-                       budget_av->slot_status = SLOTSTATUS_READY;
-               }
-       }
-
-       /* work out correct return code */
-       if (budget_av->slot_status != SLOTSTATUS_NONE) {
-               if (budget_av->slot_status & SLOTSTATUS_READY) {
-                       return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
-               }
-               return DVB_CA_EN50221_POLL_CAM_PRESENT;
-       }
-       return 0;
-}
-
-static int ciintf_init(struct budget_av *budget_av)
-{
-       struct saa7146_dev *saa = budget_av->budget.dev;
-       int result;
-
-       memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
-
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
-       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
-       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
-
-       /* Enable DEBI pins */
-       saa7146_write(saa, MC1, MASK_27 | MASK_11);
-
-       /* register CI interface */
-       budget_av->ca.owner = THIS_MODULE;
-       budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
-       budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
-       budget_av->ca.read_cam_control = ciintf_read_cam_control;
-       budget_av->ca.write_cam_control = ciintf_write_cam_control;
-       budget_av->ca.slot_reset = ciintf_slot_reset;
-       budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
-       budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
-       budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
-       budget_av->ca.data = budget_av;
-       budget_av->budget.ci_present = 1;
-       budget_av->slot_status = SLOTSTATUS_NONE;
-
-       if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
-                                         &budget_av->ca, 0, 1)) != 0) {
-               pr_err("ci initialisation failed\n");
-               goto error;
-       }
-
-       pr_info("ci interface initialised\n");
-       return 0;
-
-error:
-       saa7146_write(saa, MC1, MASK_27);
-       return result;
-}
-
-static void ciintf_deinit(struct budget_av *budget_av)
-{
-       struct saa7146_dev *saa = budget_av->budget.dev;
-
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
-       saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
-       saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
-
-       /* release the CA device */
-       dvb_ca_en50221_release(&budget_av->ca);
-
-       /* disable DEBI pins */
-       saa7146_write(saa, MC1, MASK_27);
-}
-
-
-static const u8 saa7113_tab[] = {
-       0x01, 0x08,
-       0x02, 0xc0,
-       0x03, 0x33,
-       0x04, 0x00,
-       0x05, 0x00,
-       0x06, 0xeb,
-       0x07, 0xe0,
-       0x08, 0x28,
-       0x09, 0x00,
-       0x0a, 0x80,
-       0x0b, 0x47,
-       0x0c, 0x40,
-       0x0d, 0x00,
-       0x0e, 0x01,
-       0x0f, 0x44,
-
-       0x10, 0x08,
-       0x11, 0x0c,
-       0x12, 0x7b,
-       0x13, 0x00,
-       0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
-
-       0x57, 0xff,
-       0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
-       0x5b, 0x83, 0x5e, 0x00,
-       0xff
-};
-
-static int saa7113_init(struct budget_av *budget_av)
-{
-       struct budget *budget = &budget_av->budget;
-       struct saa7146_dev *saa = budget->dev;
-       const u8 *data = saa7113_tab;
-
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
-       msleep(200);
-
-       if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
-               dprintk(1, "saa7113 not found on KNC card\n");
-               return -ENODEV;
-       }
-
-       dprintk(1, "saa7113 detected and initializing\n");
-
-       while (*data != 0xff) {
-               i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
-               data += 2;
-       }
-
-       dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
-
-       return 0;
-}
-
-static int saa7113_setinput(struct budget_av *budget_av, int input)
-{
-       struct budget *budget = &budget_av->budget;
-
-       if (1 != budget_av->has_saa7113)
-               return -ENODEV;
-
-       if (input == 1) {
-               i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
-               i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
-       } else if (input == 0) {
-               i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
-               i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
-       } else
-               return -EINVAL;
-
-       budget_av->cur_input = input;
-       return 0;
-}
-
-
-static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-       u8 m1;
-
-       aclk = 0xb5;
-       if (srate < 2000000)
-               bclk = 0x86;
-       else if (srate < 5000000)
-               bclk = 0x89;
-       else if (srate < 15000000)
-               bclk = 0x8f;
-       else if (srate < 45000000)
-               bclk = 0x95;
-
-       m1 = 0x14;
-       if (srate < 4000000)
-               m1 = 0x10;
-
-       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);
-       stv0299_writereg(fe, 0x0f, 0x80 | m1);
-
-       return 0;
-}
-
-static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 div;
-       u8 buf[4];
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
-
-       if ((c->frequency < 950000) || (c->frequency > 2150000))
-               return -EINVAL;
-
-       div = (c->frequency + (125 - 1)) / 125; /* round correctly */
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       buf[3] = 0x20;
-
-       if (c->symbol_rate < 4000000)
-               buf[3] |= 1;
-
-       if (c->frequency < 1250000)
-               buf[3] |= 0;
-       else if (c->frequency < 1550000)
-               buf[3] |= 0x40;
-       else if (c->frequency < 2050000)
-               buf[3] |= 0x80;
-       else if (c->frequency < 2150000)
-               buf[3] |= 0xC0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static u8 typhoon_cinergy1200s_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,             /* DAC not used, set to high impendance mode */
-       0x07, 0x00,             /* DAC LSB */
-       0x08, 0x40,             /* DiSEqC off */
-       0x09, 0x00,             /* FIFO */
-       0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,             // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,             // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,             // 1/2 threshold
-       0x2a, 0x14,             // 2/3 threshold
-       0x2b, 0x0f,             // 3/4 threshold
-       0x2c, 0x09,             // 5/6 threshold
-       0x2d, 0x05,             // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,             // test all FECs
-       0x32, 0x19,             // viterbi and synchro search
-       0x33, 0xfc,             // rs control
-       0x34, 0x93,             // error control
-       0x0f, 0x92,
-       0xff, 0xff
-};
-
-static struct stv0299_config typhoon_config = {
-       .demod_address = 0x68,
-       .inittab = typhoon_cinergy1200s_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
-};
-
-
-static struct stv0299_config cinergy_1200s_config = {
-       .demod_address = 0x68,
-       .inittab = typhoon_cinergy1200s_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_0,
-       .volt13_op0_op1 = STV0299_VOLT13_OP0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
-};
-
-static struct stv0299_config cinergy_1200s_1894_0010_config = {
-       .demod_address = 0x68,
-       .inittab = typhoon_cinergy1200s_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
-};
-
-static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-       u8 buf[6];
-       struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
-       int i;
-
-#define CU1216_IF 36125000
-#define TUNER_MUL 62500
-
-       u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0xce;
-       buf[3] = (c->frequency < 150000000 ? 0x01 :
-                 c->frequency < 445000000 ? 0x02 : 0x04);
-       buf[4] = 0xde;
-       buf[5] = 0x20;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-
-       /* wait for the pll lock */
-       msg.flags = I2C_M_RD;
-       msg.len = 1;
-       for (i = 0; i < 20; i++) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
-                       break;
-               msleep(10);
-       }
-
-       /* switch the charge pump to the lower current */
-       msg.flags = 0;
-       msg.len = 2;
-       msg.buf = &buf[2];
-       buf[2] &= ~0x40;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-static struct tda1002x_config philips_cu1216_config = {
-       .demod_address = 0x0c,
-       .invert = 1,
-};
-
-static struct tda1002x_config philips_cu1216_config_altaddress = {
-       .demod_address = 0x0d,
-       .invert = 0,
-};
-
-static struct tda10023_config philips_cu1216_tda10023_config = {
-       .demod_address = 0x0c,
-       .invert = 1,
-};
-
-static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
-{
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-       static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
-       struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
-
-       // setup PLL configuration
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-       msleep(1);
-
-       return 0;
-}
-
-static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-       u8 tuner_buf[4];
-       struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
-                       sizeof(tuner_buf) };
-       int tuner_frequency = 0;
-       u8 band, cp, filter;
-
-       // determine charge pump
-       tuner_frequency = c->frequency + 36166000;
-       if (tuner_frequency < 87000000)
-               return -EINVAL;
-       else if (tuner_frequency < 130000000)
-               cp = 3;
-       else if (tuner_frequency < 160000000)
-               cp = 5;
-       else if (tuner_frequency < 200000000)
-               cp = 6;
-       else if (tuner_frequency < 290000000)
-               cp = 3;
-       else if (tuner_frequency < 420000000)
-               cp = 5;
-       else if (tuner_frequency < 480000000)
-               cp = 6;
-       else if (tuner_frequency < 620000000)
-               cp = 3;
-       else if (tuner_frequency < 830000000)
-               cp = 5;
-       else if (tuner_frequency < 895000000)
-               cp = 7;
-       else
-               return -EINVAL;
-
-       // determine band
-       if (c->frequency < 49000000)
-               return -EINVAL;
-       else if (c->frequency < 161000000)
-               band = 1;
-       else if (c->frequency < 444000000)
-               band = 2;
-       else if (c->frequency < 861000000)
-               band = 4;
-       else
-               return -EINVAL;
-
-       // setup PLL filter
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               filter = 0;
-               break;
-
-       case 7000000:
-               filter = 0;
-               break;
-
-       case 8000000:
-               filter = 1;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // calculate divisor
-       // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
-       tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
-
-       // setup tuner buffer
-       tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
-       tuner_buf[1] = tuner_frequency & 0xff;
-       tuner_buf[2] = 0xca;
-       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-
-       msleep(1);
-       return 0;
-}
-
-static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
-                                          const struct firmware **fw, char *name)
-{
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-
-       return request_firmware(fw, name, &budget->dev->pci->dev);
-}
-
-static struct tda1004x_config philips_tu1216_config = {
-
-       .demod_address = 0x8,
-       .invert = 1,
-       .invert_oclk = 1,
-       .xtal_freq = TDA10046_XTAL_4M,
-       .agc_config = TDA10046_AGC_DEFAULT,
-       .if_freq = TDA10046_FREQ_3617,
-       .request_firmware = philips_tu1216_request_firmware,
-};
-
-static u8 philips_sd1878_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,
-       0x05, 0x35,
-       0x06, 0x40,
-       0x07, 0x00,
-       0x08, 0x43,
-       0x09, 0x02,
-       0x0C, 0x51,
-       0x0D, 0x82,
-       0x0E, 0x23,
-       0x10, 0x3f,
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,
-       0x16, 0x19,
-       0x17, 0x8c,
-       0x18, 0x59,
-       0x19, 0xf8,
-       0x1a, 0xfe,
-       0x1c, 0x7f,
-       0x1d, 0x00,
-       0x1e, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,
-       0x29, 0x28,
-       0x2a, 0x14,
-       0x2b, 0x0f,
-       0x2c, 0x09,
-       0x2d, 0x09,
-       0x31, 0x1f,
-       0x32, 0x19,
-       0x33, 0xfc,
-       0x34, 0x93,
-       0xff, 0xff
-};
-
-static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
-               u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-       u8 m1;
-
-       aclk = 0xb5;
-       if (srate < 2000000)
-               bclk = 0x86;
-       else if (srate < 5000000)
-               bclk = 0x89;
-       else if (srate < 15000000)
-               bclk = 0x8f;
-       else if (srate < 45000000)
-               bclk = 0x95;
-
-       m1 = 0x14;
-       if (srate < 4000000)
-               m1 = 0x10;
-
-       stv0299_writereg(fe, 0x0e, 0x23);
-       stv0299_writereg(fe, 0x0f, 0x94);
-       stv0299_writereg(fe, 0x10, 0x39);
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x15, 0xc9);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
-       stv0299_writereg(fe, 0x0f, 0x80 | m1);
-
-       return 0;
-}
-
-static struct stv0299_config philips_sd1878_config = {
-       .demod_address = 0x68,
-     .inittab = philips_sd1878_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
-};
-
-/* KNC1 DVB-S (STB0899) Inittab        */
-static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
-
-       { STB0899_DEV_ID                , 0x81 },
-       { STB0899_DISCNTRL1             , 0x32 },
-       { STB0899_DISCNTRL2             , 0x80 },
-       { STB0899_DISRX_ST0             , 0x04 },
-       { STB0899_DISRX_ST1             , 0x00 },
-       { STB0899_DISPARITY             , 0x00 },
-       { STB0899_DISSTATUS             , 0x20 },
-       { STB0899_DISF22                , 0x8c },
-       { STB0899_DISF22RX              , 0x9a },
-       { STB0899_SYSREG                , 0x0b },
-       { STB0899_ACRPRESC              , 0x11 },
-       { STB0899_ACRDIV1               , 0x0a },
-       { STB0899_ACRDIV2               , 0x05 },
-       { STB0899_DACR1                 , 0x00 },
-       { STB0899_DACR2                 , 0x00 },
-       { STB0899_OUTCFG                , 0x00 },
-       { STB0899_MODECFG               , 0x00 },
-       { STB0899_IRQSTATUS_3           , 0x30 },
-       { STB0899_IRQSTATUS_2           , 0x00 },
-       { STB0899_IRQSTATUS_1           , 0x00 },
-       { STB0899_IRQSTATUS_0           , 0x00 },
-       { STB0899_IRQMSK_3              , 0xf3 },
-       { STB0899_IRQMSK_2              , 0xfc },
-       { STB0899_IRQMSK_1              , 0xff },
-       { STB0899_IRQMSK_0              , 0xff },
-       { STB0899_IRQCFG                , 0x00 },
-       { STB0899_I2CCFG                , 0x88 },
-       { STB0899_I2CRPT                , 0x58 }, /* Repeater=8, Stop=disabled */
-       { STB0899_IOPVALUE5             , 0x00 },
-       { STB0899_IOPVALUE4             , 0x20 },
-       { STB0899_IOPVALUE3             , 0xc9 },
-       { STB0899_IOPVALUE2             , 0x90 },
-       { STB0899_IOPVALUE1             , 0x40 },
-       { STB0899_IOPVALUE0             , 0x00 },
-       { STB0899_GPIO00CFG             , 0x82 },
-       { STB0899_GPIO01CFG             , 0x82 },
-       { STB0899_GPIO02CFG             , 0x82 },
-       { STB0899_GPIO03CFG             , 0x82 },
-       { STB0899_GPIO04CFG             , 0x82 },
-       { STB0899_GPIO05CFG             , 0x82 },
-       { STB0899_GPIO06CFG             , 0x82 },
-       { STB0899_GPIO07CFG             , 0x82 },
-       { STB0899_GPIO08CFG             , 0x82 },
-       { STB0899_GPIO09CFG             , 0x82 },
-       { STB0899_GPIO10CFG             , 0x82 },
-       { STB0899_GPIO11CFG             , 0x82 },
-       { STB0899_GPIO12CFG             , 0x82 },
-       { STB0899_GPIO13CFG             , 0x82 },
-       { STB0899_GPIO14CFG             , 0x82 },
-       { STB0899_GPIO15CFG             , 0x82 },
-       { STB0899_GPIO16CFG             , 0x82 },
-       { STB0899_GPIO17CFG             , 0x82 },
-       { STB0899_GPIO18CFG             , 0x82 },
-       { STB0899_GPIO19CFG             , 0x82 },
-       { STB0899_GPIO20CFG             , 0x82 },
-       { STB0899_SDATCFG               , 0xb8 },
-       { STB0899_SCLTCFG               , 0xba },
-       { STB0899_AGCRFCFG              , 0x08 }, /* 0x1c */
-       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
-       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
-       { STB0899_DIRCLKCFG             , 0x82 },
-       { STB0899_CLKOUT27CFG           , 0x7e },
-       { STB0899_STDBYCFG              , 0x82 },
-       { STB0899_CS0CFG                , 0x82 },
-       { STB0899_CS1CFG                , 0x82 },
-       { STB0899_DISEQCOCFG            , 0x20 },
-       { STB0899_GPIO32CFG             , 0x82 },
-       { STB0899_GPIO33CFG             , 0x82 },
-       { STB0899_GPIO34CFG             , 0x82 },
-       { STB0899_GPIO35CFG             , 0x82 },
-       { STB0899_GPIO36CFG             , 0x82 },
-       { STB0899_GPIO37CFG             , 0x82 },
-       { STB0899_GPIO38CFG             , 0x82 },
-       { STB0899_GPIO39CFG             , 0x82 },
-       { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-       { STB0899_FILTCTRL              , 0x00 },
-       { STB0899_SYSCTRL               , 0x00 },
-       { STB0899_STOPCLK1              , 0x20 },
-       { STB0899_STOPCLK2              , 0x00 },
-       { STB0899_INTBUFSTATUS          , 0x00 },
-       { STB0899_INTBUFCTRL            , 0x0a },
-       { 0xffff                        , 0xff },
-};
-
-static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
-       { STB0899_DEMOD                 , 0x00 },
-       { STB0899_RCOMPC                , 0xc9 },
-       { STB0899_AGC1CN                , 0x41 },
-       { STB0899_AGC1REF               , 0x08 },
-       { STB0899_RTC                   , 0x7a },
-       { STB0899_TMGCFG                , 0x4e },
-       { STB0899_AGC2REF               , 0x33 },
-       { STB0899_TLSR                  , 0x84 },
-       { STB0899_CFD                   , 0xee },
-       { STB0899_ACLC                  , 0x87 },
-       { STB0899_BCLC                  , 0x94 },
-       { STB0899_EQON                  , 0x41 },
-       { STB0899_LDT                   , 0xdd },
-       { STB0899_LDT2                  , 0xc9 },
-       { STB0899_EQUALREF              , 0xb4 },
-       { STB0899_TMGRAMP               , 0x10 },
-       { STB0899_TMGTHD                , 0x30 },
-       { STB0899_IDCCOMP               , 0xfb },
-       { STB0899_QDCCOMP               , 0x03 },
-       { STB0899_POWERI                , 0x3b },
-       { STB0899_POWERQ                , 0x3d },
-       { STB0899_RCOMP                 , 0x81 },
-       { STB0899_AGCIQIN               , 0x80 },
-       { STB0899_AGC2I1                , 0x04 },
-       { STB0899_AGC2I2                , 0xf5 },
-       { STB0899_TLIR                  , 0x25 },
-       { STB0899_RTF                   , 0x80 },
-       { STB0899_DSTATUS               , 0x00 },
-       { STB0899_LDI                   , 0xca },
-       { STB0899_CFRM                  , 0xf1 },
-       { STB0899_CFRL                  , 0xf3 },
-       { STB0899_NIRM                  , 0x2a },
-       { STB0899_NIRL                  , 0x05 },
-       { STB0899_ISYMB                 , 0x17 },
-       { STB0899_QSYMB                 , 0xfa },
-       { STB0899_SFRH                  , 0x2f },
-       { STB0899_SFRM                  , 0x68 },
-       { STB0899_SFRL                  , 0x40 },
-       { STB0899_SFRUPH                , 0x2f },
-       { STB0899_SFRUPM                , 0x68 },
-       { STB0899_SFRUPL                , 0x40 },
-       { STB0899_EQUAI1                , 0xfd },
-       { STB0899_EQUAQ1                , 0x04 },
-       { STB0899_EQUAI2                , 0x0f },
-       { STB0899_EQUAQ2                , 0xff },
-       { STB0899_EQUAI3                , 0xdf },
-       { STB0899_EQUAQ3                , 0xfa },
-       { STB0899_EQUAI4                , 0x37 },
-       { STB0899_EQUAQ4                , 0x0d },
-       { STB0899_EQUAI5                , 0xbd },
-       { STB0899_EQUAQ5                , 0xf7 },
-       { STB0899_DSTATUS2              , 0x00 },
-       { STB0899_VSTATUS               , 0x00 },
-       { STB0899_VERROR                , 0xff },
-       { STB0899_IQSWAP                , 0x2a },
-       { STB0899_ECNT1M                , 0x00 },
-       { STB0899_ECNT1L                , 0x00 },
-       { STB0899_ECNT2M                , 0x00 },
-       { STB0899_ECNT2L                , 0x00 },
-       { STB0899_ECNT3M                , 0x00 },
-       { STB0899_ECNT3L                , 0x00 },
-       { STB0899_FECAUTO1              , 0x06 },
-       { STB0899_FECM                  , 0x01 },
-       { STB0899_VTH12                 , 0xf0 },
-       { STB0899_VTH23                 , 0xa0 },
-       { STB0899_VTH34                 , 0x78 },
-       { STB0899_VTH56                 , 0x4e },
-       { STB0899_VTH67                 , 0x48 },
-       { STB0899_VTH78                 , 0x38 },
-       { STB0899_PRVIT                 , 0xff },
-       { STB0899_VITSYNC               , 0x19 },
-       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-       { STB0899_TSULC                 , 0x42 },
-       { STB0899_RSLLC                 , 0x40 },
-       { STB0899_TSLPL                 , 0x12 },
-       { STB0899_TSCFGH                , 0x0c },
-       { STB0899_TSCFGM                , 0x00 },
-       { STB0899_TSCFGL                , 0x0c },
-       { STB0899_TSOUT                 , 0x4d }, /* 0x0d for CAM */
-       { STB0899_RSSYNCDEL             , 0x00 },
-       { STB0899_TSINHDELH             , 0x02 },
-       { STB0899_TSINHDELM             , 0x00 },
-       { STB0899_TSINHDELL             , 0x00 },
-       { STB0899_TSLLSTKM              , 0x00 },
-       { STB0899_TSLLSTKL              , 0x00 },
-       { STB0899_TSULSTKM              , 0x00 },
-       { STB0899_TSULSTKL              , 0xab },
-       { STB0899_PCKLENUL              , 0x00 },
-       { STB0899_PCKLENLL              , 0xcc },
-       { STB0899_RSPCKLEN              , 0xcc },
-       { STB0899_TSSTATUS              , 0x80 },
-       { STB0899_ERRCTRL1              , 0xb6 },
-       { STB0899_ERRCTRL2              , 0x96 },
-       { STB0899_ERRCTRL3              , 0x89 },
-       { STB0899_DMONMSK1              , 0x27 },
-       { STB0899_DMONMSK0              , 0x03 },
-       { STB0899_DEMAPVIT              , 0x5c },
-       { STB0899_PLPARM                , 0x1f },
-       { STB0899_PDELCTRL              , 0x48 },
-       { STB0899_PDELCTRL2             , 0x00 },
-       { STB0899_BBHCTRL1              , 0x00 },
-       { STB0899_BBHCTRL2              , 0x00 },
-       { STB0899_HYSTTHRESH            , 0x77 },
-       { STB0899_MATCSTM               , 0x00 },
-       { STB0899_MATCSTL               , 0x00 },
-       { STB0899_UPLCSTM               , 0x00 },
-       { STB0899_UPLCSTL               , 0x00 },
-       { STB0899_DFLCSTM               , 0x00 },
-       { STB0899_DFLCSTL               , 0x00 },
-       { STB0899_SYNCCST               , 0x00 },
-       { STB0899_SYNCDCSTM             , 0x00 },
-       { STB0899_SYNCDCSTL             , 0x00 },
-       { STB0899_ISI_ENTRY             , 0x00 },
-       { STB0899_ISI_BIT_EN            , 0x00 },
-       { STB0899_MATSTRM               , 0x00 },
-       { STB0899_MATSTRL               , 0x00 },
-       { STB0899_UPLSTRM               , 0x00 },
-       { STB0899_UPLSTRL               , 0x00 },
-       { STB0899_DFLSTRM               , 0x00 },
-       { STB0899_DFLSTRL               , 0x00 },
-       { STB0899_SYNCSTR               , 0x00 },
-       { STB0899_SYNCDSTRM             , 0x00 },
-       { STB0899_SYNCDSTRL             , 0x00 },
-       { STB0899_CFGPDELSTATUS1        , 0x10 },
-       { STB0899_CFGPDELSTATUS2        , 0x00 },
-       { STB0899_BBFERRORM             , 0x00 },
-       { STB0899_BBFERRORL             , 0x00 },
-       { STB0899_UPKTERRORM            , 0x00 },
-       { STB0899_UPKTERRORL            , 0x00 },
-       { 0xffff                        , 0xff },
-};
-
-/* STB0899 demodulator config for the KNC1 and clones */
-static struct stb0899_config knc1_dvbs2_config = {
-       .init_dev               = knc1_stb0899_s1_init_1,
-       .init_s2_demod          = stb0899_s2_init_2,
-       .init_s1_demod          = knc1_stb0899_s1_init_3,
-       .init_s2_fec            = stb0899_s2_init_4,
-       .init_tst               = stb0899_s1_init_5,
-
-       .postproc               = NULL,
-
-       .demod_address          = 0x68,
-//     .ts_output_mode         = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL      */
-       .block_sync_mode        = STB0899_SYNC_FORCED,  /* DSS, SYNC_FORCED/UNSYNCED    */
-//     .ts_pfbit_toggle        = STB0899_MPEG_NORMAL,  /* DirecTV, MPEG toggling seq   */
-
-       .xtal_freq              = 27000000,
-       .inversion              = IQ_SWAP_OFF, /* 1 */
-
-       .lo_clk                 = 76500000,
-       .hi_clk                 = 90000000,
-
-       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
-       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
-       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
-       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
-       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
-       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
-       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
-       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
-       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
-
-       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
-       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
-       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
-       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
-
-       .tuner_get_frequency    = tda8261_get_frequency,
-       .tuner_set_frequency    = tda8261_set_frequency,
-       .tuner_set_bandwidth    = NULL,
-       .tuner_get_bandwidth    = tda8261_get_bandwidth,
-       .tuner_set_rfsiggain    = NULL
-};
-
-/*
- * SD1878/SHA tuner config
- * 1F, Single I/P, Horizontal mount, High Sensitivity
- */
-static const struct tda8261_config sd1878c_config = {
-//     .name           = "SD1878/SHA",
-       .addr           = 0x60,
-       .step_size      = TDA8261_STEP_1000 /* kHz */
-};
-
-static u8 read_pwm(struct budget_av *budget_av)
-{
-       u8 b = 0xff;
-       u8 pwm;
-       struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
-       {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
-       };
-
-       if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
-           || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-#define SUBID_DVBS_KNC1                        0x0010
-#define SUBID_DVBS_KNC1_PLUS           0x0011
-#define SUBID_DVBS_TYPHOON             0x4f56
-#define SUBID_DVBS_CINERGY1200         0x1154
-#define SUBID_DVBS_CYNERGY1200N        0x1155
-#define SUBID_DVBS_TV_STAR             0x0014
-#define SUBID_DVBS_TV_STAR_PLUS_X4     0x0015
-#define SUBID_DVBS_TV_STAR_CI          0x0016
-#define SUBID_DVBS2_KNC1               0x0018
-#define SUBID_DVBS2_KNC1_OEM           0x0019
-#define SUBID_DVBS_EASYWATCH_1         0x001a
-#define SUBID_DVBS_EASYWATCH_2         0x001b
-#define SUBID_DVBS2_EASYWATCH          0x001d
-#define SUBID_DVBS_EASYWATCH           0x001e
-
-#define SUBID_DVBC_EASYWATCH           0x002a
-#define SUBID_DVBC_EASYWATCH_MK3       0x002c
-#define SUBID_DVBC_KNC1                        0x0020
-#define SUBID_DVBC_KNC1_PLUS           0x0021
-#define SUBID_DVBC_KNC1_MK3            0x0022
-#define SUBID_DVBC_KNC1_TDA10024       0x0028
-#define SUBID_DVBC_KNC1_PLUS_MK3       0x0023
-#define SUBID_DVBC_CINERGY1200         0x1156
-#define SUBID_DVBC_CINERGY1200_MK3     0x1176
-
-#define SUBID_DVBT_EASYWATCH           0x003a
-#define SUBID_DVBT_KNC1_PLUS           0x0031
-#define SUBID_DVBT_KNC1                        0x0030
-#define SUBID_DVBT_CINERGY1200         0x1157
-
-static void frontend_init(struct budget_av *budget_av)
-{
-       struct saa7146_dev * saa = budget_av->budget.dev;
-       struct dvb_frontend * fe = NULL;
-
-       /* Enable / PowerON Frontend */
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
-
-       /* Wait for PowerON */
-       msleep(100);
-
-       /* additional setup necessary for the PLUS cards */
-       switch (saa->pci->subsystem_device) {
-               case SUBID_DVBS_KNC1_PLUS:
-               case SUBID_DVBC_KNC1_PLUS:
-               case SUBID_DVBT_KNC1_PLUS:
-               case SUBID_DVBC_EASYWATCH:
-               case SUBID_DVBC_KNC1_PLUS_MK3:
-               case SUBID_DVBS2_KNC1:
-               case SUBID_DVBS2_KNC1_OEM:
-               case SUBID_DVBS2_EASYWATCH:
-                       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
-                       break;
-       }
-
-       switch (saa->pci->subsystem_device) {
-
-       case SUBID_DVBS_KNC1:
-               /*
-                * maybe that setting is needed for other dvb-s cards as well,
-                * but so far it has been only confirmed for this type
-                */
-               budget_av->reinitialise_demod = 1;
-               /* fall through */
-       case SUBID_DVBS_KNC1_PLUS:
-       case SUBID_DVBS_EASYWATCH_1:
-               if (saa->pci->subsystem_vendor == 0x1894) {
-                       fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
-                                            &budget_av->budget.i2c_adap);
-                       if (fe) {
-                               dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
-                       }
-               } else {
-                       fe = dvb_attach(stv0299_attach, &typhoon_config,
-                                            &budget_av->budget.i2c_adap);
-                       if (fe) {
-                               fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
-                       }
-               }
-               break;
-
-       case SUBID_DVBS_TV_STAR:
-       case SUBID_DVBS_TV_STAR_PLUS_X4:
-       case SUBID_DVBS_TV_STAR_CI:
-       case SUBID_DVBS_CYNERGY1200N:
-       case SUBID_DVBS_EASYWATCH:
-       case SUBID_DVBS_EASYWATCH_2:
-               fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
-                               &budget_av->budget.i2c_adap);
-               if (fe) {
-                       dvb_attach(dvb_pll_attach, fe, 0x60,
-                                  &budget_av->budget.i2c_adap,
-                                  DVB_PLL_PHILIPS_SD1878_TDA8261);
-               }
-               break;
-
-       case SUBID_DVBS_TYPHOON:
-               fe = dvb_attach(stv0299_attach, &typhoon_config,
-                                   &budget_av->budget.i2c_adap);
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
-               }
-               break;
-       case SUBID_DVBS2_KNC1:
-       case SUBID_DVBS2_KNC1_OEM:
-       case SUBID_DVBS2_EASYWATCH:
-               budget_av->reinitialise_demod = 1;
-               if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
-                       dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
-
-               break;
-       case SUBID_DVBS_CINERGY1200:
-               fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
-                                   &budget_av->budget.i2c_adap);
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
-               }
-               break;
-
-       case SUBID_DVBC_KNC1:
-       case SUBID_DVBC_KNC1_PLUS:
-       case SUBID_DVBC_CINERGY1200:
-       case SUBID_DVBC_EASYWATCH:
-               budget_av->reinitialise_demod = 1;
-               budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
-               fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
-                                    &budget_av->budget.i2c_adap,
-                                    read_pwm(budget_av));
-               if (fe == NULL)
-                       fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
-                                            &budget_av->budget.i2c_adap,
-                                            read_pwm(budget_av));
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
-               }
-               break;
-
-       case SUBID_DVBC_EASYWATCH_MK3:
-       case SUBID_DVBC_CINERGY1200_MK3:
-       case SUBID_DVBC_KNC1_MK3:
-       case SUBID_DVBC_KNC1_TDA10024:
-       case SUBID_DVBC_KNC1_PLUS_MK3:
-               budget_av->reinitialise_demod = 1;
-               budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
-               fe = dvb_attach(tda10023_attach,
-                       &philips_cu1216_tda10023_config,
-                       &budget_av->budget.i2c_adap,
-                       read_pwm(budget_av));
-               if (fe) {
-                       fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
-               }
-               break;
-
-       case SUBID_DVBT_EASYWATCH:
-       case SUBID_DVBT_KNC1:
-       case SUBID_DVBT_KNC1_PLUS:
-       case SUBID_DVBT_CINERGY1200:
-               budget_av->reinitialise_demod = 1;
-               fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
-                                    &budget_av->budget.i2c_adap);
-               if (fe) {
-                       fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
-                       fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
-               }
-               break;
-       }
-
-       if (fe == NULL) {
-               pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      saa->pci->vendor,
-                      saa->pci->device,
-                      saa->pci->subsystem_vendor,
-                      saa->pci->subsystem_device);
-               return;
-       }
-
-       budget_av->budget.dvb_frontend = fe;
-
-       if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
-                                 budget_av->budget.dvb_frontend)) {
-               pr_err("Frontend registration failed!\n");
-               dvb_frontend_detach(budget_av->budget.dvb_frontend);
-               budget_av->budget.dvb_frontend = NULL;
-       }
-}
-
-
-static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
-{
-       struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-
-       dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
-
-       if (*isr & MASK_10)
-               ttpci_budget_irq10_handler(dev, isr);
-}
-
-static int budget_av_detach(struct saa7146_dev *dev)
-{
-       struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-       int err;
-
-       dprintk(2, "dev: %p\n", dev);
-
-       if (1 == budget_av->has_saa7113) {
-               saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
-
-               msleep(200);
-
-               saa7146_unregister_device(&budget_av->vd, dev);
-
-               saa7146_vv_release(dev);
-       }
-
-       if (budget_av->budget.ci_present)
-               ciintf_deinit(budget_av);
-
-       if (budget_av->budget.dvb_frontend != NULL) {
-               dvb_unregister_frontend(budget_av->budget.dvb_frontend);
-               dvb_frontend_detach(budget_av->budget.dvb_frontend);
-       }
-       err = ttpci_budget_deinit(&budget_av->budget);
-
-       kfree(budget_av);
-
-       return err;
-}
-
-#define KNC1_INPUTS 2
-static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
-       { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
-               V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
-       { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
-               V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
-};
-
-static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
-       dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
-       if (i->index >= KNC1_INPUTS)
-               return -EINVAL;
-       memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
-       return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
-
-       *i = budget_av->cur_input;
-
-       dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
-       return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
-{
-       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
-       struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
-
-       dprintk(1, "VIDIOC_S_INPUT %d\n", input);
-       return saa7113_setinput(budget_av, input);
-}
-
-static struct saa7146_ext_vv vv_data;
-
-static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-{
-       struct budget_av *budget_av;
-       u8 *mac;
-       int err;
-
-       dprintk(2, "dev: %p\n", dev);
-
-       if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
-               return -ENOMEM;
-
-       budget_av->has_saa7113 = 0;
-       budget_av->budget.ci_present = 0;
-
-       dev->ext_priv = budget_av;
-
-       err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
-                               adapter_nr);
-       if (err) {
-               kfree(budget_av);
-               return err;
-       }
-
-       /* knc1 initialization */
-       saa7146_write(dev, DD1_STREAM_B, 0x04000000);
-       saa7146_write(dev, DD1_INIT, 0x07000600);
-       saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
-
-       if (saa7113_init(budget_av) == 0) {
-               budget_av->has_saa7113 = 1;
-
-               if (0 != saa7146_vv_init(dev, &vv_data)) {
-                       /* fixme: proper cleanup here */
-                       ERR("cannot init vv subsystem\n");
-                       return err;
-               }
-               vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
-               vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
-               vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
-
-               if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
-                       /* fixme: proper cleanup here */
-                       ERR("cannot register capture v4l2 device\n");
-                       saa7146_vv_release(dev);
-                       return err;
-               }
-
-               /* beware: this modifies dev->vv ... */
-               saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
-                                               SAA7146_HPS_SYNC_PORT_A);
-
-               saa7113_setinput(budget_av, 0);
-       }
-
-       /* fixme: find some sane values here... */
-       saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
-
-       mac = budget_av->budget.dvb_adapter.proposed_mac;
-       if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
-               pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
-                      budget_av->budget.dvb_adapter.num);
-               memset(mac, 0, 6);
-       } else {
-               pr_info("KNC1-%d: MAC addr = %pM\n",
-                       budget_av->budget.dvb_adapter.num, mac);
-       }
-
-       budget_av->budget.dvb_adapter.priv = budget_av;
-       frontend_init(budget_av);
-       ciintf_init(budget_av);
-
-       ttpci_budget_init_hooks(&budget_av->budget);
-
-       return 0;
-}
-
-static struct saa7146_standard standard[] = {
-       {.name = "PAL",.id = V4L2_STD_PAL,
-        .v_offset = 0x17,.v_field = 288,
-        .h_offset = 0x14,.h_pixels = 680,
-        .v_max_out = 576,.h_max_out = 768 },
-
-       {.name = "NTSC",.id = V4L2_STD_NTSC,
-        .v_offset = 0x16,.v_field = 240,
-        .h_offset = 0x06,.h_pixels = 708,
-        .v_max_out = 480,.h_max_out = 640, },
-};
-
-static struct saa7146_ext_vv vv_data = {
-       .inputs = 2,
-       .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
-       .flags = 0,
-       .stds = &standard[0],
-       .num_stds = ARRAY_SIZE(standard),
-};
-
-static struct saa7146_extension budget_extension;
-
-MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
-MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
-MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
-MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
-MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
-MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
-MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
-MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
-MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
-MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
-MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
-MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
-MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
-MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
-MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
-MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
-MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
-MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
-MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
-MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
-MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
-MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
-MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
-MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
-
-static struct pci_device_id pci_tbl[] = {
-       MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
-       MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
-       MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
-       MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
-       MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
-       MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
-       MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
-       MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
-       MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
-       MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
-       MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
-       MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
-       MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
-       MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
-       MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
-       MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
-       MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
-       MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
-       MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
-       MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
-       MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
-       MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
-       MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
-       MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
-       MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
-       MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
-       MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
-       MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
-       MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
-       {
-        .vendor = 0,
-       }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_extension budget_extension = {
-       .name = "budget_av",
-       .flags = SAA7146_USE_I2C_IRQ,
-
-       .pci_tbl = pci_tbl,
-
-       .module = THIS_MODULE,
-       .attach = budget_av_attach,
-       .detach = budget_av_detach,
-
-       .irq_mask = MASK_10,
-       .irq_func = budget_av_irq,
-};
-
-static int __init budget_av_init(void)
-{
-       return saa7146_register_extension(&budget_extension);
-}
-
-static void __exit budget_av_exit(void)
-{
-       saa7146_unregister_extension(&budget_extension);
-}
-
-module_init(budget_av_init);
-module_exit(budget_av_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
-MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
-                  "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
deleted file mode 100644 (file)
index 98e5241..0000000
+++ /dev/null
@@ -1,1591 +0,0 @@
-/*
- * budget-ci.c: driver for the SAA7146 based Budget DVB cards
- *
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
- *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
- *
- * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <media/rc-core.h>
-
-#include "budget.h"
-
-#include "dvb_ca_en50221.h"
-#include "stv0299.h"
-#include "stv0297.h"
-#include "tda1004x.h"
-#include "stb0899_drv.h"
-#include "stb0899_reg.h"
-#include "stb0899_cfg.h"
-#include "stb6100.h"
-#include "stb6100_cfg.h"
-#include "lnbp21.h"
-#include "bsbe1.h"
-#include "bsru6.h"
-#include "tda1002x.h"
-#include "tda827x.h"
-#include "bsbe1-d01a.h"
-
-#define MODULE_NAME "budget_ci"
-
-/*
- * Regarding DEBIADDR_IR:
- * Some CI modules hang if random addresses are read.
- * Using address 0x4000 for the IR read means that we
- * use the same address as for CI version, which should
- * be a safe default.
- */
-#define DEBIADDR_IR            0x4000
-#define DEBIADDR_CICONTROL     0x0000
-#define DEBIADDR_CIVERSION     0x4000
-#define DEBIADDR_IO            0x1000
-#define DEBIADDR_ATTR          0x3000
-
-#define CICONTROL_RESET                0x01
-#define CICONTROL_ENABLETS     0x02
-#define CICONTROL_CAMDETECT    0x08
-
-#define DEBICICTL              0x00420000
-#define DEBICICAM              0x02420000
-
-#define SLOTSTATUS_NONE                1
-#define SLOTSTATUS_PRESENT     2
-#define SLOTSTATUS_RESET       4
-#define SLOTSTATUS_READY       8
-#define SLOTSTATUS_OCCUPIED    (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
-
-/* RC5 device wildcard */
-#define IR_DEVICE_ANY          255
-
-static int rc5_device = -1;
-module_param(rc5_device, int, 0644);
-MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
-
-static int ir_debug;
-module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct budget_ci_ir {
-       struct rc_dev *dev;
-       struct tasklet_struct msp430_irq_tasklet;
-       char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
-       char phys[32];
-       int rc5_device;
-       u32 ir_key;
-       bool have_command;
-       bool full_rc5;          /* Outputs a full RC5 code */
-};
-
-struct budget_ci {
-       struct budget budget;
-       struct tasklet_struct ciintf_irq_tasklet;
-       int slot_status;
-       int ci_irq;
-       struct dvb_ca_en50221 ca;
-       struct budget_ci_ir ir;
-       u8 tuner_pll_address; /* used for philips_tdm1316l configs */
-};
-
-static void msp430_ir_interrupt(unsigned long data)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) data;
-       struct rc_dev *dev = budget_ci->ir.dev;
-       u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
-
-       /*
-        * The msp430 chip can generate two different bytes, command and device
-        *
-        * type1: X1CCCCCC, C = command bits (0 - 63)
-        * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
-        *
-        * Each signal from the remote control can generate one or more command
-        * bytes and one or more device bytes. For the repeated bytes, the
-        * highest bit (X) is set. The first command byte is always generated
-        * before the first device byte. Other than that, no specific order
-        * seems to apply. To make life interesting, bytes can also be lost.
-        *
-        * Only when we have a command and device byte, a keypress is
-        * generated.
-        */
-
-       if (ir_debug)
-               printk("budget_ci: received byte 0x%02x\n", command);
-
-       /* Remove repeat bit, we use every command */
-       command = command & 0x7f;
-
-       /* Is this a RC5 command byte? */
-       if (command & 0x40) {
-               budget_ci->ir.have_command = true;
-               budget_ci->ir.ir_key = command & 0x3f;
-               return;
-       }
-
-       /* It's a RC5 device byte */
-       if (!budget_ci->ir.have_command)
-               return;
-       budget_ci->ir.have_command = false;
-
-       if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
-           budget_ci->ir.rc5_device != (command & 0x1f))
-               return;
-
-       if (budget_ci->ir.full_rc5) {
-               rc_keydown(dev,
-                          budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
-                          (command & 0x20) ? 1 : 0);
-               return;
-       }
-
-       /* FIXME: We should generate complete scancodes for all devices */
-       rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
-}
-
-static int msp430_ir_init(struct budget_ci *budget_ci)
-{
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-       struct rc_dev *dev;
-       int error;
-
-       dev = rc_allocate_device();
-       if (!dev) {
-               printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
-               return -ENOMEM;
-       }
-
-       snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
-                "Budget-CI dvb ir receiver %s", saa->name);
-       snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
-                "pci-%s/ir0", pci_name(saa->pci));
-
-       dev->driver_name = MODULE_NAME;
-       dev->input_name = budget_ci->ir.name;
-       dev->input_phys = budget_ci->ir.phys;
-       dev->input_id.bustype = BUS_PCI;
-       dev->input_id.version = 1;
-       if (saa->pci->subsystem_vendor) {
-               dev->input_id.vendor = saa->pci->subsystem_vendor;
-               dev->input_id.product = saa->pci->subsystem_device;
-       } else {
-               dev->input_id.vendor = saa->pci->vendor;
-               dev->input_id.product = saa->pci->device;
-       }
-       dev->dev.parent = &saa->pci->dev;
-
-       if (rc5_device < 0)
-               budget_ci->ir.rc5_device = IR_DEVICE_ANY;
-       else
-               budget_ci->ir.rc5_device = rc5_device;
-
-       /* Select keymap and address */
-       switch (budget_ci->budget.dev->pci->subsystem_device) {
-       case 0x100c:
-       case 0x100f:
-       case 0x1011:
-       case 0x1012:
-               /* The hauppauge keymap is a superset of these remotes */
-               dev->map_name = RC_MAP_HAUPPAUGE;
-               budget_ci->ir.full_rc5 = true;
-
-               if (rc5_device < 0)
-                       budget_ci->ir.rc5_device = 0x1f;
-               break;
-       case 0x1010:
-       case 0x1017:
-       case 0x1019:
-       case 0x101a:
-       case 0x101b:
-               /* for the Technotrend 1500 bundled remote */
-               dev->map_name = RC_MAP_TT_1500;
-               break;
-       default:
-               /* unknown remote */
-               dev->map_name = RC_MAP_BUDGET_CI_OLD;
-               break;
-       }
-       if (!budget_ci->ir.full_rc5)
-               dev->scanmask = 0xff;
-
-       error = rc_register_device(dev);
-       if (error) {
-               printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
-               rc_free_device(dev);
-               return error;
-       }
-
-       budget_ci->ir.dev = dev;
-
-       tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
-                    (unsigned long) budget_ci);
-
-       SAA7146_IER_ENABLE(saa, MASK_06);
-       saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
-
-       return 0;
-}
-
-static void msp430_ir_deinit(struct budget_ci *budget_ci)
-{
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-
-       SAA7146_IER_DISABLE(saa, MASK_06);
-       saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
-       tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
-
-       rc_unregister_device(budget_ci->ir.dev);
-}
-
-static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
-                                    DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
-}
-
-static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
-                                     DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
-}
-
-static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
-                                    DEBIADDR_IO | (address & 3), 1, 1, 0);
-}
-
-static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
-                                     DEBIADDR_IO | (address & 3), 1, value, 1, 0);
-}
-
-static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       if (budget_ci->ci_irq) {
-               // trigger on RISING edge during reset so we know when READY is re-asserted
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
-       }
-       budget_ci->slot_status = SLOTSTATUS_RESET;
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
-       msleep(1);
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
-                              CICONTROL_RESET, 1, 0);
-
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
-       return 0;
-}
-
-static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
-       return 0;
-}
-
-static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-       int tmp;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
-
-       tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
-                              tmp | CICONTROL_ENABLETS, 1, 0);
-
-       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
-       return 0;
-}
-
-static void ciintf_interrupt(unsigned long data)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) data;
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-       unsigned int flags;
-
-       // ensure we don't get spurious IRQs during initialisation
-       if (!budget_ci->budget.ci_present)
-               return;
-
-       // read the CAM status
-       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
-       if (flags & CICONTROL_CAMDETECT) {
-
-               // GPIO should be set to trigger on falling edge if a CAM is present
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
-
-               if (budget_ci->slot_status & SLOTSTATUS_NONE) {
-                       // CAM insertion IRQ
-                       budget_ci->slot_status = SLOTSTATUS_PRESENT;
-                       dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
-                                                    DVB_CA_EN50221_CAMCHANGE_INSERTED);
-
-               } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
-                       // CAM ready (reset completed)
-                       budget_ci->slot_status = SLOTSTATUS_READY;
-                       dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
-
-               } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
-                       // FR/DA IRQ
-                       dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
-               }
-       } else {
-
-               // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
-               // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
-               // the CAM might not actually be ready yet.
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
-
-               // generate a CAM removal IRQ if we haven't already
-               if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
-                       // CAM removal IRQ
-                       budget_ci->slot_status = SLOTSTATUS_NONE;
-                       dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
-                                                    DVB_CA_EN50221_CAMCHANGE_REMOVED);
-               }
-       }
-}
-
-static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
-       unsigned int flags;
-
-       // ensure we don't get spurious IRQs during initialisation
-       if (!budget_ci->budget.ci_present)
-               return -EINVAL;
-
-       // read the CAM status
-       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
-       if (flags & CICONTROL_CAMDETECT) {
-               // mark it as present if it wasn't before
-               if (budget_ci->slot_status & SLOTSTATUS_NONE) {
-                       budget_ci->slot_status = SLOTSTATUS_PRESENT;
-               }
-
-               // during a RESET, we check if we can read from IO memory to see when CAM is ready
-               if (budget_ci->slot_status & SLOTSTATUS_RESET) {
-                       if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
-                               budget_ci->slot_status = SLOTSTATUS_READY;
-                       }
-               }
-       } else {
-               budget_ci->slot_status = SLOTSTATUS_NONE;
-       }
-
-       if (budget_ci->slot_status != SLOTSTATUS_NONE) {
-               if (budget_ci->slot_status & SLOTSTATUS_READY) {
-                       return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
-               }
-               return DVB_CA_EN50221_POLL_CAM_PRESENT;
-       }
-
-       return 0;
-}
-
-static int ciintf_init(struct budget_ci *budget_ci)
-{
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-       int flags;
-       int result;
-       int ci_version;
-       int ca_flags;
-
-       memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
-
-       // enable DEBI pins
-       saa7146_write(saa, MC1, MASK_27 | MASK_11);
-
-       // test if it is there
-       ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
-       if ((ci_version & 0xa0) != 0xa0) {
-               result = -ENODEV;
-               goto error;
-       }
-
-       // determine whether a CAM is present or not
-       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
-       budget_ci->slot_status = SLOTSTATUS_NONE;
-       if (flags & CICONTROL_CAMDETECT)
-               budget_ci->slot_status = SLOTSTATUS_PRESENT;
-
-       // version 0xa2 of the CI firmware doesn't generate interrupts
-       if (ci_version == 0xa2) {
-               ca_flags = 0;
-               budget_ci->ci_irq = 0;
-       } else {
-               ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
-                               DVB_CA_EN50221_FLAG_IRQ_FR |
-                               DVB_CA_EN50221_FLAG_IRQ_DA;
-               budget_ci->ci_irq = 1;
-       }
-
-       // register CI interface
-       budget_ci->ca.owner = THIS_MODULE;
-       budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
-       budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
-       budget_ci->ca.read_cam_control = ciintf_read_cam_control;
-       budget_ci->ca.write_cam_control = ciintf_write_cam_control;
-       budget_ci->ca.slot_reset = ciintf_slot_reset;
-       budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
-       budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
-       budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
-       budget_ci->ca.data = budget_ci;
-       if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
-                                         &budget_ci->ca,
-                                         ca_flags, 1)) != 0) {
-               printk("budget_ci: CI interface detected, but initialisation failed.\n");
-               goto error;
-       }
-
-       // Setup CI slot IRQ
-       if (budget_ci->ci_irq) {
-               tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
-               if (budget_ci->slot_status != SLOTSTATUS_NONE) {
-                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
-               } else {
-                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
-               }
-               SAA7146_IER_ENABLE(saa, MASK_03);
-       }
-
-       // enable interface
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
-                              CICONTROL_RESET, 1, 0);
-
-       // success!
-       printk("budget_ci: CI interface initialised\n");
-       budget_ci->budget.ci_present = 1;
-
-       // forge a fake CI IRQ so the CAM state is setup correctly
-       if (budget_ci->ci_irq) {
-               flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
-               if (budget_ci->slot_status != SLOTSTATUS_NONE)
-                       flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
-               dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
-       }
-
-       return 0;
-
-error:
-       saa7146_write(saa, MC1, MASK_27);
-       return result;
-}
-
-static void ciintf_deinit(struct budget_ci *budget_ci)
-{
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-
-       // disable CI interrupts
-       if (budget_ci->ci_irq) {
-               SAA7146_IER_DISABLE(saa, MASK_03);
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
-               tasklet_kill(&budget_ci->ciintf_irq_tasklet);
-       }
-
-       // reset interface
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
-       msleep(1);
-       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
-                              CICONTROL_RESET, 1, 0);
-
-       // disable TS data stream to CI interface
-       saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
-
-       // release the CA device
-       dvb_ca_en50221_release(&budget_ci->ca);
-
-       // disable DEBI pins
-       saa7146_write(saa, MC1, MASK_27);
-}
-
-static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
-
-       dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
-
-       if (*isr & MASK_06)
-               tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
-
-       if (*isr & MASK_10)
-               ttpci_budget_irq10_handler(dev, isr);
-
-       if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
-               tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
-}
-
-static u8 philips_su1278_tt_inittab[] = {
-       0x01, 0x0f,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x5b,
-       0x05, 0x85,
-       0x06, 0x02,
-       0x07, 0x00,
-       0x08, 0x02,
-       0x09, 0x00,
-       0x0C, 0x01,
-       0x0D, 0x81,
-       0x0E, 0x44,
-       0x0f, 0x14,
-       0x10, 0x3c,
-       0x11, 0x84,
-       0x12, 0xda,
-       0x13, 0x97,
-       0x14, 0x95,
-       0x15, 0xc9,
-       0x16, 0x19,
-       0x17, 0x8c,
-       0x18, 0x59,
-       0x19, 0xf8,
-       0x1a, 0xfe,
-       0x1c, 0x7f,
-       0x1d, 0x00,
-       0x1e, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,
-       0x29, 0x28,
-       0x2a, 0x14,
-       0x2b, 0x0f,
-       0x2c, 0x09,
-       0x2d, 0x09,
-       0x31, 0x1f,
-       0x32, 0x19,
-       0x33, 0xfc,
-       0x34, 0x93,
-       0xff, 0xff
-};
-
-static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
-{
-       stv0299_writereg(fe, 0x0e, 0x44);
-       if (srate >= 10000000) {
-               stv0299_writereg(fe, 0x13, 0x97);
-               stv0299_writereg(fe, 0x14, 0x95);
-               stv0299_writereg(fe, 0x15, 0xc9);
-               stv0299_writereg(fe, 0x17, 0x8c);
-               stv0299_writereg(fe, 0x1a, 0xfe);
-               stv0299_writereg(fe, 0x1c, 0x7f);
-               stv0299_writereg(fe, 0x2d, 0x09);
-       } else {
-               stv0299_writereg(fe, 0x13, 0x99);
-               stv0299_writereg(fe, 0x14, 0x8d);
-               stv0299_writereg(fe, 0x15, 0xce);
-               stv0299_writereg(fe, 0x17, 0x43);
-               stv0299_writereg(fe, 0x1a, 0x1d);
-               stv0299_writereg(fe, 0x1c, 0x12);
-               stv0299_writereg(fe, 0x2d, 0x05);
-       }
-       stv0299_writereg(fe, 0x0e, 0x23);
-       stv0299_writereg(fe, 0x0f, 0x94);
-       stv0299_writereg(fe, 0x10, 0x39);
-       stv0299_writereg(fe, 0x15, 0xc9);
-
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
-
-       return 0;
-}
-
-static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
-       u32 div;
-       u8 buf[4];
-       struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
-
-       if ((p->frequency < 950000) || (p->frequency > 2150000))
-               return -EINVAL;
-
-       div = (p->frequency + (500 - 1)) / 500; /* round correctly */
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
-       buf[3] = 0x20;
-
-       if (p->symbol_rate < 4000000)
-               buf[3] |= 1;
-
-       if (p->frequency < 1250000)
-               buf[3] |= 0;
-       else if (p->frequency < 1550000)
-               buf[3] |= 0x40;
-       else if (p->frequency < 2050000)
-               buf[3] |= 0x80;
-       else if (p->frequency < 2150000)
-               buf[3] |= 0xC0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct stv0299_config philips_su1278_tt_config = {
-
-       .demod_address = 0x68,
-       .inittab = philips_su1278_tt_inittab,
-       .mclk = 64000000UL,
-       .invert = 0,
-       .skip_reinit = 1,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 50,
-       .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
-};
-
-
-
-static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
-       static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
-       static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
-       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
-                       sizeof(td1316_init) };
-
-       // setup PLL configuration
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-       msleep(1);
-
-       // disable the mc44BC374c (do not check for errors)
-       tuner_msg.addr = 0x65;
-       tuner_msg.buf = disable_mc44BC374c;
-       tuner_msg.len = sizeof(disable_mc44BC374c);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
-       }
-
-       return 0;
-}
-
-static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
-       u8 tuner_buf[4];
-       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
-       int tuner_frequency = 0;
-       u8 band, cp, filter;
-
-       // determine charge pump
-       tuner_frequency = p->frequency + 36130000;
-       if (tuner_frequency < 87000000)
-               return -EINVAL;
-       else if (tuner_frequency < 130000000)
-               cp = 3;
-       else if (tuner_frequency < 160000000)
-               cp = 5;
-       else if (tuner_frequency < 200000000)
-               cp = 6;
-       else if (tuner_frequency < 290000000)
-               cp = 3;
-       else if (tuner_frequency < 420000000)
-               cp = 5;
-       else if (tuner_frequency < 480000000)
-               cp = 6;
-       else if (tuner_frequency < 620000000)
-               cp = 3;
-       else if (tuner_frequency < 830000000)
-               cp = 5;
-       else if (tuner_frequency < 895000000)
-               cp = 7;
-       else
-               return -EINVAL;
-
-       // determine band
-       if (p->frequency < 49000000)
-               return -EINVAL;
-       else if (p->frequency < 159000000)
-               band = 1;
-       else if (p->frequency < 444000000)
-               band = 2;
-       else if (p->frequency < 861000000)
-               band = 4;
-       else
-               return -EINVAL;
-
-       // setup PLL filter and TDA9889
-       switch (p->bandwidth_hz) {
-       case 6000000:
-               tda1004x_writereg(fe, 0x0C, 0x14);
-               filter = 0;
-               break;
-
-       case 7000000:
-               tda1004x_writereg(fe, 0x0C, 0x80);
-               filter = 0;
-               break;
-
-       case 8000000:
-               tda1004x_writereg(fe, 0x0C, 0x14);
-               filter = 1;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // calculate divisor
-       // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
-       tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
-
-       // setup tuner buffer
-       tuner_buf[0] = tuner_frequency >> 8;
-       tuner_buf[1] = tuner_frequency & 0xff;
-       tuner_buf[2] = 0xca;
-       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-
-       msleep(1);
-       return 0;
-}
-
-static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
-                                            const struct firmware **fw, char *name)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
-
-       return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
-}
-
-static struct tda1004x_config philips_tdm1316l_config = {
-
-       .demod_address = 0x8,
-       .invert = 0,
-       .invert_oclk = 0,
-       .xtal_freq = TDA10046_XTAL_4M,
-       .agc_config = TDA10046_AGC_DEFAULT,
-       .if_freq = TDA10046_FREQ_3617,
-       .request_firmware = philips_tdm1316l_request_firmware,
-};
-
-static struct tda1004x_config philips_tdm1316l_config_invert = {
-
-       .demod_address = 0x8,
-       .invert = 1,
-       .invert_oclk = 0,
-       .xtal_freq = TDA10046_XTAL_4M,
-       .agc_config = TDA10046_AGC_DEFAULT,
-       .if_freq = TDA10046_FREQ_3617,
-       .request_firmware = philips_tdm1316l_request_firmware,
-};
-
-static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
-       u8 tuner_buf[5];
-       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
-                                   .flags = 0,
-                                   .buf = tuner_buf,
-                                   .len = sizeof(tuner_buf) };
-       int tuner_frequency = 0;
-       u8 band, cp, filter;
-
-       // determine charge pump
-       tuner_frequency = p->frequency + 36125000;
-       if (tuner_frequency < 87000000)
-               return -EINVAL;
-       else if (tuner_frequency < 130000000) {
-               cp = 3;
-               band = 1;
-       } else if (tuner_frequency < 160000000) {
-               cp = 5;
-               band = 1;
-       } else if (tuner_frequency < 200000000) {
-               cp = 6;
-               band = 1;
-       } else if (tuner_frequency < 290000000) {
-               cp = 3;
-               band = 2;
-       } else if (tuner_frequency < 420000000) {
-               cp = 5;
-               band = 2;
-       } else if (tuner_frequency < 480000000) {
-               cp = 6;
-               band = 2;
-       } else if (tuner_frequency < 620000000) {
-               cp = 3;
-               band = 4;
-       } else if (tuner_frequency < 830000000) {
-               cp = 5;
-               band = 4;
-       } else if (tuner_frequency < 895000000) {
-               cp = 7;
-               band = 4;
-       } else
-               return -EINVAL;
-
-       // assume PLL filter should always be 8MHz for the moment.
-       filter = 1;
-
-       // calculate divisor
-       tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500;
-
-       // setup tuner buffer
-       tuner_buf[0] = tuner_frequency >> 8;
-       tuner_buf[1] = tuner_frequency & 0xff;
-       tuner_buf[2] = 0xc8;
-       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
-       tuner_buf[4] = 0x80;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-
-       msleep(50);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
-               return -EIO;
-
-       msleep(1);
-
-       return 0;
-}
-
-static u8 dvbc_philips_tdm1316l_inittab[] = {
-       0x80, 0x01,
-       0x80, 0x00,
-       0x81, 0x01,
-       0x81, 0x00,
-       0x00, 0x09,
-       0x01, 0x69,
-       0x03, 0x00,
-       0x04, 0x00,
-       0x07, 0x00,
-       0x08, 0x00,
-       0x20, 0x00,
-       0x21, 0x40,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x24, 0x40,
-       0x25, 0x88,
-       0x30, 0xff,
-       0x31, 0x00,
-       0x32, 0xff,
-       0x33, 0x00,
-       0x34, 0x50,
-       0x35, 0x7f,
-       0x36, 0x00,
-       0x37, 0x20,
-       0x38, 0x00,
-       0x40, 0x1c,
-       0x41, 0xff,
-       0x42, 0x29,
-       0x43, 0x20,
-       0x44, 0xff,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x49, 0x04,
-       0x4a, 0x00,
-       0x4b, 0x7b,
-       0x52, 0x30,
-       0x55, 0xae,
-       0x56, 0x47,
-       0x57, 0xe1,
-       0x58, 0x3a,
-       0x5a, 0x1e,
-       0x5b, 0x34,
-       0x60, 0x00,
-       0x63, 0x00,
-       0x64, 0x00,
-       0x65, 0x00,
-       0x66, 0x00,
-       0x67, 0x00,
-       0x68, 0x00,
-       0x69, 0x00,
-       0x6a, 0x02,
-       0x6b, 0x00,
-       0x70, 0xff,
-       0x71, 0x00,
-       0x72, 0x00,
-       0x73, 0x00,
-       0x74, 0x0c,
-       0x80, 0x00,
-       0x81, 0x00,
-       0x82, 0x00,
-       0x83, 0x00,
-       0x84, 0x04,
-       0x85, 0x80,
-       0x86, 0x24,
-       0x87, 0x78,
-       0x88, 0x10,
-       0x89, 0x00,
-       0x90, 0x01,
-       0x91, 0x01,
-       0xa0, 0x04,
-       0xa1, 0x00,
-       0xa2, 0x00,
-       0xb0, 0x91,
-       0xb1, 0x0b,
-       0xc0, 0x53,
-       0xc1, 0x70,
-       0xc2, 0x12,
-       0xd0, 0x00,
-       0xd1, 0x00,
-       0xd2, 0x00,
-       0xd3, 0x00,
-       0xd4, 0x00,
-       0xd5, 0x00,
-       0xde, 0x00,
-       0xdf, 0x00,
-       0x61, 0x38,
-       0x62, 0x0a,
-       0x53, 0x13,
-       0x59, 0x08,
-       0xff, 0xff,
-};
-
-static struct stv0297_config dvbc_philips_tdm1316l_config = {
-       .demod_address = 0x1c,
-       .inittab = dvbc_philips_tdm1316l_inittab,
-       .invert = 0,
-       .stop_during_read = 1,
-};
-
-static struct tda10023_config tda10023_config = {
-       .demod_address = 0xc,
-       .invert = 0,
-       .xtal = 16000000,
-       .pll_m = 11,
-       .pll_p = 3,
-       .pll_n = 1,
-       .deltaf = 0xa511,
-};
-
-static struct tda827x_config tda827x_config = {
-       .config = 0,
-};
-
-/* TT S2-3200 DVB-S (STB0899) Inittab */
-static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
-
-       { STB0899_DEV_ID                , 0x81 },
-       { STB0899_DISCNTRL1             , 0x32 },
-       { STB0899_DISCNTRL2             , 0x80 },
-       { STB0899_DISRX_ST0             , 0x04 },
-       { STB0899_DISRX_ST1             , 0x00 },
-       { STB0899_DISPARITY             , 0x00 },
-       { STB0899_DISSTATUS             , 0x20 },
-       { STB0899_DISF22                , 0x8c },
-       { STB0899_DISF22RX              , 0x9a },
-       { STB0899_SYSREG                , 0x0b },
-       { STB0899_ACRPRESC              , 0x11 },
-       { STB0899_ACRDIV1               , 0x0a },
-       { STB0899_ACRDIV2               , 0x05 },
-       { STB0899_DACR1                 , 0x00 },
-       { STB0899_DACR2                 , 0x00 },
-       { STB0899_OUTCFG                , 0x00 },
-       { STB0899_MODECFG               , 0x00 },
-       { STB0899_IRQSTATUS_3           , 0x30 },
-       { STB0899_IRQSTATUS_2           , 0x00 },
-       { STB0899_IRQSTATUS_1           , 0x00 },
-       { STB0899_IRQSTATUS_0           , 0x00 },
-       { STB0899_IRQMSK_3              , 0xf3 },
-       { STB0899_IRQMSK_2              , 0xfc },
-       { STB0899_IRQMSK_1              , 0xff },
-       { STB0899_IRQMSK_0              , 0xff },
-       { STB0899_IRQCFG                , 0x00 },
-       { STB0899_I2CCFG                , 0x88 },
-       { STB0899_I2CRPT                , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
-       { STB0899_IOPVALUE5             , 0x00 },
-       { STB0899_IOPVALUE4             , 0x20 },
-       { STB0899_IOPVALUE3             , 0xc9 },
-       { STB0899_IOPVALUE2             , 0x90 },
-       { STB0899_IOPVALUE1             , 0x40 },
-       { STB0899_IOPVALUE0             , 0x00 },
-       { STB0899_GPIO00CFG             , 0x82 },
-       { STB0899_GPIO01CFG             , 0x82 },
-       { STB0899_GPIO02CFG             , 0x82 },
-       { STB0899_GPIO03CFG             , 0x82 },
-       { STB0899_GPIO04CFG             , 0x82 },
-       { STB0899_GPIO05CFG             , 0x82 },
-       { STB0899_GPIO06CFG             , 0x82 },
-       { STB0899_GPIO07CFG             , 0x82 },
-       { STB0899_GPIO08CFG             , 0x82 },
-       { STB0899_GPIO09CFG             , 0x82 },
-       { STB0899_GPIO10CFG             , 0x82 },
-       { STB0899_GPIO11CFG             , 0x82 },
-       { STB0899_GPIO12CFG             , 0x82 },
-       { STB0899_GPIO13CFG             , 0x82 },
-       { STB0899_GPIO14CFG             , 0x82 },
-       { STB0899_GPIO15CFG             , 0x82 },
-       { STB0899_GPIO16CFG             , 0x82 },
-       { STB0899_GPIO17CFG             , 0x82 },
-       { STB0899_GPIO18CFG             , 0x82 },
-       { STB0899_GPIO19CFG             , 0x82 },
-       { STB0899_GPIO20CFG             , 0x82 },
-       { STB0899_SDATCFG               , 0xb8 },
-       { STB0899_SCLTCFG               , 0xba },
-       { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
-       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
-       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
-       { STB0899_DIRCLKCFG             , 0x82 },
-       { STB0899_CLKOUT27CFG           , 0x7e },
-       { STB0899_STDBYCFG              , 0x82 },
-       { STB0899_CS0CFG                , 0x82 },
-       { STB0899_CS1CFG                , 0x82 },
-       { STB0899_DISEQCOCFG            , 0x20 },
-       { STB0899_GPIO32CFG             , 0x82 },
-       { STB0899_GPIO33CFG             , 0x82 },
-       { STB0899_GPIO34CFG             , 0x82 },
-       { STB0899_GPIO35CFG             , 0x82 },
-       { STB0899_GPIO36CFG             , 0x82 },
-       { STB0899_GPIO37CFG             , 0x82 },
-       { STB0899_GPIO38CFG             , 0x82 },
-       { STB0899_GPIO39CFG             , 0x82 },
-       { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-       { STB0899_FILTCTRL              , 0x00 },
-       { STB0899_SYSCTRL               , 0x00 },
-       { STB0899_STOPCLK1              , 0x20 },
-       { STB0899_STOPCLK2              , 0x00 },
-       { STB0899_INTBUFSTATUS          , 0x00 },
-       { STB0899_INTBUFCTRL            , 0x0a },
-       { 0xffff                        , 0xff },
-};
-
-static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
-       { STB0899_DEMOD                 , 0x00 },
-       { STB0899_RCOMPC                , 0xc9 },
-       { STB0899_AGC1CN                , 0x41 },
-       { STB0899_AGC1REF               , 0x10 },
-       { STB0899_RTC                   , 0x7a },
-       { STB0899_TMGCFG                , 0x4e },
-       { STB0899_AGC2REF               , 0x34 },
-       { STB0899_TLSR                  , 0x84 },
-       { STB0899_CFD                   , 0xc7 },
-       { STB0899_ACLC                  , 0x87 },
-       { STB0899_BCLC                  , 0x94 },
-       { STB0899_EQON                  , 0x41 },
-       { STB0899_LDT                   , 0xdd },
-       { STB0899_LDT2                  , 0xc9 },
-       { STB0899_EQUALREF              , 0xb4 },
-       { STB0899_TMGRAMP               , 0x10 },
-       { STB0899_TMGTHD                , 0x30 },
-       { STB0899_IDCCOMP               , 0xfb },
-       { STB0899_QDCCOMP               , 0x03 },
-       { STB0899_POWERI                , 0x3b },
-       { STB0899_POWERQ                , 0x3d },
-       { STB0899_RCOMP                 , 0x81 },
-       { STB0899_AGCIQIN               , 0x80 },
-       { STB0899_AGC2I1                , 0x04 },
-       { STB0899_AGC2I2                , 0xf5 },
-       { STB0899_TLIR                  , 0x25 },
-       { STB0899_RTF                   , 0x80 },
-       { STB0899_DSTATUS               , 0x00 },
-       { STB0899_LDI                   , 0xca },
-       { STB0899_CFRM                  , 0xf1 },
-       { STB0899_CFRL                  , 0xf3 },
-       { STB0899_NIRM                  , 0x2a },
-       { STB0899_NIRL                  , 0x05 },
-       { STB0899_ISYMB                 , 0x17 },
-       { STB0899_QSYMB                 , 0xfa },
-       { STB0899_SFRH                  , 0x2f },
-       { STB0899_SFRM                  , 0x68 },
-       { STB0899_SFRL                  , 0x40 },
-       { STB0899_SFRUPH                , 0x2f },
-       { STB0899_SFRUPM                , 0x68 },
-       { STB0899_SFRUPL                , 0x40 },
-       { STB0899_EQUAI1                , 0xfd },
-       { STB0899_EQUAQ1                , 0x04 },
-       { STB0899_EQUAI2                , 0x0f },
-       { STB0899_EQUAQ2                , 0xff },
-       { STB0899_EQUAI3                , 0xdf },
-       { STB0899_EQUAQ3                , 0xfa },
-       { STB0899_EQUAI4                , 0x37 },
-       { STB0899_EQUAQ4                , 0x0d },
-       { STB0899_EQUAI5                , 0xbd },
-       { STB0899_EQUAQ5                , 0xf7 },
-       { STB0899_DSTATUS2              , 0x00 },
-       { STB0899_VSTATUS               , 0x00 },
-       { STB0899_VERROR                , 0xff },
-       { STB0899_IQSWAP                , 0x2a },
-       { STB0899_ECNT1M                , 0x00 },
-       { STB0899_ECNT1L                , 0x00 },
-       { STB0899_ECNT2M                , 0x00 },
-       { STB0899_ECNT2L                , 0x00 },
-       { STB0899_ECNT3M                , 0x00 },
-       { STB0899_ECNT3L                , 0x00 },
-       { STB0899_FECAUTO1              , 0x06 },
-       { STB0899_FECM                  , 0x01 },
-       { STB0899_VTH12                 , 0xf0 },
-       { STB0899_VTH23                 , 0xa0 },
-       { STB0899_VTH34                 , 0x78 },
-       { STB0899_VTH56                 , 0x4e },
-       { STB0899_VTH67                 , 0x48 },
-       { STB0899_VTH78                 , 0x38 },
-       { STB0899_PRVIT                 , 0xff },
-       { STB0899_VITSYNC               , 0x19 },
-       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-       { STB0899_TSULC                 , 0x42 },
-       { STB0899_RSLLC                 , 0x40 },
-       { STB0899_TSLPL                 , 0x12 },
-       { STB0899_TSCFGH                , 0x0c },
-       { STB0899_TSCFGM                , 0x00 },
-       { STB0899_TSCFGL                , 0x0c },
-       { STB0899_TSOUT                 , 0x4d }, /* 0x0d for CAM */
-       { STB0899_RSSYNCDEL             , 0x00 },
-       { STB0899_TSINHDELH             , 0x02 },
-       { STB0899_TSINHDELM             , 0x00 },
-       { STB0899_TSINHDELL             , 0x00 },
-       { STB0899_TSLLSTKM              , 0x00 },
-       { STB0899_TSLLSTKL              , 0x00 },
-       { STB0899_TSULSTKM              , 0x00 },
-       { STB0899_TSULSTKL              , 0xab },
-       { STB0899_PCKLENUL              , 0x00 },
-       { STB0899_PCKLENLL              , 0xcc },
-       { STB0899_RSPCKLEN              , 0xcc },
-       { STB0899_TSSTATUS              , 0x80 },
-       { STB0899_ERRCTRL1              , 0xb6 },
-       { STB0899_ERRCTRL2              , 0x96 },
-       { STB0899_ERRCTRL3              , 0x89 },
-       { STB0899_DMONMSK1              , 0x27 },
-       { STB0899_DMONMSK0              , 0x03 },
-       { STB0899_DEMAPVIT              , 0x5c },
-       { STB0899_PLPARM                , 0x1f },
-       { STB0899_PDELCTRL              , 0x48 },
-       { STB0899_PDELCTRL2             , 0x00 },
-       { STB0899_BBHCTRL1              , 0x00 },
-       { STB0899_BBHCTRL2              , 0x00 },
-       { STB0899_HYSTTHRESH            , 0x77 },
-       { STB0899_MATCSTM               , 0x00 },
-       { STB0899_MATCSTL               , 0x00 },
-       { STB0899_UPLCSTM               , 0x00 },
-       { STB0899_UPLCSTL               , 0x00 },
-       { STB0899_DFLCSTM               , 0x00 },
-       { STB0899_DFLCSTL               , 0x00 },
-       { STB0899_SYNCCST               , 0x00 },
-       { STB0899_SYNCDCSTM             , 0x00 },
-       { STB0899_SYNCDCSTL             , 0x00 },
-       { STB0899_ISI_ENTRY             , 0x00 },
-       { STB0899_ISI_BIT_EN            , 0x00 },
-       { STB0899_MATSTRM               , 0x00 },
-       { STB0899_MATSTRL               , 0x00 },
-       { STB0899_UPLSTRM               , 0x00 },
-       { STB0899_UPLSTRL               , 0x00 },
-       { STB0899_DFLSTRM               , 0x00 },
-       { STB0899_DFLSTRL               , 0x00 },
-       { STB0899_SYNCSTR               , 0x00 },
-       { STB0899_SYNCDSTRM             , 0x00 },
-       { STB0899_SYNCDSTRL             , 0x00 },
-       { STB0899_CFGPDELSTATUS1        , 0x10 },
-       { STB0899_CFGPDELSTATUS2        , 0x00 },
-       { STB0899_BBFERRORM             , 0x00 },
-       { STB0899_BBFERRORL             , 0x00 },
-       { STB0899_UPKTERRORM            , 0x00 },
-       { STB0899_UPKTERRORL            , 0x00 },
-       { 0xffff                        , 0xff },
-};
-
-static struct stb0899_config tt3200_config = {
-       .init_dev               = tt3200_stb0899_s1_init_1,
-       .init_s2_demod          = stb0899_s2_init_2,
-       .init_s1_demod          = tt3200_stb0899_s1_init_3,
-       .init_s2_fec            = stb0899_s2_init_4,
-       .init_tst               = stb0899_s1_init_5,
-
-       .postproc               = NULL,
-
-       .demod_address          = 0x68,
-
-       .xtal_freq              = 27000000,
-       .inversion              = IQ_SWAP_ON, /* 1 */
-
-       .lo_clk                 = 76500000,
-       .hi_clk                 = 99000000,
-
-       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
-       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
-       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
-       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
-       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
-       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
-       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
-       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
-       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
-
-       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
-       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
-       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
-       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
-
-       .tuner_get_frequency    = stb6100_get_frequency,
-       .tuner_set_frequency    = stb6100_set_frequency,
-       .tuner_set_bandwidth    = stb6100_set_bandwidth,
-       .tuner_get_bandwidth    = stb6100_get_bandwidth,
-       .tuner_set_rfsiggain    = NULL
-};
-
-static struct stb6100_config tt3200_stb6100_config = {
-       .tuner_address  = 0x60,
-       .refclock       = 27000000,
-};
-
-static void frontend_init(struct budget_ci *budget_ci)
-{
-       switch (budget_ci->budget.dev->pci->subsystem_device) {
-       case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
-               budget_ci->budget.dvb_frontend =
-                       dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
-                       budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
-                       break;
-               }
-               break;
-
-       case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
-               budget_ci->budget.dvb_frontend =
-                       dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1010:            // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
-               budget_ci->tuner_pll_address = 0x61;
-               budget_ci->budget.dvb_frontend =
-                       dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
-               budget_ci->tuner_pll_address = 0x63;
-               budget_ci->budget.dvb_frontend =
-                       dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1012:            // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
-               budget_ci->tuner_pll_address = 0x60;
-               budget_ci->budget.dvb_frontend =
-                       dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1017:            // TT S-1500 PCI
-               budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
-                       budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
-
-                       budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
-                       if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
-                               printk("%s: No LNBP21 found!\n", __func__);
-                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                               budget_ci->budget.dvb_frontend = NULL;
-                       }
-               }
-               break;
-
-       case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
-               budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
-               if (budget_ci->budget.dvb_frontend) {
-                       if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
-                               printk(KERN_ERR "%s: No tda827x found!\n", __func__);
-                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                               budget_ci->budget.dvb_frontend = NULL;
-                       }
-               }
-               break;
-
-       case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
-               budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
-                               if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
-                                       printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
-                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                                       budget_ci->budget.dvb_frontend = NULL;
-                               }
-                       } else {
-                               printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
-                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                               budget_ci->budget.dvb_frontend = NULL;
-                       }
-               }
-               break;
-
-       case 0x1019:            // TT S2-3200 PCI
-               /*
-                * NOTE! on some STB0899 versions, the internal PLL takes a longer time
-                * to settle, aka LOCK. On the older revisions of the chip, we don't see
-                * this, as a result on the newer chips the entire clock tree, will not
-                * be stable after a freshly POWER 'ed up situation.
-                * In this case, we should RESET the STB0899 (Active LOW) and wait for
-                * PLL stabilization.
-                *
-                * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
-                * connected to the SAA7146 GPIO, GPIO2, Pin 142
-                */
-               /* Reset Demodulator */
-               saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
-               /* Wait for everything to die */
-               msleep(50);
-               /* Pull it up out of Reset state */
-               saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
-               /* Wait for PLL to stabilize */
-               msleep(250);
-               /*
-                * PLL state should be stable now. Ideally, we should check
-                * for PLL LOCK status. But well, never mind!
-                */
-               budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
-               if (budget_ci->budget.dvb_frontend) {
-                       if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
-                               if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
-                                       printk("%s: No LNBP21 found!\n", __func__);
-                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                                       budget_ci->budget.dvb_frontend = NULL;
-                               }
-                       } else {
-                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                                       budget_ci->budget.dvb_frontend = NULL;
-                       }
-               }
-               break;
-
-       }
-
-       if (budget_ci->budget.dvb_frontend == NULL) {
-               printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      budget_ci->budget.dev->pci->vendor,
-                      budget_ci->budget.dev->pci->device,
-                      budget_ci->budget.dev->pci->subsystem_vendor,
-                      budget_ci->budget.dev->pci->subsystem_device);
-       } else {
-               if (dvb_register_frontend
-                   (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
-                       printk("budget-ci: Frontend registration failed!\n");
-                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-                       budget_ci->budget.dvb_frontend = NULL;
-               }
-       }
-}
-
-static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-{
-       struct budget_ci *budget_ci;
-       int err;
-
-       budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
-       if (!budget_ci) {
-               err = -ENOMEM;
-               goto out1;
-       }
-
-       dprintk(2, "budget_ci: %p\n", budget_ci);
-
-       dev->ext_priv = budget_ci;
-
-       err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
-                               adapter_nr);
-       if (err)
-               goto out2;
-
-       err = msp430_ir_init(budget_ci);
-       if (err)
-               goto out3;
-
-       ciintf_init(budget_ci);
-
-       budget_ci->budget.dvb_adapter.priv = budget_ci;
-       frontend_init(budget_ci);
-
-       ttpci_budget_init_hooks(&budget_ci->budget);
-
-       return 0;
-
-out3:
-       ttpci_budget_deinit(&budget_ci->budget);
-out2:
-       kfree(budget_ci);
-out1:
-       return err;
-}
-
-static int budget_ci_detach(struct saa7146_dev *dev)
-{
-       struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
-       struct saa7146_dev *saa = budget_ci->budget.dev;
-       int err;
-
-       if (budget_ci->budget.ci_present)
-               ciintf_deinit(budget_ci);
-       msp430_ir_deinit(budget_ci);
-       if (budget_ci->budget.dvb_frontend) {
-               dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
-               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
-       }
-       err = ttpci_budget_deinit(&budget_ci->budget);
-
-       // disable frontend and CI interface
-       saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
-
-       kfree(budget_ci);
-
-       return err;
-}
-
-static struct saa7146_extension budget_extension;
-
-MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
-MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T         PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
-
-static struct pci_device_id pci_tbl[] = {
-       MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
-       MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
-       MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
-       MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
-       MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
-       MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
-       MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
-       MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
-       MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
-       {
-        .vendor = 0,
-        }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_extension budget_extension = {
-       .name = "budget_ci dvb",
-       .flags = SAA7146_USE_I2C_IRQ,
-
-       .module = THIS_MODULE,
-       .pci_tbl = &pci_tbl[0],
-       .attach = budget_ci_attach,
-       .detach = budget_ci_detach,
-
-       .irq_mask = MASK_03 | MASK_06 | MASK_10,
-       .irq_func = budget_ci_irq,
-};
-
-static int __init budget_ci_init(void)
-{
-       return saa7146_register_extension(&budget_extension);
-}
-
-static void __exit budget_ci_exit(void)
-{
-       saa7146_unregister_extension(&budget_extension);
-}
-
-module_init(budget_ci_init);
-module_exit(budget_ci_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
-MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
-                  "budget PCI DVB cards w/ CI-module produced by "
-                  "Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
deleted file mode 100644 (file)
index 37d02fe..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * budget-core.c: driver for the SAA7146 based Budget DVB cards
- *
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                      & Marcus Metzler for convergence integrated media GmbH
- *
- * 26feb2004 Support for FS Activy Card (Grundig tuner) by
- *          Michael Dreher <michael@5dot1.de>,
- *          Oliver Endriss <o.endriss@gmx.de>,
- *          Andreas 'randy' Weinberger
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-
-#include "budget.h"
-#include "ttpci-eeprom.h"
-
-#define TS_WIDTH               (2 * TS_SIZE)
-#define TS_WIDTH_ACTIVY                TS_SIZE
-#define TS_WIDTH_DVBC          TS_SIZE
-#define TS_HEIGHT_MASK         0xf00
-#define TS_HEIGHT_MASK_ACTIVY  0xc00
-#define TS_HEIGHT_MASK_DVBC    0xe00
-#define TS_MIN_BUFSIZE_K       188
-#define TS_MAX_BUFSIZE_K       1410
-#define TS_MAX_BUFSIZE_K_ACTIVY        564
-#define TS_MAX_BUFSIZE_K_DVBC  1316
-#define BUFFER_WARNING_WAIT    (30*HZ)
-
-int budget_debug;
-static int dma_buffer_size = TS_MIN_BUFSIZE_K;
-module_param_named(debug, budget_debug, int, 0644);
-module_param_named(bufsize, dma_buffer_size, int, 0444);
-MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
-MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)");
-
-/****************************************************************************
- * TT budget / WinTV Nova
- ****************************************************************************/
-
-static int stop_ts_capture(struct budget *budget)
-{
-       dprintk(2, "budget: %p\n", budget);
-
-       saa7146_write(budget->dev, MC1, MASK_20);       // DMA3 off
-       SAA7146_IER_DISABLE(budget->dev, MASK_10);
-       return 0;
-}
-
-static int start_ts_capture(struct budget *budget)
-{
-       struct saa7146_dev *dev = budget->dev;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       if (!budget->feeding || !budget->fe_synced)
-               return 0;
-
-       saa7146_write(dev, MC1, MASK_20);       // DMA3 off
-
-       memset(budget->grabbing, 0x00, budget->buffer_size);
-
-       saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
-
-       budget->ttbp = 0;
-
-       /*
-        *  Signal path on the Activy:
-        *
-        *  tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory
-        *
-        *  Since the tuner feeds 204 bytes packets into the SAA7146,
-        *  DMA3 is configured to strip the trailing 16 FEC bytes:
-        *      Pitch: 188, NumBytes3: 188, NumLines3: 1024
-        */
-
-       switch(budget->card->type) {
-       case BUDGET_FS_ACTIVY:
-               saa7146_write(dev, DD1_INIT, 0x04000000);
-               saa7146_write(dev, MC2, (MASK_09 | MASK_25));
-               saa7146_write(dev, BRS_CTRL, 0x00000000);
-               break;
-       case BUDGET_PATCH:
-               saa7146_write(dev, DD1_INIT, 0x00000200);
-               saa7146_write(dev, MC2, (MASK_10 | MASK_26));
-               saa7146_write(dev, BRS_CTRL, 0x60000000);
-               break;
-       case BUDGET_CIN1200C_MK3:
-       case BUDGET_KNC1C_MK3:
-       case BUDGET_KNC1C_TDA10024:
-       case BUDGET_KNC1CP_MK3:
-               if (budget->video_port == BUDGET_VIDEO_PORTA) {
-                       saa7146_write(dev, DD1_INIT, 0x06000200);
-                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-                       saa7146_write(dev, BRS_CTRL, 0x00000000);
-               } else {
-                       saa7146_write(dev, DD1_INIT, 0x00000600);
-                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-                       saa7146_write(dev, BRS_CTRL, 0x60000000);
-               }
-               break;
-       default:
-               if (budget->video_port == BUDGET_VIDEO_PORTA) {
-                       saa7146_write(dev, DD1_INIT, 0x06000200);
-                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-                       saa7146_write(dev, BRS_CTRL, 0x00000000);
-               } else {
-                       saa7146_write(dev, DD1_INIT, 0x02000600);
-                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-                       saa7146_write(dev, BRS_CTRL, 0x60000000);
-               }
-       }
-
-       saa7146_write(dev, MC2, (MASK_08 | MASK_24));
-       mdelay(10);
-
-       saa7146_write(dev, BASE_ODD3, 0);
-       if (budget->buffer_size > budget->buffer_height * budget->buffer_width) {
-               // using odd/even buffers
-               saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width);
-       } else {
-               // using a single buffer
-               saa7146_write(dev, BASE_EVEN3, 0);
-       }
-       saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
-       saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
-
-       saa7146_write(dev, PITCH3, budget->buffer_width);
-       saa7146_write(dev, NUM_LINE_BYTE3,
-                       (budget->buffer_height << 16) | budget->buffer_width);
-
-       saa7146_write(dev, MC2, (MASK_04 | MASK_20));
-
-       SAA7146_ISR_CLEAR(budget->dev, MASK_10);        /* VPE */
-       SAA7146_IER_ENABLE(budget->dev, MASK_10);       /* VPE */
-       saa7146_write(dev, MC1, (MASK_04 | MASK_20));   /* DMA3 on */
-
-       return 0;
-}
-
-static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct budget *budget = (struct budget *) fe->dvb->priv;
-       int synced;
-       int ret;
-
-       if (budget->read_fe_status)
-               ret = budget->read_fe_status(fe, status);
-       else
-               ret = -EINVAL;
-
-       if (!ret) {
-               synced = (*status & FE_HAS_LOCK);
-               if (synced != budget->fe_synced) {
-                       budget->fe_synced = synced;
-                       spin_lock(&budget->feedlock);
-                       if (synced)
-                               start_ts_capture(budget);
-                       else
-                               stop_ts_capture(budget);
-                       spin_unlock(&budget->feedlock);
-               }
-       }
-       return ret;
-}
-
-static void vpeirq(unsigned long data)
-{
-       struct budget *budget = (struct budget *) data;
-       u8 *mem = (u8 *) (budget->grabbing);
-       u32 olddma = budget->ttbp;
-       u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
-       u32 count;
-
-       /* Ensure streamed PCI data is synced to CPU */
-       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
-
-       /* nearest lower position divisible by 188 */
-       newdma -= newdma % 188;
-
-       if (newdma >= budget->buffer_size)
-               return;
-
-       budget->ttbp = newdma;
-
-       if (budget->feeding == 0 || newdma == olddma)
-               return;
-
-       if (newdma > olddma) {  /* no wraparound, dump olddma..newdma */
-               count = newdma - olddma;
-               dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
-       } else {                /* wraparound, dump olddma..buflen and 0..newdma */
-               count = budget->buffer_size - olddma;
-               dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
-               count += newdma;
-               dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
-       }
-
-       if (count > budget->buffer_warning_threshold)
-               budget->buffer_warnings++;
-
-       if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) {
-               printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n",
-                       budget->dev->name, __func__, budget->buffer_warnings, count);
-               budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT;
-               budget->buffer_warnings = 0;
-       }
-}
-
-
-int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
-                         int uselocks, int nobusyloop)
-{
-       struct saa7146_dev *saa = budget->dev;
-       int result = 0;
-       unsigned long flags = 0;
-
-       if (count > 4 || count <= 0)
-               return 0;
-
-       if (uselocks)
-               spin_lock_irqsave(&budget->debilock, flags);
-
-       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
-               if (uselocks)
-                       spin_unlock_irqrestore(&budget->debilock, flags);
-               return result;
-       }
-
-       saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
-       saa7146_write(saa, DEBI_CONFIG, config);
-       saa7146_write(saa, DEBI_PAGE, 0);
-       saa7146_write(saa, MC2, (2 << 16) | 2);
-
-       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
-               if (uselocks)
-                       spin_unlock_irqrestore(&budget->debilock, flags);
-               return result;
-       }
-
-       result = saa7146_read(saa, DEBI_AD);
-       result &= (0xffffffffUL >> ((4 - count) * 8));
-
-       if (uselocks)
-               spin_unlock_irqrestore(&budget->debilock, flags);
-
-       return result;
-}
-
-int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr,
-                          int count, u32 value, int uselocks, int nobusyloop)
-{
-       struct saa7146_dev *saa = budget->dev;
-       unsigned long flags = 0;
-       int result;
-
-       if (count > 4 || count <= 0)
-               return 0;
-
-       if (uselocks)
-               spin_lock_irqsave(&budget->debilock, flags);
-
-       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
-               if (uselocks)
-                       spin_unlock_irqrestore(&budget->debilock, flags);
-               return result;
-       }
-
-       saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff));
-       saa7146_write(saa, DEBI_CONFIG, config);
-       saa7146_write(saa, DEBI_PAGE, 0);
-       saa7146_write(saa, DEBI_AD, value);
-       saa7146_write(saa, MC2, (2 << 16) | 2);
-
-       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
-               if (uselocks)
-                       spin_unlock_irqrestore(&budget->debilock, flags);
-               return result;
-       }
-
-       if (uselocks)
-               spin_unlock_irqrestore(&budget->debilock, flags);
-       return 0;
-}
-
-
-/****************************************************************************
- * DVB API SECTION
- ****************************************************************************/
-
-static int budget_start_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct budget *budget = (struct budget *) demux->priv;
-       int status = 0;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       if (!demux->dmx.frontend)
-               return -EINVAL;
-
-       spin_lock(&budget->feedlock);
-       feed->pusi_seen = 0; /* have a clean section start */
-       if (budget->feeding++ == 0)
-               status = start_ts_capture(budget);
-       spin_unlock(&budget->feedlock);
-       return status;
-}
-
-static int budget_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct dvb_demux *demux = feed->demux;
-       struct budget *budget = (struct budget *) demux->priv;
-       int status = 0;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       spin_lock(&budget->feedlock);
-       if (--budget->feeding == 0)
-               status = stop_ts_capture(budget);
-       spin_unlock(&budget->feedlock);
-       return status;
-}
-
-static int budget_register(struct budget *budget)
-{
-       struct dvb_demux *dvbdemux = &budget->demux;
-       int ret;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       dvbdemux->priv = (void *) budget;
-
-       dvbdemux->filternum = 256;
-       dvbdemux->feednum = 256;
-       dvbdemux->start_feed = budget_start_feed;
-       dvbdemux->stop_feed = budget_stop_feed;
-       dvbdemux->write_to_decoder = NULL;
-
-       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
-                                     DMX_MEMORY_BASED_FILTERING);
-
-       dvb_dmx_init(&budget->demux);
-
-       budget->dmxdev.filternum = 256;
-       budget->dmxdev.demux = &dvbdemux->dmx;
-       budget->dmxdev.capabilities = 0;
-
-       dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter);
-
-       budget->hw_frontend.source = DMX_FRONTEND_0;
-
-       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
-
-       if (ret < 0)
-               return ret;
-
-       budget->mem_frontend.source = DMX_MEMORY_FE;
-       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
-       if (ret < 0)
-               return ret;
-
-       ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);
-       if (ret < 0)
-               return ret;
-
-       dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
-
-       return 0;
-}
-
-static void budget_unregister(struct budget *budget)
-{
-       struct dvb_demux *dvbdemux = &budget->demux;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       dvb_net_release(&budget->dvb_net);
-
-       dvbdemux->dmx.close(&dvbdemux->dmx);
-       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
-       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
-
-       dvb_dmxdev_release(&budget->dmxdev);
-       dvb_dmx_release(&budget->demux);
-}
-
-int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
-                     struct saa7146_pci_extension_data *info,
-                     struct module *owner, short *adapter_nums)
-{
-       int ret = 0;
-       struct budget_info *bi = info->ext_priv;
-       int max_bufsize;
-       int height_mask;
-
-       memset(budget, 0, sizeof(struct budget));
-
-       dprintk(2, "dev: %p, budget: %p\n", dev, budget);
-
-       budget->card = bi;
-       budget->dev = (struct saa7146_dev *) dev;
-
-       switch(budget->card->type) {
-       case BUDGET_FS_ACTIVY:
-               budget->buffer_width = TS_WIDTH_ACTIVY;
-               max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
-               height_mask = TS_HEIGHT_MASK_ACTIVY;
-               break;
-
-       case BUDGET_KNC1C:
-       case BUDGET_KNC1CP:
-       case BUDGET_CIN1200C:
-       case BUDGET_KNC1C_MK3:
-       case BUDGET_KNC1C_TDA10024:
-       case BUDGET_KNC1CP_MK3:
-       case BUDGET_CIN1200C_MK3:
-               budget->buffer_width = TS_WIDTH_DVBC;
-               max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
-               height_mask = TS_HEIGHT_MASK_DVBC;
-               break;
-
-       default:
-               budget->buffer_width = TS_WIDTH;
-               max_bufsize = TS_MAX_BUFSIZE_K;
-               height_mask = TS_HEIGHT_MASK;
-       }
-
-       if (dma_buffer_size < TS_MIN_BUFSIZE_K)
-               dma_buffer_size = TS_MIN_BUFSIZE_K;
-       else if (dma_buffer_size > max_bufsize)
-               dma_buffer_size = max_bufsize;
-
-       budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
-       if (budget->buffer_height > 0xfff) {
-               budget->buffer_height /= 2;
-               budget->buffer_height &= height_mask;
-               budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
-       } else {
-               budget->buffer_height &= height_mask;
-               budget->buffer_size = budget->buffer_height * budget->buffer_width;
-       }
-       budget->buffer_warning_threshold = budget->buffer_size * 80/100;
-       budget->buffer_warnings = 0;
-       budget->buffer_warning_time = jiffies;
-
-       dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
-               budget->dev->name,
-               budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
-               budget->buffer_width, budget->buffer_height);
-       printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
-
-       ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name,
-                                  owner, &budget->dev->pci->dev, adapter_nums);
-       if (ret < 0)
-               return ret;
-
-       /* set dd1 stream a & b */
-       saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-       saa7146_write(dev, MC2, (MASK_09 | MASK_25));
-       saa7146_write(dev, MC2, (MASK_10 | MASK_26));
-       saa7146_write(dev, DD1_INIT, 0x02000000);
-       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
-       if (bi->type != BUDGET_FS_ACTIVY)
-               budget->video_port = BUDGET_VIDEO_PORTB;
-       else
-               budget->video_port = BUDGET_VIDEO_PORTA;
-       spin_lock_init(&budget->feedlock);
-       spin_lock_init(&budget->debilock);
-
-       /* the Siemens DVB needs this if you want to have the i2c chips
-          get recognized before the main driver is loaded */
-       if (bi->type != BUDGET_FS_ACTIVY)
-               saa7146_write(dev, GPIO_CTRL, 0x500000);        /* GPIO 3 = 1 */
-
-       strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
-
-       saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
-       strcpy(budget->i2c_adap.name, budget->card->name);
-
-       if (i2c_add_adapter(&budget->i2c_adap) < 0) {
-               ret = -ENOMEM;
-               goto err_dvb_unregister;
-       }
-
-       ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
-
-       budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
-       if (NULL == budget->grabbing) {
-               ret = -ENOMEM;
-               goto err_del_i2c;
-       }
-
-       saa7146_write(dev, PCI_BT_V1, 0x001c0000);
-       /* upload all */
-       saa7146_write(dev, GPIO_CTRL, 0x000000);
-
-       tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
-
-       /* frontend power on */
-       if (bi->type != BUDGET_FS_ACTIVY)
-               saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-
-       if ((ret = budget_register(budget)) == 0)
-               return 0; /* Everything OK */
-
-       /* An error occurred, cleanup resources */
-       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
-
-err_del_i2c:
-       i2c_del_adapter(&budget->i2c_adap);
-
-err_dvb_unregister:
-       dvb_unregister_adapter(&budget->dvb_adapter);
-
-       return ret;
-}
-
-void ttpci_budget_init_hooks(struct budget *budget)
-{
-       if (budget->dvb_frontend && !budget->read_fe_status) {
-               budget->read_fe_status = budget->dvb_frontend->ops.read_status;
-               budget->dvb_frontend->ops.read_status = budget_read_fe_status;
-       }
-}
-
-int ttpci_budget_deinit(struct budget *budget)
-{
-       struct saa7146_dev *dev = budget->dev;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       budget_unregister(budget);
-
-       tasklet_kill(&budget->vpe_tasklet);
-
-       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
-
-       i2c_del_adapter(&budget->i2c_adap);
-
-       dvb_unregister_adapter(&budget->dvb_adapter);
-
-       return 0;
-}
-
-void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr)
-{
-       struct budget *budget = (struct budget *) dev->ext_priv;
-
-       dprintk(8, "dev: %p, budget: %p\n", dev, budget);
-
-       if (*isr & MASK_10)
-               tasklet_schedule(&budget->vpe_tasklet);
-}
-
-void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
-{
-       struct budget *budget = (struct budget *) dev->ext_priv;
-
-       spin_lock(&budget->feedlock);
-       budget->video_port = video_port;
-       if (budget->feeding) {
-               stop_ts_capture(budget);
-               start_ts_capture(budget);
-       }
-       spin_unlock(&budget->feedlock);
-}
-
-EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
-EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
-EXPORT_SYMBOL_GPL(ttpci_budget_init);
-EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks);
-EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
-EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
-EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
-EXPORT_SYMBOL_GPL(budget_debug);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
deleted file mode 100644 (file)
index 2cb35c2..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * budget-patch.c: driver for Budget Patch,
- * hardware modification of DVB-S cards enabling full TS
- *
- * Written by Emard <emard@softhome.net>
- *
- * Original idea by Roberto Deza <rdeza@unav.es>
- *
- * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
- * and Metzlerbros
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "budget.h"
-#include "stv0299.h"
-#include "ves1x93.h"
-#include "tda8083.h"
-
-#include "bsru6.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define budget_patch budget
-
-static struct saa7146_extension budget_extension;
-
-MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
-//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
-
-static struct pci_device_id pci_tbl[] = {
-       MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
-//        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
-       {
-               .vendor    = 0,
-       }
-};
-
-/* those lines are for budget-patch to be tried
-** on a true budget card and observe the
-** behaviour of VSYNC generated by rps1.
-** this code was shamelessly copy/pasted from budget.c
-*/
-static void gpio_Set22K (struct budget *budget, int state)
-{
-       struct saa7146_dev *dev=budget->dev;
-       dprintk(2, "budget: %p\n", budget);
-       saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
-}
-
-/* Diseqc functions only for TT Budget card */
-/* taken from the Skyvision DVB driver by
-   Ralph Metzler <rjkm@metzlerbros.de> */
-
-static void DiseqcSendBit (struct budget *budget, int data)
-{
-       struct saa7146_dev *dev=budget->dev;
-       dprintk(2, "budget: %p\n", budget);
-
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-       udelay(data ? 500 : 1000);
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       udelay(data ? 1000 : 500);
-}
-
-static void DiseqcSendByte (struct budget *budget, int data)
-{
-       int i, par=1, d;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       for (i=7; i>=0; i--) {
-               d = (data>>i)&1;
-               par ^= d;
-               DiseqcSendBit(budget, d);
-       }
-
-       DiseqcSendBit(budget, par);
-}
-
-static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
-{
-       struct saa7146_dev *dev=budget->dev;
-       int i;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       mdelay(16);
-
-       for (i=0; i<len; i++)
-               DiseqcSendByte(budget, msg[i]);
-
-       mdelay(16);
-
-       if (burst!=-1) {
-               if (burst)
-                       DiseqcSendByte(budget, 0xff);
-               else {
-                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-                       mdelay(12);
-                       udelay(500);
-                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-               }
-               msleep(20);
-       }
-
-       return 0;
-}
-
-/* shamelessly copy/pasted from budget.c
-*/
-static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               gpio_Set22K (budget, 1);
-               break;
-
-       case SEC_TONE_OFF:
-               gpio_Set22K (budget, 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
-
-       return 0;
-}
-
-static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       SendDiSEqCMsg (budget, 0, NULL, minicmd);
-
-       return 0;
-}
-
-static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
-{
-       int i;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       for (i = 2; i < length; i++)
-       {
-                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
-                 msleep(5);
-       }
-       if (length)
-                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
-       else
-                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
-       msleep(5);
-       ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
-       msleep(5);
-       return 0;
-}
-
-static void av7110_set22k(struct budget_patch *budget, int state)
-{
-       u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
-
-       dprintk(2, "budget: %p\n", budget);
-       budget_av7110_send_fw_cmd(budget, buf, 2);
-}
-
-static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
-{
-       int i;
-       u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
-               16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-       dprintk(2, "budget: %p\n", budget);
-
-       if (len>10)
-               len=10;
-
-       buf[1] = len+2;
-       buf[2] = len;
-
-       if (burst != -1)
-               buf[3]=burst ? 0x01 : 0x00;
-       else
-               buf[3]=0xffff;
-
-       for (i=0; i<len; i++)
-               buf[i+4]=msg[i];
-
-       budget_av7110_send_fw_cmd(budget, buf, 18);
-       return 0;
-}
-
-static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               av7110_set22k (budget, 1);
-               break;
-
-       case SEC_TONE_OFF:
-               av7110_set22k (budget, 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-{
-       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
-       av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
-
-       return 0;
-}
-
-static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
-       av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
-
-       return 0;
-}
-
-static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-       u8 pwr = 0;
-       u8 buf[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-       u32 div = (p->frequency + 479500) / 125;
-
-       if (p->frequency > 2000000)
-               pwr = 3;
-       else if (p->frequency > 1800000)
-               pwr = 2;
-       else if (p->frequency > 1600000)
-               pwr = 1;
-       else if (p->frequency > 1200000)
-               pwr = 0;
-       else if (p->frequency >= 1100000)
-               pwr = 1;
-       else pwr = 2;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = ((div & 0x18000) >> 10) | 0x95;
-       buf[3] = (pwr << 6) | 0x30;
-
-       // NOTE: since we're using a prescaler of 2, we set the
-       // divisor frequency to 62.5kHz and divide by 125 above
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct ves1x93_config alps_bsrv2_config = {
-       .demod_address = 0x08,
-       .xin = 90100000UL,
-       .invert_pwm = 0,
-};
-
-static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = p->frequency / 125;
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x8e;
-       data[3] = 0x00;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct tda8083_config grundig_29504_451_config = {
-       .demod_address = 0x68,
-};
-
-static void frontend_init(struct budget_patch* budget)
-{
-       switch(budget->dev->pci->subsystem_device) {
-       case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
-       case 0x1013: // SATELCO Multimedia PCI
-
-               // try the ALPS BSRV2 first of all
-               budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
-                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
-                       budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
-                       budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
-                       break;
-               }
-
-               // try the ALPS BSRU6 now
-               budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
-                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-
-                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
-                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
-                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
-                       break;
-               }
-
-               // Try the grundig 29504-451
-               budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
-                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
-                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
-                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
-                       break;
-               }
-               break;
-       }
-
-       if (budget->dvb_frontend == NULL) {
-               printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      budget->dev->pci->vendor,
-                      budget->dev->pci->device,
-                      budget->dev->pci->subsystem_vendor,
-                      budget->dev->pci->subsystem_device);
-       } else {
-               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
-                       printk("budget-av: Frontend registration failed!\n");
-                       dvb_frontend_detach(budget->dvb_frontend);
-                       budget->dvb_frontend = NULL;
-               }
-       }
-}
-
-/* written by Emard */
-static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
-{
-       struct budget_patch *budget;
-       int err;
-       int count = 0;
-       int detected = 0;
-
-#define PATCH_RESET 0
-#define RPS_IRQ 0
-#define HPS_SETUP 0
-#if PATCH_RESET
-       saa7146_write(dev, MC1, MASK_31);
-       msleep(40);
-#endif
-#if HPS_SETUP
-       // initialize registers. Better to have it like this
-       // than leaving something unconfigured
-       saa7146_write(dev, DD1_STREAM_B, 0);
-       // port B VSYNC at rising edge
-       saa7146_write(dev, DD1_INIT, 0x00000200);  // have this in budget-core too!
-       saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
-
-       // debi config
-       // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
-
-       // zero all HPS registers
-       saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
-       saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
-       saa7146_write(dev, BCS_CTRL, 0);                        // r70
-       saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
-       saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
-       saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
-       saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
-       // Set HPS prescaler for port B input
-       saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
-       saa7146_write(dev, MC2,
-         0 * (MASK_08 | MASK_24)  |   // BRS control
-         0 * (MASK_09 | MASK_25)  |   // a
-         0 * (MASK_10 | MASK_26)  |   // b
-         1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
-         1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
-         0 * (MASK_01 | MASK_15)      // DEBI
-          );
-#endif
-       // Disable RPS1 and RPS0
-       saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
-       // RPS1 timeout disable
-       saa7146_write(dev, RPS_TOV1, 0);
-
-       // code for autodetection
-       // will wait for VBI_B event (vertical blank at port B)
-       // and will reset GPIO3 after VBI_B is detected.
-       // (GPIO3 should be raised high by CPU to
-       // test if GPIO3 will generate vertical blank signal
-       // in budget patch GPIO3 is connected to VSYNC_B
-       count = 0;
-#if 0
-       WRITE_RPS1(CMD_UPLOAD |
-         MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
-#endif
-       WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
-       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-       WRITE_RPS1(GPIO3_MSK);
-       WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
-       // issue RPS1 interrupt to increment counter
-       WRITE_RPS1(CMD_INTERRUPT);
-       // at least a NOP is neede between two interrupts
-       WRITE_RPS1(CMD_NOP);
-       // interrupt again
-       WRITE_RPS1(CMD_INTERRUPT);
-#endif
-       WRITE_RPS1(CMD_STOP);
-
-#if RPS_IRQ
-       // set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
-       // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
-       // use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
-       saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-       // set event counter 1 threshold to maximum allowed value        (rEC p55)
-       saa7146_write(dev, ECT1R,  0x3fff );
-#endif
-       // Fix VSYNC level
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       // Set RPS1 Address register to point to RPS code               (r108 p42)
-       saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-       // Enable RPS1,                                                 (rFC p33)
-       saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
-
-
-       mdelay(50);
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-       mdelay(150);
-
-
-       if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
-               detected = 1;
-
-#if RPS_IRQ
-       printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
-#endif
-       // Disable RPS1
-       saa7146_write(dev, MC1, ( MASK_29 ));
-
-       if(detected == 0)
-               printk("budget-patch not detected or saa7146 in non-default state.\n"
-                      "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
-
-       else
-               printk("BUDGET-PATCH DETECTED.\n");
-
-
-/*      OLD (Original design by Roberto Deza):
-**      This code will setup the SAA7146_RPS1 to generate a square
-**      wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
-**      TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
-**      then, this GPIO3 output which is connected to the D1B_VSYNC
-**      input, will trigger the acquisition of the alternate field
-**      and so on.
-**      Currently, the TT_budget / WinTV_Nova cards have two ICs
-**      (74HCT4040, LVC74) for the generation of this VSYNC signal,
-**      which seems that can be done perfectly without this :-)).
-*/
-
-/*      New design (By Emard)
-**      this rps1 code will copy internal HS event to GPIO3 pin.
-**      GPIO3 is in budget-patch hardware connected to port B VSYNC
-
-**      HS is an internal event of 7146, accessible with RPS
-**      and temporarily raised high every n lines
-**      (n in defined in the RPS_THRESH1 counter threshold)
-**      I think HS is raised high on the beginning of the n-th line
-**      and remains high until this n-th line that triggered
-**      it is completely received. When the reception of n-th line
-**      ends, HS is lowered.
-
-**      To transmit data over DMA, 7146 needs changing state at
-**      port B VSYNC pin. Any changing of port B VSYNC will
-**      cause some DMA data transfer, with more or less packets loss.
-**      It depends on the phase and frequency of VSYNC and
-**      the way of 7146 is instructed to trigger on port B (defined
-**      in DD1_INIT register, 3rd nibble from the right valid
-**      numbers are 0-7, see datasheet)
-**
-**      The correct triggering can minimize packet loss,
-**      dvbtraffic should give this stable bandwidths:
-**        22k transponder = 33814 kbit/s
-**      27.5k transponder = 38045 kbit/s
-**      by experiment it is found that the best results
-**      (stable bandwidths and almost no packet loss)
-**      are obtained using DD1_INIT triggering number 2
-**      (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
-**      and a VSYNC phase that occurs in the middle of DMA transfer
-**      (about byte 188*512=96256 in the DMA window).
-**
-**      Phase of HS is still not clear to me how to control,
-**      It just happens to be so. It can be seen if one enables
-**      RPS_IRQ and print Event Counter 1 in vpeirq(). Every
-**      time RPS_INTERRUPT is called, the Event Counter 1 will
-**      increment. That's how the 7146 is programmed to do event
-**      counting in this budget-patch.c
-**      I *think* HPS setting has something to do with the phase
-**      of HS but I can't be 100% sure in that.
-
-**      hardware debug note: a working budget card (including budget patch)
-**      with vpeirq() interrupt setup in mode "0x90" (every 64K) will
-**      generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
-**      and that means 3*25=75 Hz of interrupt frequency, as seen by
-**      watch cat /proc/interrupts
-**
-**      If this frequency is 3x lower (and data received in the DMA
-**      buffer don't start with 0x47, but in the middle of packets,
-**      whose lengths appear to be like 188 292 188 104 etc.
-**      this means VSYNC line is not connected in the hardware.
-**      (check soldering pcb and pins)
-**      The same behaviour of missing VSYNC can be duplicated on budget
-**      cards, by setting DD1_INIT trigger mode 7 in 3rd nibble.
-*/
-
-       // Setup RPS1 "program" (p35)
-       count = 0;
-
-
-       // Wait Source Line Counter Threshold                           (p36)
-       WRITE_RPS1(CMD_PAUSE | EVT_HS);
-       // Set GPIO3=1                                                  (p42)
-       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-       WRITE_RPS1(GPIO3_MSK);
-       WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
-#if RPS_IRQ
-       // issue RPS1 interrupt
-       WRITE_RPS1(CMD_INTERRUPT);
-#endif
-       // Wait reset Source Line Counter Threshold                     (p36)
-       WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
-       // Set GPIO3=0                                                  (p42)
-       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
-       WRITE_RPS1(GPIO3_MSK);
-       WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
-       // issue RPS1 interrupt
-       WRITE_RPS1(CMD_INTERRUPT);
-#endif
-       // Jump to begin of RPS program                                 (p37)
-       WRITE_RPS1(CMD_JUMP);
-       WRITE_RPS1(dev->d_rps1.dma_handle);
-
-       // Fix VSYNC level
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       // Set RPS1 Address register to point to RPS code               (r108 p42)
-       saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-
-       if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
-               return -ENOMEM;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
-       if (err) {
-               kfree(budget);
-               return err;
-       }
-
-       // Set Source Line Counter Threshold, using BRS                 (rCC p43)
-       // It generates HS event every TS_HEIGHT lines
-       // this is related to TS_WIDTH set in register
-       // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
-       // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
-       //,then RPS_THRESH1
-       // should be set to trigger every TS_HEIGHT (512) lines.
-       //
-       saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
-
-       // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
-       // Enable RPS1                                                  (rFC p33)
-       saa7146_write(dev, MC1, (MASK_13 | MASK_29));
-
-
-       dev->ext_priv = budget;
-
-       budget->dvb_adapter.priv = budget;
-       frontend_init(budget);
-
-       ttpci_budget_init_hooks(budget);
-
-       return 0;
-}
-
-static int budget_patch_detach (struct saa7146_dev* dev)
-{
-       struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
-       int err;
-
-       if (budget->dvb_frontend) {
-               dvb_unregister_frontend(budget->dvb_frontend);
-               dvb_frontend_detach(budget->dvb_frontend);
-       }
-       err = ttpci_budget_deinit (budget);
-
-       kfree (budget);
-
-       return err;
-}
-
-static int __init budget_patch_init(void)
-{
-       return saa7146_register_extension(&budget_extension);
-}
-
-static void __exit budget_patch_exit(void)
-{
-       saa7146_unregister_extension(&budget_extension);
-}
-
-static struct saa7146_extension budget_extension = {
-       .name           = "budget_patch dvb",
-       .flags          = 0,
-
-       .module         = THIS_MODULE,
-       .pci_tbl        = pci_tbl,
-       .attach         = budget_patch_attach,
-       .detach         = budget_patch_detach,
-
-       .irq_mask       = MASK_10,
-       .irq_func       = ttpci_budget_irq10_handler,
-};
-
-module_init(budget_patch_init);
-module_exit(budget_patch_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
-MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
-                  "based so-called Budget Patch cards");
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
deleted file mode 100644 (file)
index 7e6e43a..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * budget.c: driver for the SAA7146 based Budget DVB cards
- *
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- *
- * 26feb2004 Support for FS Activy Card (Grundig tuner) by
- *           Michael Dreher <michael@5dot1.de>,
- *           Oliver Endriss <o.endriss@gmx.de> and
- *           Andreas 'randy' Weinberger
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org/ 
- */
-
-#include "budget.h"
-#include "stv0299.h"
-#include "ves1x93.h"
-#include "ves1820.h"
-#include "l64781.h"
-#include "tda8083.h"
-#include "s5h1420.h"
-#include "tda10086.h"
-#include "tda826x.h"
-#include "lnbp21.h"
-#include "bsru6.h"
-#include "bsbe1.h"
-#include "tdhd1.h"
-#include "stv6110x.h"
-#include "stv090x.h"
-#include "isl6423.h"
-#include "lnbh24.h"
-
-
-static int diseqc_method;
-module_param(diseqc_method, int, 0444);
-MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static void Set22K (struct budget *budget, int state)
-{
-       struct saa7146_dev *dev=budget->dev;
-       dprintk(2, "budget: %p\n", budget);
-       saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
-}
-
-/* Diseqc functions only for TT Budget card */
-/* taken from the Skyvision DVB driver by
-   Ralph Metzler <rjkm@metzlerbros.de> */
-
-static void DiseqcSendBit (struct budget *budget, int data)
-{
-       struct saa7146_dev *dev=budget->dev;
-       dprintk(2, "budget: %p\n", budget);
-
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-       udelay(data ? 500 : 1000);
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       udelay(data ? 1000 : 500);
-}
-
-static void DiseqcSendByte (struct budget *budget, int data)
-{
-       int i, par=1, d;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       for (i=7; i>=0; i--) {
-               d = (data>>i)&1;
-               par ^= d;
-               DiseqcSendBit(budget, d);
-       }
-
-       DiseqcSendBit(budget, par);
-}
-
-static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
-{
-       struct saa7146_dev *dev=budget->dev;
-       int i;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-       mdelay(16);
-
-       for (i=0; i<len; i++)
-               DiseqcSendByte(budget, msg[i]);
-
-       mdelay(16);
-
-       if (burst!=-1) {
-               if (burst)
-                       DiseqcSendByte(budget, 0xff);
-               else {
-                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
-                       mdelay(12);
-                       udelay(500);
-                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-               }
-               msleep(20);
-       }
-
-       return 0;
-}
-
-/*
- *   Routines for the Fujitsu Siemens Activy budget card
- *   22 kHz tone and DiSEqC are handled by the frontend.
- *   Voltage must be set here.
- *   GPIO 1: LNBP EN, GPIO 2: LNBP VSEL
- */
-static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
-{
-       struct saa7146_dev *dev=budget->dev;
-
-       dprintk(2, "budget: %p\n", budget);
-
-       switch (voltage) {
-               case SEC_VOLTAGE_13:
-                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
-                       saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
-                       break;
-               case SEC_VOLTAGE_18:
-                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
-                       saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-                       break;
-               case SEC_VOLTAGE_OFF:
-                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       return SetVoltage_Activy (budget, voltage);
-}
-
-static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               Set22K (budget, 1);
-               break;
-
-       case SEC_TONE_OFF:
-               Set22K (budget, 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
-
-       return 0;
-}
-
-static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-
-       SendDiSEqCMsg (budget, 0, NULL, minicmd);
-
-       return 0;
-}
-
-static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u8 pwr = 0;
-       u8 buf[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-       u32 div = (c->frequency + 479500) / 125;
-
-       if (c->frequency > 2000000)
-               pwr = 3;
-       else if (c->frequency > 1800000)
-               pwr = 2;
-       else if (c->frequency > 1600000)
-               pwr = 1;
-       else if (c->frequency > 1200000)
-               pwr = 0;
-       else if (c->frequency >= 1100000)
-               pwr = 1;
-       else pwr = 2;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = ((div & 0x18000) >> 10) | 0x95;
-       buf[3] = (pwr << 6) | 0x30;
-
-       // NOTE: since we're using a prescaler of 2, we set the
-       // divisor frequency to 62.5kHz and divide by 125 above
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct ves1x93_config alps_bsrv2_config =
-{
-       .demod_address = 0x08,
-       .xin = 90100000UL,
-       .invert_pwm = 0,
-};
-
-static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = (c->frequency + 35937500 + 31250) / 62500;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x85 | ((div >> 10) & 0x60);
-       data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct ves1820_config alps_tdbe2_config = {
-       .demod_address = 0x09,
-       .xin = 57840000UL,
-       .invert = 1,
-       .selagc = VES1820_SELAGC_SIGNAMPERR,
-};
-
-static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget *budget = fe->dvb->priv;
-       u8 *tuner_addr = fe->tuner_priv;
-       u32 div;
-       u8 cfg, cpump, band_select;
-       u8 data[4];
-       struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if (tuner_addr)
-               msg.addr = *tuner_addr;
-       else
-               msg.addr = 0x61;
-
-       div = (36125000 + c->frequency) / 166666;
-
-       cfg = 0x88;
-
-       if (c->frequency < 175000000)
-               cpump = 2;
-       else if (c->frequency < 390000000)
-               cpump = 1;
-       else if (c->frequency < 470000000)
-               cpump = 2;
-       else if (c->frequency < 750000000)
-               cpump = 1;
-       else
-               cpump = 3;
-
-       if (c->frequency < 175000000)
-               band_select = 0x0e;
-       else if (c->frequency < 470000000)
-               band_select = 0x05;
-       else
-               band_select = 0x03;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = ((div >> 10) & 0x60) | cfg;
-       data[3] = (cpump << 6) | band_select;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct l64781_config grundig_29504_401_config = {
-       .demod_address = 0x55,
-};
-
-static struct l64781_config grundig_29504_401_config_activy = {
-       .demod_address = 0x54,
-};
-
-static u8 tuner_address_grundig_29504_401_activy = 0x60;
-
-static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = c->frequency / 125;
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x8e;
-       data[3] = 0x00;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct tda8083_config grundig_29504_451_config = {
-       .demod_address = 0x68,
-};
-
-static int s5h1420_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u32 div;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       div = c->frequency / 1000;
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0xc2;
-
-       if (div < 1450)
-               data[3] = 0x00;
-       else if (div < 1850)
-               data[3] = 0x40;
-       else if (div < 2000)
-               data[3] = 0x80;
-       else
-               data[3] = 0xc0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       return 0;
-}
-
-static struct s5h1420_config s5h1420_config = {
-       .demod_address = 0x53,
-       .invert = 1,
-       .cdclk_polarity = 1,
-};
-
-static struct tda10086_config tda10086_config = {
-       .demod_address = 0x0e,
-       .invert = 0,
-       .diseqc_tone = 1,
-       .xtal_freq = TDA10086_XTAL_16M,
-};
-
-static struct stv0299_config alps_bsru6_config_activy = {
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .op0_off = 1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-};
-
-static struct stv0299_config alps_bsbe1_config_activy = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .op0_off = 1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
-};
-
-static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
-{
-       struct budget *budget = (struct budget *)fe->dvb->priv;
-
-       return request_firmware(fw, name, &budget->dev->pci->dev);
-}
-
-
-static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg)
-{
-       u8 val;
-       struct i2c_msg msg[] = {
-               { .addr = adr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-       };
-
-       return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val;
-}
-
-static u8 read_pwm(struct budget* budget)
-{
-       u8 b = 0xff;
-       u8 pwm;
-       struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
-                                { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
-
-       if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-static struct stv090x_config tt1600_stv090x_config = {
-       .device                 = STV0903,
-       .demod_mode             = STV090x_SINGLE,
-       .clk_mode               = STV090x_CLK_EXT,
-
-       .xtal                   = 13500000,
-       .address                = 0x68,
-
-       .ts1_mode               = STV090x_TSMODE_DVBCI,
-       .ts2_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
-
-       .repeater_level         = STV090x_RPTLEVEL_16,
-
-       .tuner_init             = NULL,
-       .tuner_sleep            = NULL,
-       .tuner_set_mode         = NULL,
-       .tuner_set_frequency    = NULL,
-       .tuner_get_frequency    = NULL,
-       .tuner_set_bandwidth    = NULL,
-       .tuner_get_bandwidth    = NULL,
-       .tuner_set_bbgain       = NULL,
-       .tuner_get_bbgain       = NULL,
-       .tuner_set_refclk       = NULL,
-       .tuner_get_status       = NULL,
-};
-
-static struct stv6110x_config tt1600_stv6110x_config = {
-       .addr                   = 0x60,
-       .refclk                 = 27000000,
-       .clk_div                = 2,
-};
-
-static struct isl6423_config tt1600_isl6423_config = {
-       .current_max            = SEC_CURRENT_515m,
-       .curlim                 = SEC_CURRENT_LIM_ON,
-       .mod_extern             = 1,
-       .addr                   = 0x08,
-};
-
-static void frontend_init(struct budget *budget)
-{
-       (void)alps_bsbe1_config; /* avoid warning */
-
-       switch(budget->dev->pci->subsystem_device) {
-       case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
-       case 0x1013:
-               // try the ALPS BSRV2 first of all
-               budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
-                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
-                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
-                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
-                       break;
-               }
-
-               // try the ALPS BSRU6 now
-               budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
-                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-                       if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) {
-                               budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
-                               budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
-                               budget->dvb_frontend->ops.set_tone = budget_set_tone;
-                       }
-                       break;
-               }
-               break;
-
-       case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
-
-               budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
-
-               budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
-                       budget->dvb_frontend->tuner_priv = NULL;
-                       break;
-               }
-               break;
-
-       case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */
-       {
-               int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67);
-
-               if (subtype < 0)
-                       break;
-               /* fixme: find a better way to identify the card */
-               if (subtype < 0x36) {
-                       /* assume ALPS BSRU6 */
-                       budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap);
-                       if (budget->dvb_frontend) {
-                               printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n");
-                               budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
-                               budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-                               budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
-                               budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
-                               break;
-                       }
-               } else {
-                       /* assume ALPS BSBE1 */
-                       /* reset tuner */
-                       saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO);
-                       msleep(50);
-                       saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI);
-                       msleep(250);
-                       budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap);
-                       if (budget->dvb_frontend) {
-                               printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n");
-                               budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
-                               budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-                               budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
-                               budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
-                               break;
-                       }
-               }
-               break;
-       }
-
-       case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
-               budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
-                       budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
-                       budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
-               }
-               break;
-
-       case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */
-               budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params;
-                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-               }
-               break;
-
-       case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */
-               budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy;
-                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
-               }
-               break;
-
-       case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
-               budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params;
-                       if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
-                               printk("%s: No LNBP21 found!\n", __func__);
-                               goto error_out;
-                       }
-                       break;
-               }
-
-       case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262)
-               // gpio2 is connected to CLB - reset it + leave it high
-               saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
-               msleep(1);
-               saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
-               msleep(1);
-
-               budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL)
-                               printk("%s: No tda826x found!\n", __func__);
-                       if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
-                               printk("%s: No LNBP21 found!\n", __func__);
-                               goto error_out;
-                       }
-                       break;
-               }
-
-       case 0x101c: { /* TT S2-1600 */
-                       struct stv6110x_devctl *ctl;
-                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
-                       msleep(50);
-                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
-                       msleep(250);
-
-                       budget->dvb_frontend = dvb_attach(stv090x_attach,
-                                                         &tt1600_stv090x_config,
-                                                         &budget->i2c_adap,
-                                                         STV090x_DEMODULATOR_0);
-
-                       if (budget->dvb_frontend) {
-
-                               ctl = dvb_attach(stv6110x_attach,
-                                                budget->dvb_frontend,
-                                                &tt1600_stv6110x_config,
-                                                &budget->i2c_adap);
-
-                               if (ctl) {
-                                       tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
-                                       tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
-                                       tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
-                                       tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
-                                       tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
-                                       tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-                                       tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-                                       tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
-                                       tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
-                                       tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
-                                       tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
-
-                                       /* call the init function once to initialize
-                                          tuner's clock output divider and demod's
-                                          master clock */
-                                       if (budget->dvb_frontend->ops.init)
-                                               budget->dvb_frontend->ops.init(budget->dvb_frontend);
-
-                                       if (dvb_attach(isl6423_attach,
-                                                      budget->dvb_frontend,
-                                                      &budget->i2c_adap,
-                                                      &tt1600_isl6423_config) == NULL) {
-                                               printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__);
-                                               goto error_out;
-                                       }
-                               } else {
-                                       printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
-                                       goto error_out;
-                               }
-                       }
-               }
-               break;
-
-       case 0x1020: { /* Omicom S2 */
-                       struct stv6110x_devctl *ctl;
-                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
-                       msleep(50);
-                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
-                       msleep(250);
-
-                       budget->dvb_frontend = dvb_attach(stv090x_attach,
-                                                         &tt1600_stv090x_config,
-                                                         &budget->i2c_adap,
-                                                         STV090x_DEMODULATOR_0);
-
-                       if (budget->dvb_frontend) {
-                               printk(KERN_INFO "budget: Omicom S2 detected\n");
-
-                               ctl = dvb_attach(stv6110x_attach,
-                                                budget->dvb_frontend,
-                                                &tt1600_stv6110x_config,
-                                                &budget->i2c_adap);
-
-                               if (ctl) {
-                                       tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
-                                       tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
-                                       tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
-                                       tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
-                                       tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
-                                       tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-                                       tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-                                       tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
-                                       tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
-                                       tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
-                                       tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
-
-                                       /* call the init function once to initialize
-                                          tuner's clock output divider and demod's
-                                          master clock */
-                                       if (budget->dvb_frontend->ops.init)
-                                               budget->dvb_frontend->ops.init(budget->dvb_frontend);
-
-                                       if (dvb_attach(lnbh24_attach,
-                                                       budget->dvb_frontend,
-                                                       &budget->i2c_adap,
-                                                       LNBH24_PCL | LNBH24_TTX,
-                                                       LNBH24_TEN, 0x14>>1) == NULL) {
-                                               printk(KERN_ERR
-                                               "No LNBH24 found!\n");
-                                               goto error_out;
-                                       }
-                               } else {
-                                       printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
-                                       goto error_out;
-                               }
-                       }
-               }
-               break;
-       }
-
-       if (budget->dvb_frontend == NULL) {
-               printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
-                      budget->dev->pci->vendor,
-                      budget->dev->pci->device,
-                      budget->dev->pci->subsystem_vendor,
-                      budget->dev->pci->subsystem_device);
-       } else {
-               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
-                       goto error_out;
-       }
-       return;
-
-error_out:
-       printk("budget: Frontend registration failed!\n");
-       dvb_frontend_detach(budget->dvb_frontend);
-       budget->dvb_frontend = NULL;
-       return;
-}
-
-static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
-{
-       struct budget *budget = NULL;
-       int err;
-
-       budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
-       if( NULL == budget ) {
-               return -ENOMEM;
-       }
-
-       dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
-
-       dev->ext_priv = budget;
-
-       err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
-       if (err) {
-               printk("==> failed\n");
-               kfree (budget);
-               return err;
-       }
-
-       budget->dvb_adapter.priv = budget;
-       frontend_init(budget);
-
-       ttpci_budget_init_hooks(budget);
-
-       return 0;
-}
-
-static int budget_detach (struct saa7146_dev* dev)
-{
-       struct budget *budget = (struct budget*) dev->ext_priv;
-       int err;
-
-       if (budget->dvb_frontend) {
-               dvb_unregister_frontend(budget->dvb_frontend);
-               dvb_frontend_detach(budget->dvb_frontend);
-       }
-
-       err = ttpci_budget_deinit (budget);
-
-       kfree (budget);
-       dev->ext_priv = NULL;
-
-       return err;
-}
-
-static struct saa7146_extension budget_extension;
-
-MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S  PCI",  BUDGET_TT);
-MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C  PCI",  BUDGET_TT);
-MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
-MAKE_BUDGET_INFO(satel,        "SATELCO Multimedia PCI",       BUDGET_TT_HW_DISEQC);
-MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
-MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
-MAKE_BUDGET_INFO(fsact,         "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
-MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY);
-MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT);
-
-static struct pci_device_id pci_tbl[] = {
-       MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
-       MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
-       MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
-       MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
-       MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1016),
-       MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
-       MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c),
-       MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
-       MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
-       MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
-       MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61),
-       MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020),
-       {
-               .vendor    = 0,
-       }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-static struct saa7146_extension budget_extension = {
-       .name           = "budget dvb",
-       .flags          = SAA7146_USE_I2C_IRQ,
-
-       .module         = THIS_MODULE,
-       .pci_tbl        = pci_tbl,
-       .attach         = budget_attach,
-       .detach         = budget_detach,
-
-       .irq_mask       = MASK_10,
-       .irq_func       = ttpci_budget_irq10_handler,
-};
-
-static int __init budget_init(void)
-{
-       return saa7146_register_extension(&budget_extension);
-}
-
-static void __exit budget_exit(void)
-{
-       saa7146_unregister_extension(&budget_extension);
-}
-
-module_init(budget_init);
-module_exit(budget_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
-MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
-                  "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
deleted file mode 100644 (file)
index 3d8a806..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-
-#ifndef __BUDGET_DVB__
-#define __BUDGET_DVB__
-
-#include "dvb_frontend.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_filter.h"
-#include "dvb_net.h"
-
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <media/saa7146.h>
-
-extern int budget_debug;
-
-#ifdef dprintk
-#undef dprintk
-#endif
-
-#define dprintk(level,args...) \
-           do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0)
-
-struct budget_info {
-       char *name;
-       int type;
-};
-
-/* place to store all the necessary device information */
-struct budget {
-
-       /* devices */
-       struct dvb_device dvb_dev;
-       struct dvb_net dvb_net;
-
-       struct saa7146_dev *dev;
-
-       struct i2c_adapter i2c_adap;
-       struct budget_info *card;
-
-       unsigned char *grabbing;
-       struct saa7146_pgtable pt;
-
-       struct tasklet_struct fidb_tasklet;
-       struct tasklet_struct vpe_tasklet;
-
-       struct dmxdev dmxdev;
-       struct dvb_demux demux;
-
-       struct dmx_frontend hw_frontend;
-       struct dmx_frontend mem_frontend;
-
-       int ci_present;
-       int video_port;
-
-       u32 buffer_width;
-       u32 buffer_height;
-       u32 buffer_size;
-       u32 buffer_warning_threshold;
-       u32 buffer_warnings;
-       unsigned long buffer_warning_time;
-
-       u32 ttbp;
-       int feeding;
-
-       spinlock_t feedlock;
-
-       spinlock_t debilock;
-
-       struct dvb_adapter dvb_adapter;
-       struct dvb_frontend *dvb_frontend;
-       int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status);
-       int fe_synced;
-
-       void *priv;
-};
-
-#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \
-static struct budget_info x_var ## _info = { \
-       .name=x_name,   \
-       .type=x_type }; \
-static struct saa7146_pci_extension_data x_var = { \
-       .ext_priv = &x_var ## _info, \
-       .ext = &budget_extension };
-
-#define BUDGET_TT                 0
-#define BUDGET_TT_HW_DISEQC       1
-#define BUDGET_PATCH              3
-#define BUDGET_FS_ACTIVY          4
-#define BUDGET_CIN1200S                   5
-#define BUDGET_CIN1200C                   6
-#define BUDGET_CIN1200T                   7
-#define BUDGET_KNC1S              8
-#define BUDGET_KNC1C              9
-#define BUDGET_KNC1T              10
-#define BUDGET_KNC1SP             11
-#define BUDGET_KNC1CP             12
-#define BUDGET_KNC1TP             13
-#define BUDGET_TVSTAR             14
-#define BUDGET_CIN1200C_MK3       15
-#define BUDGET_KNC1C_MK3          16
-#define BUDGET_KNC1CP_MK3         17
-#define BUDGET_KNC1S2              18
-#define BUDGET_KNC1C_TDA10024     19
-
-#define BUDGET_VIDEO_PORTA         0
-#define BUDGET_VIDEO_PORTB         1
-
-extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
-                            struct saa7146_pci_extension_data *info,
-                            struct module *owner, short *adapter_nums);
-extern void ttpci_budget_init_hooks(struct budget *budget);
-extern int ttpci_budget_deinit(struct budget *budget);
-extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
-extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port);
-extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
-                                int uselocks, int nobusyloop);
-extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value,
-                                 int uselocks, int nobusyloop);
-
-#endif
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
deleted file mode 100644 (file)
index 32d4315..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-    Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,
-    decode it and store it in the associated adapter struct for
-    use by dvb_net.c
-
-    This card appear to have the 24C16 write protect held to ground,
-    thus permitting normal read/write operation. Theoretically it
-    would be possible to write routines to burn a different (encoded)
-    MAC address into the EEPROM.
-
-    Robert Schlabbach  GMX
-    Michael Glaum      KVH Industries
-    Holger Waechtler   Convergence
-
-    Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
-                           Metzler Brothers Systementwicklung GbR
-
-    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/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/i2c.h>
-
-#include "ttpci-eeprom.h"
-
-#if 1
-#define dprintk(x...) do { printk(x); } while (0)
-#else
-#define dprintk(x...) do { } while (0)
-#endif
-
-
-static int check_mac_tt(u8 *buf)
-{
-       int i;
-       u16 tmp = 0xffff;
-
-       for (i = 0; i < 8; i++) {
-               tmp  = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
-               tmp ^= (tmp >> 4) & 0x0f;
-               tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
-       }
-       tmp ^= 0xffff;
-       return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
-}
-
-static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
-{
-       u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
-                      0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
-                      0x1d, 0x36, 0x64, 0x78};
-       u8 data[20];
-       int i;
-
-       /* In case there is a sig check failure have the orig contents available */
-       memcpy(data, encodedMAC, 20);
-
-       for (i = 0; i < 20; i++)
-               data[i] ^= xor[i];
-       for (i = 0; i < 10; i++)
-               data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
-                       >> ((data[2 * i + 1] >> 6) & 3);
-
-       if (check_mac_tt(data))
-               return -ENODEV;
-
-       decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];
-       decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];
-       return 0;
-}
-
-int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC)
-{
-       u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
-                      0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
-                      0x1d, 0x36, 0x64, 0x78};
-       u8 data[20];
-       int i;
-
-       memcpy(data, encodedMAC, 20);
-
-       for (i = 0; i < 20; i++)
-               data[i] ^= xor[i];
-       for (i = 0; i < 10; i++)
-               data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
-                       >> ((data[2 * i + 1] >> 6) & 3);
-
-       if (check_mac_tt(data))
-               return -ENODEV;
-
-       decodedMAC[0] = data[2];
-       decodedMAC[1] = data[1];
-       decodedMAC[2] = data[0];
-       decodedMAC[3] = data[6];
-       decodedMAC[4] = data[5];
-       decodedMAC[5] = data[4];
-       return 0;
-}
-EXPORT_SYMBOL(ttpci_eeprom_decode_mac);
-
-static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
-{
-       int ret;
-       u8 b0[] = { 0xcc };
-
-       struct i2c_msg msg[] = {
-               { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },
-               { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 }
-       };
-
-       /* dprintk("%s\n", __func__); */
-
-       ret = i2c_transfer(adapter, msg, 2);
-
-       if (ret != 2)           /* Assume EEPROM isn't there */
-               return (-ENODEV);
-
-       return 0;
-}
-
-
-int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)
-{
-       int ret, i;
-       u8 encodedMAC[20];
-       u8 decodedMAC[6];
-
-       ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);
-
-       if (ret != 0) {         /* Will only be -ENODEV */
-               dprintk("Couldn't read from EEPROM: not there?\n");
-               memset(proposed_mac, 0, 6);
-               return ret;
-       }
-
-       ret = getmac_tt(decodedMAC, encodedMAC);
-       if( ret != 0 ) {
-               dprintk("adapter failed MAC signature check\n");
-               dprintk("encoded MAC from EEPROM was " );
-               for(i=0; i<19; i++) {
-                       dprintk( "%.2x:", encodedMAC[i]);
-               }
-               dprintk("%.2x\n", encodedMAC[19]);
-               memset(proposed_mac, 0, 6);
-               return ret;
-       }
-
-       memcpy(proposed_mac, decodedMAC, 6);
-       dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
-               decodedMAC[0], decodedMAC[1], decodedMAC[2],
-               decodedMAC[3], decodedMAC[4], decodedMAC[5]);
-       return 0;
-}
-
-EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
-MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "
-               "made by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h
deleted file mode 100644 (file)
index dcc33d5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-    Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
-    decode it and store it in associated adapter net device
-
-    Robert Schlabbach  GMX
-    Michael Glaum      KVH Industries
-    Holger Waechtler   Convergence
-
-    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 __TTPCI_EEPROM_H__
-#define __TTPCI_EEPROM_H__
-
-#include <linux/types.h>
-#include <linux/i2c.h>
-
-extern int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC);
-extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac);
-
-#endif
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
new file mode 100644 (file)
index 0000000..3b9164a
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# DVB device configuration
+#
+
+menuconfig DVB_CAPTURE_DRIVERS
+       bool "DVB/ATSC adapters"
+       depends on DVB_CORE
+       default y
+       ---help---
+         Say Y to select Digital TV adapters
+
+if DVB_CAPTURE_DRIVERS && DVB_CORE
+
+comment "Supported SAA7146 based PCI Adapters"
+       depends on DVB_CORE && PCI && I2C
+source "drivers/media/pci/ttpci/Kconfig"
+
+comment "Supported FlexCopII (B2C2) Adapters"
+       depends on DVB_CORE && (PCI || USB) && I2C
+source "drivers/media/pci/b2c2/Kconfig"
+
+comment "Supported BT878 Adapters"
+       depends on DVB_CORE && PCI && I2C
+source "drivers/media/pci/bt8xx/Kconfig"
+
+comment "Supported Pluto2 Adapters"
+       depends on DVB_CORE && PCI && I2C
+source "drivers/media/pci/pluto2/Kconfig"
+
+comment "Supported SDMC DM1105 Adapters"
+       depends on DVB_CORE && PCI && I2C
+source "drivers/media/pci/dm1105/Kconfig"
+
+comment "Supported Earthsoft PT1 Adapters"
+       depends on DVB_CORE && PCI && I2C
+source "drivers/media/pci/pt1/Kconfig"
+
+comment "Supported Mantis Adapters"
+       depends on DVB_CORE && PCI && I2C
+       source "drivers/media/pci/mantis/Kconfig"
+
+comment "Supported nGene Adapters"
+       depends on DVB_CORE && PCI && I2C
+       source "drivers/media/pci/ngene/Kconfig"
+
+comment "Supported ddbridge ('Octopus') Adapters"
+       depends on DVB_CORE && PCI && I2C
+       source "drivers/media/pci/ddbridge/Kconfig"
+
+endif # DVB_CAPTURE_DRIVERS
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
new file mode 100644 (file)
index 0000000..c5fa43a
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# Makefile for the kernel multimedia device drivers.
+#
+
+obj-y        :=        ttpci/          \
+               b2c2/           \
+               bt8xx/          \
+               pluto2/         \
+               dm1105/         \
+               pt1/            \
+               mantis/         \
+               ngene/          \
+               ddbridge/
diff --git a/drivers/media/pci/b2c2/Kconfig b/drivers/media/pci/b2c2/Kconfig
new file mode 100644 (file)
index 0000000..9e57814
--- /dev/null
@@ -0,0 +1,45 @@
+config DVB_B2C2_FLEXCOP
+       tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
+       depends on DVB_CORE && I2C
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_MT312 if !DVB_FE_CUSTOMISE
+       select DVB_NXT200X if !DVB_FE_CUSTOMISE
+       select DVB_STV0297 if !DVB_FE_CUSTOMISE
+       select DVB_BCM3510 if !DVB_FE_CUSTOMISE
+       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_S5H1420 if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
+       select DVB_ISL6421 if !DVB_FE_CUSTOMISE
+       select DVB_CX24123 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+       select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
+       help
+         Support for the digital TV receiver chip made by B2C2 Inc. included in
+         Technisats PCI cards and USB boxes.
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_PCI
+       tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
+       depends on DVB_B2C2_FLEXCOP && PCI && I2C
+       help
+         Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_USB
+       tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
+       depends on DVB_B2C2_FLEXCOP && USB && I2C
+       help
+         Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_DEBUG
+       bool "Enable debug for the B2C2 FlexCop drivers"
+       depends on DVB_B2C2_FLEXCOP
+       help
+         Say Y if you want to enable the module option to control debug messages
+         of all B2C2 FlexCop drivers.
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
new file mode 100644 (file)
index 0000000..7a1f5ce
--- /dev/null
@@ -0,0 +1,16 @@
+b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
+       flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
+
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
+b2c2-flexcop-pci-objs = flexcop-pci.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
+
+b2c2-flexcop-usb-objs = flexcop-usb.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/common/tuners/
diff --git a/drivers/media/pci/b2c2/flexcop-common.h b/drivers/media/pci/b2c2/flexcop-common.h
new file mode 100644 (file)
index 0000000..437912e
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-common.h - common header file for device-specific source files
+ * see flexcop.c for copyright information
+ */
+#ifndef __FLEXCOP_COMMON_H__
+#define __FLEXCOP_COMMON_H__
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+
+#include "flexcop-reg.h"
+
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+#include "dvb_frontend.h"
+
+#define FC_MAX_FEED 256
+
+#ifndef FC_LOG_PREFIX
+#warning please define a log prefix for your file, using a default one
+#define FC_LOG_PREFIX "b2c2-undef"
+#endif
+
+/* Steal from usb.h */
+#undef err
+#define err(format, arg...) \
+       printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) \
+       printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) \
+       printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+
+struct flexcop_dma {
+       struct pci_dev *pdev;
+
+       u8 *cpu_addr0;
+       dma_addr_t dma_addr0;
+       u8 *cpu_addr1;
+       dma_addr_t dma_addr1;
+       u32 size; /* size of each address in bytes */
+};
+
+struct flexcop_i2c_adapter {
+       struct flexcop_device *fc;
+       struct i2c_adapter i2c_adap;
+
+       u8 no_base_addr;
+       flexcop_i2c_port_t port;
+};
+
+/* Control structure for data definitions that are common to
+ * the B2C2-based PCI and USB devices.
+ */
+struct flexcop_device {
+       /* general */
+       struct device *dev; /* for firmware_class */
+
+#define FC_STATE_DVB_INIT 0x01
+#define FC_STATE_I2C_INIT 0x02
+#define FC_STATE_FE_INIT  0x04
+       int init_state;
+
+       /* device information */
+       int has_32_hw_pid_filter;
+       flexcop_revision_t rev;
+       flexcop_device_type_t dev_type;
+       flexcop_bus_t bus_type;
+
+       /* dvb stuff */
+       struct dvb_adapter dvb_adapter;
+       struct dvb_frontend *fe;
+       struct dvb_net dvbnet;
+       struct dvb_demux demux;
+       struct dmxdev dmxdev;
+       struct dmx_frontend hw_frontend;
+       struct dmx_frontend mem_frontend;
+       int (*fe_sleep) (struct dvb_frontend *);
+
+       struct flexcop_i2c_adapter fc_i2c_adap[3];
+       struct mutex i2c_mutex;
+       struct module *owner;
+
+       /* options and status */
+       int extra_feedcount;
+       int feedcount;
+       int pid_filtering;
+       int fullts_streaming_state;
+
+       /* bus specific callbacks */
+       flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+                       flexcop_ibi_register);
+       int (*write_ibi_reg) (struct flexcop_device *,
+                       flexcop_ibi_register, flexcop_ibi_value);
+       int (*i2c_request) (struct flexcop_i2c_adapter *,
+               flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+       int (*stream_control) (struct flexcop_device *, int);
+       int (*get_mac_addr) (struct flexcop_device *fc, int extended);
+       void *bus_specific;
+};
+
+/* exported prototypes */
+
+/* from flexcop.c */
+void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
+void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
+
+struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
+void flexcop_device_kfree(struct flexcop_device *);
+
+int flexcop_device_initialize(struct flexcop_device *);
+void flexcop_device_exit(struct flexcop_device *fc);
+void flexcop_reset_block_300(struct flexcop_device *fc);
+
+/* from flexcop-dma.c */
+int flexcop_dma_allocate(struct pci_dev *pdev,
+               struct flexcop_dma *dma, u32 size);
+void flexcop_dma_free(struct flexcop_dma *dma);
+
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+               flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+               flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
+               flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+               flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
+               int onoff);
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+               flexcop_dma_index_t dma_idx, u8 cycles);
+
+/* from flexcop-eeprom.c */
+/* the PCI part uses this call to get the MAC address, the USB part has its own */
+int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
+
+/* from flexcop-i2c.c */
+/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
+ * one. We have it in flexcop-i2c.c, because it is going via the actual
+ * I2C-channel of the flexcop.
+ */
+int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
+       u8 chipaddr, u8 addr, u8 *buf, u16 len);
+
+/* from flexcop-sram.c */
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+       flexcop_sram_dest_target_t target);
+void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
+void flexcop_sram_ctrl(struct flexcop_device *fc,
+               int usb_wan, int sramdma, int maximumfill);
+
+/* global prototypes for the flexcop-chip */
+/* from flexcop-fe-tuner.c */
+int flexcop_frontend_init(struct flexcop_device *fc);
+void flexcop_frontend_exit(struct flexcop_device *fc);
+
+/* from flexcop-i2c.c */
+int flexcop_i2c_init(struct flexcop_device *fc);
+void flexcop_i2c_exit(struct flexcop_device *fc);
+
+/* from flexcop-sram.c */
+int flexcop_sram_init(struct flexcop_device *fc);
+
+/* from flexcop-misc.c */
+void flexcop_determine_revision(struct flexcop_device *fc);
+void flexcop_device_name(struct flexcop_device *fc,
+               const char *prefix, const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc,
+               flexcop_ibi_register reg, int num);
+
+/* from flexcop-hw-filter.c */
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+               struct dvb_demux_feed *dvbdmxfeed, int onoff);
+void flexcop_hw_filter_init(struct flexcop_device *fc);
+
+void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
+
+void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
+void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop-dma.c b/drivers/media/pci/b2c2/flexcop-dma.c
new file mode 100644 (file)
index 0000000..2881e0d
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+int flexcop_dma_allocate(struct pci_dev *pdev,
+               struct flexcop_dma *dma, u32 size)
+{
+       u8 *tcpu;
+       dma_addr_t tdma = 0;
+
+       if (size % 2) {
+               err("dma buffersize has to be even.");
+               return -EINVAL;
+       }
+
+       if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) {
+               dma->pdev = pdev;
+               dma->cpu_addr0 = tcpu;
+               dma->dma_addr0 = tdma;
+               dma->cpu_addr1 = tcpu + size/2;
+               dma->dma_addr1 = tdma + size/2;
+               dma->size = size/2;
+               return 0;
+       }
+       return -ENOMEM;
+}
+EXPORT_SYMBOL(flexcop_dma_allocate);
+
+void flexcop_dma_free(struct flexcop_dma *dma)
+{
+       pci_free_consistent(dma->pdev, dma->size*2,
+                       dma->cpu_addr0, dma->dma_addr0);
+       memset(dma,0,sizeof(struct flexcop_dma));
+}
+EXPORT_SYMBOL(flexcop_dma_free);
+
+int flexcop_dma_config(struct flexcop_device *fc,
+               struct flexcop_dma *dma,
+               flexcop_dma_index_t dma_idx)
+{
+       flexcop_ibi_value v0x0,v0x4,v0xc;
+       v0x0.raw = v0x4.raw = v0xc.raw = 0;
+
+       v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+       v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
+       v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
+
+       if ((dma_idx & FC_DMA_1) == dma_idx) {
+               fc->write_ibi_reg(fc,dma1_000,v0x0);
+               fc->write_ibi_reg(fc,dma1_004,v0x4);
+               fc->write_ibi_reg(fc,dma1_00c,v0xc);
+       } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+               fc->write_ibi_reg(fc,dma2_010,v0x0);
+               fc->write_ibi_reg(fc,dma2_014,v0x4);
+               fc->write_ibi_reg(fc,dma2_01c,v0xc);
+       } else {
+               err("either DMA1 or DMA2 can be configured within one "
+                       "flexcop_dma_config call.");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_config);
+
+/* start the DMA transfers, but not the DMA IRQs */
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+               flexcop_dma_index_t dma_idx,
+               flexcop_dma_addr_index_t index,
+               int onoff)
+{
+       flexcop_ibi_value v0x0,v0xc;
+       flexcop_ibi_register r0x0,r0xc;
+
+       if ((dma_idx & FC_DMA_1) == dma_idx) {
+               r0x0 = dma1_000;
+               r0xc = dma1_00c;
+       } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+               r0x0 = dma2_010;
+               r0xc = dma2_01c;
+       } else {
+               err("either transfer DMA1 or DMA2 can be started within one "
+                       "flexcop_dma_xfer_control call.");
+               return -EINVAL;
+       }
+
+       v0x0 = fc->read_ibi_reg(fc,r0x0);
+       v0xc = fc->read_ibi_reg(fc,r0xc);
+
+       deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+       deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+
+       if (index & FC_DMA_SUBADDR_0)
+               v0x0.dma_0x0.dma_0start = onoff;
+
+       if (index & FC_DMA_SUBADDR_1)
+               v0xc.dma_0xc.dma_1start = onoff;
+
+       fc->write_ibi_reg(fc,r0x0,v0x0);
+       fc->write_ibi_reg(fc,r0xc,v0xc);
+
+       deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+       deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_xfer_control);
+
+static int flexcop_dma_remap(struct flexcop_device *fc,
+               flexcop_dma_index_t dma_idx,
+               int onoff)
+{
+       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+       deb_info("%s\n",__func__);
+       v.dma_0xc.remap_enable = onoff;
+       fc->write_ibi_reg(fc,r,v);
+       return 0;
+}
+
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+               flexcop_dma_index_t no,
+               int onoff)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+
+       if (no & FC_DMA_1)
+               v.ctrl_208.DMA1_IRQ_Enable_sig = onoff;
+
+       if (no & FC_DMA_2)
+               v.ctrl_208.DMA2_IRQ_Enable_sig = onoff;
+
+       fc->write_ibi_reg(fc,ctrl_208,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_control_size_irq);
+
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+               flexcop_dma_index_t no,
+               int onoff)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+
+       if (no & FC_DMA_1)
+               v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
+
+       if (no & FC_DMA_2)
+               v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
+
+       fc->write_ibi_reg(fc,ctrl_208,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
+
+/* 1 cycles = 1.97 msec */
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+               flexcop_dma_index_t dma_idx, u8 cycles)
+{
+       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+
+       flexcop_dma_remap(fc,dma_idx,0);
+
+       deb_info("%s\n",__func__);
+       v.dma_0x4_write.dmatimer = cycles;
+       fc->write_ibi_reg(fc,r,v);
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_config_timer);
+
diff --git a/drivers/media/pci/b2c2/flexcop-eeprom.c b/drivers/media/pci/b2c2/flexcop-eeprom.c
new file mode 100644 (file)
index 0000000..a25373a
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+#if 0
+/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
+static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
+{
+       return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
+}
+
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+               u32 len, u8 *wbuf, u8 *rbuf, int retries)
+{
+int i;
+
+for (i = 0; i < retries; i++) {
+       if (eeprom_write(adapter, addr, wbuf, len) == len) {
+               if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* These functions could be used to unlock SkyStar2 cards. */
+
+static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
+{
+       u8 rbuf[20];
+       u8 wbuf[20];
+
+       if (len != 16)
+               return 0;
+
+       memcpy(wbuf, key, len);
+       wbuf[16] = 0;
+       wbuf[17] = 0;
+       wbuf[18] = 0;
+       wbuf[19] = calc_lrc(wbuf, 19);
+       return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
+}
+
+static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
+{
+       u8 buf[20];
+
+       if (len != 16)
+               return 0;
+
+       if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
+               return 0;
+
+       memcpy(key, buf, len);
+       return 1;
+}
+
+static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
+{
+       u8 tmp[8];
+
+       if (type != 0) {
+               tmp[0] = mac[0];
+               tmp[1] = mac[1];
+               tmp[2] = mac[2];
+               tmp[3] = mac[5];
+               tmp[4] = mac[6];
+               tmp[5] = mac[7];
+       } else {
+               tmp[0] = mac[0];
+               tmp[1] = mac[1];
+               tmp[2] = mac[2];
+               tmp[3] = mac[3];
+               tmp[4] = mac[4];
+               tmp[5] = mac[5];
+       }
+
+       tmp[6] = 0;
+       tmp[7] = calc_lrc(tmp, 7);
+
+       if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
+               return 1;
+       return 0;
+}
+
+static int flexcop_eeprom_read(struct flexcop_device *fc,
+               u16 addr, u8 *buf, u16 len)
+{
+       return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
+}
+
+#endif
+
+static u8 calc_lrc(u8 *buf, int len)
+{
+       int i;
+       u8 sum = 0;
+       for (i = 0; i < len; i++)
+               sum = sum ^ buf[i];
+       return sum;
+}
+
+static int flexcop_eeprom_request(struct flexcop_device *fc,
+       flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+{
+       int i,ret = 0;
+       u8 chipaddr =  0x50 | ((addr >> 8) & 3);
+       for (i = 0; i < retries; i++) {
+               ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
+                       addr & 0xff, buf, len);
+               if (ret == 0)
+                       break;
+       }
+       return ret;
+}
+
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
+               u8 *buf, u16 len, int retries)
+{
+       int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
+       if (ret == 0)
+               if (calc_lrc(buf, len - 1) != buf[len - 1])
+                       ret = -EINVAL;
+       return ret;
+}
+
+/* JJ's comment about extended == 1: it is not presently used anywhere but was
+ * added to the low-level functions for possible support of EUI64 */
+int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
+{
+       u8 buf[8];
+       int ret = 0;
+
+       if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
+               if (extended != 0) {
+                       err("TODO: extended (EUI64) MAC addresses aren't "
+                               "completely supported yet");
+                       ret = -EINVAL;
+               } else
+                       memcpy(fc->dvb_adapter.proposed_mac,buf,6);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
diff --git a/drivers/media/pci/b2c2/flexcop-fe-tuner.c b/drivers/media/pci/b2c2/flexcop-fe-tuner.c
new file mode 100644 (file)
index 0000000..850a6c6
--- /dev/null
@@ -0,0 +1,678 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
+ * see flexcop.c for copyright information
+ */
+#include <media/tuner.h>
+#include "flexcop.h"
+#include "mt312.h"
+#include "stv0299.h"
+#include "s5h1420.h"
+#include "itd1000.h"
+#include "cx24113.h"
+#include "cx24123.h"
+#include "isl6421.h"
+#include "mt352.h"
+#include "bcm3510.h"
+#include "nxt200x.h"
+#include "dvb-pll.h"
+#include "lgdt330x.h"
+#include "tuner-simple.h"
+#include "stv0297.h"
+
+
+/* Can we use the specified front-end?  Remember that if we are compiled
+ * into the kernel we can't call code that's in modules.  */
+#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
+       (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
+
+/* lnb control */
+#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
+static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+       flexcop_ibi_value v;
+       deb_tuner("polarity/voltage = %u\n", voltage);
+
+       v = fc->read_ibi_reg(fc, misc_204);
+       switch (voltage) {
+       case SEC_VOLTAGE_OFF:
+               v.misc_204.ACPI1_sig = 1;
+               break;
+       case SEC_VOLTAGE_13:
+               v.misc_204.ACPI1_sig = 0;
+               v.misc_204.LNB_L_H_sig = 0;
+               break;
+       case SEC_VOLTAGE_18:
+               v.misc_204.ACPI1_sig = 0;
+               v.misc_204.LNB_L_H_sig = 1;
+               break;
+       default:
+               err("unknown SEC_VOLTAGE value");
+               return -EINVAL;
+       }
+       return fc->write_ibi_reg(fc, misc_204, v);
+}
+#endif
+
+#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
+static int flexcop_sleep(struct dvb_frontend* fe)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+       if (fc->fe_sleep)
+               return fc->fe_sleep(fe);
+       return 0;
+}
+#endif
+
+/* SkyStar2 DVB-S rev 2.3 */
+#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
+static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
+       struct flexcop_device *fc = fe->dvb->priv;
+       flexcop_ibi_value v;
+       u16 ax;
+       v.raw = 0;
+       deb_tuner("tone = %u\n",tone);
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               ax = 0x01ff;
+               break;
+       case SEC_TONE_OFF:
+               ax = 0;
+               break;
+       default:
+               err("unknown SEC_TONE value");
+               return -EINVAL;
+       }
+
+       v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
+       v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
+       v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
+       return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
+}
+
+static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
+{
+       flexcop_set_tone(fe, SEC_TONE_ON);
+       udelay(data ? 500 : 1000);
+       flexcop_set_tone(fe, SEC_TONE_OFF);
+       udelay(data ? 1000 : 500);
+}
+
+static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
+{
+       int i, par = 1, d;
+       for (i = 7; i >= 0; i--) {
+               d = (data >> i) & 1;
+               par ^= d;
+               flexcop_diseqc_send_bit(fe, d);
+       }
+       flexcop_diseqc_send_bit(fe, par);
+}
+
+static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
+       int len, u8 *msg, unsigned long burst)
+{
+       int i;
+
+       flexcop_set_tone(fe, SEC_TONE_OFF);
+       mdelay(16);
+
+       for (i = 0; i < len; i++)
+               flexcop_diseqc_send_byte(fe,msg[i]);
+       mdelay(16);
+
+       if (burst != -1) {
+               if (burst)
+                       flexcop_diseqc_send_byte(fe, 0xff);
+               else {
+                       flexcop_set_tone(fe, SEC_TONE_ON);
+                       mdelay(12);
+                       udelay(500);
+                       flexcop_set_tone(fe, SEC_TONE_OFF);
+               }
+               msleep(20);
+       }
+       return 0;
+}
+
+static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
+       struct dvb_diseqc_master_cmd *cmd)
+{
+       return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
+}
+
+static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
+       fe_sec_mini_cmd_t minicmd)
+{
+       return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
+}
+
+static struct mt312_config skystar23_samsung_tbdu18132_config = {
+       .demod_address = 0x0e,
+};
+
+static int skystar2_rev23_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       struct dvb_frontend_ops *ops;
+
+       fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
+       if (!fc->fe)
+               return 0;
+
+       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
+                       DVB_PLL_SAMSUNG_TBDU18132))
+               return 0;
+
+       ops = &fc->fe->ops;
+       ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
+       ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
+       ops->set_tone               = flexcop_set_tone;
+       ops->set_voltage            = flexcop_set_voltage;
+       fc->fe_sleep                = ops->sleep;
+       ops->sleep                  = flexcop_sleep;
+       return 1;
+}
+#else
+#define skystar2_rev23_attach NULL
+#endif
+
+/* SkyStar2 DVB-S rev 2.6 */
+#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
+static int samsung_tbmu24112_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;
+}
+
+static u8 samsung_tbmu24112_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7D,
+       0x05, 0x35,
+       0x06, 0x02,
+       0x07, 0x00,
+       0x08, 0xC3,
+       0x0C, 0x00,
+       0x0D, 0x81,
+       0x0E, 0x23,
+       0x0F, 0x12,
+       0x10, 0x7E,
+       0x11, 0x84,
+       0x12, 0xB9,
+       0x13, 0x88,
+       0x14, 0x89,
+       0x15, 0xC9,
+       0x16, 0x00,
+       0x17, 0x5C,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1A, 0x00,
+       0x1C, 0x00,
+       0x1D, 0x00,
+       0x1E, 0x00,
+       0x1F, 0x3A,
+       0x20, 0x2E,
+       0x21, 0x80,
+       0x22, 0xFF,
+       0x23, 0xC1,
+       0x28, 0x00,
+       0x29, 0x1E,
+       0x2A, 0x14,
+       0x2B, 0x0F,
+       0x2C, 0x09,
+       0x2D, 0x05,
+       0x31, 0x1F,
+       0x32, 0x19,
+       0x33, 0xFE,
+       0x34, 0x93,
+       0xff, 0xff,
+};
+
+static struct stv0299_config samsung_tbmu24112_config = {
+       .demod_address = 0x68,
+       .inittab = samsung_tbmu24112_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_LK,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
+};
+
+static int skystar2_rev26_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
+       if (!fc->fe)
+               return 0;
+
+       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
+                       DVB_PLL_SAMSUNG_TBMU24112))
+               return 0;
+
+       fc->fe->ops.set_voltage = flexcop_set_voltage;
+       fc->fe_sleep = fc->fe->ops.sleep;
+       fc->fe->ops.sleep = flexcop_sleep;
+       return 1;
+
+}
+#else
+#define skystar2_rev26_attach NULL
+#endif
+
+/* SkyStar2 DVB-S rev 2.7 */
+#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
+static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
+       .demod_address = 0x53,
+       .invert = 1,
+       .repeated_start_workaround = 1,
+       .serial_mpeg = 1,
+};
+
+static struct itd1000_config skystar2_rev2_7_itd1000_config = {
+       .i2c_address = 0x61,
+};
+
+static int skystar2_rev27_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       flexcop_ibi_value r108;
+       struct i2c_adapter *i2c_tuner;
+
+       /* enable no_base_addr - no repeated start when reading */
+       fc->fc_i2c_adap[0].no_base_addr = 1;
+       fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
+                           i2c);
+       if (!fc->fe)
+               goto fail;
+
+       i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
+       if (!i2c_tuner)
+               goto fail;
+
+       fc->fe_sleep = fc->fe->ops.sleep;
+       fc->fe->ops.sleep = flexcop_sleep;
+
+       /* enable no_base_addr - no repeated start when reading */
+       fc->fc_i2c_adap[2].no_base_addr = 1;
+       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
+                       0x08, 1, 1)) {
+               err("ISL6421 could NOT be attached");
+               goto fail_isl;
+       }
+       info("ISL6421 successfully attached");
+
+       /* the ITD1000 requires a lower i2c clock - is it a problem ? */
+       r108.raw = 0x00000506;
+       fc->write_ibi_reg(fc, tw_sm_c_108, r108);
+       if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
+                       &skystar2_rev2_7_itd1000_config)) {
+               err("ITD1000 could NOT be attached");
+               /* Should i2c clock be restored? */
+               goto fail_isl;
+       }
+       info("ITD1000 successfully attached");
+
+       return 1;
+
+fail_isl:
+       fc->fc_i2c_adap[2].no_base_addr = 0;
+fail:
+       /* for the next devices we need it again */
+       fc->fc_i2c_adap[0].no_base_addr = 0;
+       return 0;
+}
+#else
+#define skystar2_rev27_attach NULL
+#endif
+
+/* SkyStar2 rev 2.8 */
+#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
+static struct cx24123_config skystar2_rev2_8_cx24123_config = {
+       .demod_address = 0x55,
+       .dont_use_pll = 1,
+       .agc_callback = cx24113_agc_callback,
+};
+
+static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
+       .i2c_addr = 0x54,
+       .xtal_khz = 10111,
+};
+
+static int skystar2_rev28_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       struct i2c_adapter *i2c_tuner;
+
+       fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
+                           i2c);
+       if (!fc->fe)
+               return 0;
+
+       i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
+       if (!i2c_tuner)
+               return 0;
+
+       if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
+                       i2c_tuner)) {
+               err("CX24113 could NOT be attached");
+               return 0;
+       }
+       info("CX24113 successfully attached");
+
+       fc->fc_i2c_adap[2].no_base_addr = 1;
+       if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
+                       0x08, 0, 0)) {
+               err("ISL6421 could NOT be attached");
+               fc->fc_i2c_adap[2].no_base_addr = 0;
+               return 0;
+       }
+       info("ISL6421 successfully attached");
+       /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
+        * IR-receiver (PIC16F818) - but the card has no input for that ??? */
+       return 1;
+}
+#else
+#define skystar2_rev28_attach NULL
+#endif
+
+/* AirStar DVB-T */
+#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
+static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
+{
+       static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
+       static u8 mt352_reset[] = { 0x50, 0x80 };
+       static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
+       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+       return 0;
+}
+
+static struct mt352_config samsung_tdtc9251dh0_config = {
+       .demod_address = 0x0f,
+       .demod_init    = samsung_tdtc9251dh0_demod_init,
+};
+
+static int airstar_dvbt_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
+       if (!fc->fe)
+               return 0;
+
+       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
+                           DVB_PLL_SAMSUNG_TDTC9251DH0);
+}
+#else
+#define airstar_dvbt_attach NULL
+#endif
+
+/* AirStar ATSC 1st generation */
+#if FE_SUPPORTED(BCM3510)
+static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
+       const struct firmware **fw, char* name)
+{
+       struct flexcop_device *fc = fe->dvb->priv;
+       return request_firmware(fw, name, fc->dev);
+}
+
+static struct bcm3510_config air2pc_atsc_first_gen_config = {
+       .demod_address    = 0x0f,
+       .request_firmware = flexcop_fe_request_firmware,
+};
+
+static int airstar_atsc1_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
+       return fc->fe != NULL;
+}
+#else
+#define airstar_atsc1_attach NULL
+#endif
+
+/* AirStar ATSC 2nd generation */
+#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
+static struct nxt200x_config samsung_tbmv_config = {
+       .demod_address = 0x0a,
+};
+
+static int airstar_atsc2_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
+       if (!fc->fe)
+               return 0;
+
+       return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
+                           DVB_PLL_SAMSUNG_TBMV);
+}
+#else
+#define airstar_atsc2_attach NULL
+#endif
+
+/* AirStar ATSC 3rd generation */
+#if FE_SUPPORTED(LGDT330X)
+static struct lgdt330x_config air2pc_atsc_hd5000_config = {
+       .demod_address       = 0x59,
+       .demod_chip          = LGDT3303,
+       .serial_mpeg         = 0x04,
+       .clock_polarity_flip = 1,
+};
+
+static int airstar_atsc3_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
+       if (!fc->fe)
+               return 0;
+
+       return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
+                           TUNER_LG_TDVS_H06XF);
+}
+#else
+#define airstar_atsc3_attach NULL
+#endif
+
+/* CableStar2 DVB-C */
+#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
+static u8 alps_tdee4_stv0297_inittab[] = {
+       0x80, 0x01,
+       0x80, 0x00,
+       0x81, 0x01,
+       0x81, 0x00,
+       0x00, 0x48,
+       0x01, 0x58,
+       0x03, 0x00,
+       0x04, 0x00,
+       0x07, 0x00,
+       0x08, 0x00,
+       0x30, 0xff,
+       0x31, 0x9d,
+       0x32, 0xff,
+       0x33, 0x00,
+       0x34, 0x29,
+       0x35, 0x55,
+       0x36, 0x80,
+       0x37, 0x6e,
+       0x38, 0x9c,
+       0x40, 0x1a,
+       0x41, 0xfe,
+       0x42, 0x33,
+       0x43, 0x00,
+       0x44, 0xff,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x49, 0x04,
+       0x4a, 0x51,
+       0x4b, 0xf8,
+       0x52, 0x30,
+       0x53, 0x06,
+       0x59, 0x06,
+       0x5a, 0x5e,
+       0x5b, 0x04,
+       0x61, 0x49,
+       0x62, 0x0a,
+       0x70, 0xff,
+       0x71, 0x04,
+       0x72, 0x00,
+       0x73, 0x00,
+       0x74, 0x0c,
+       0x80, 0x20,
+       0x81, 0x00,
+       0x82, 0x30,
+       0x83, 0x00,
+       0x84, 0x04,
+       0x85, 0x22,
+       0x86, 0x08,
+       0x87, 0x1b,
+       0x88, 0x00,
+       0x89, 0x00,
+       0x90, 0x00,
+       0x91, 0x04,
+       0xa0, 0x86,
+       0xa1, 0x00,
+       0xa2, 0x00,
+       0xb0, 0x91,
+       0xb1, 0x0b,
+       0xc0, 0x5b,
+       0xc1, 0x10,
+       0xc2, 0x12,
+       0xd0, 0x02,
+       0xd1, 0x00,
+       0xd2, 0x00,
+       0xd3, 0x00,
+       0xd4, 0x02,
+       0xd5, 0x00,
+       0xde, 0x00,
+       0xdf, 0x01,
+       0xff, 0xff,
+};
+
+static struct stv0297_config alps_tdee4_stv0297_config = {
+       .demod_address = 0x1c,
+       .inittab = alps_tdee4_stv0297_inittab,
+};
+
+static int cablestar2_attach(struct flexcop_device *fc,
+       struct i2c_adapter *i2c)
+{
+       fc->fc_i2c_adap[0].no_base_addr = 1;
+       fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
+       if (!fc->fe)
+               goto fail;
+
+       /* This tuner doesn't use the stv0297's I2C gate, but instead the
+        * tuner is connected to a different flexcop I2C adapter.  */
+       if (fc->fe->ops.i2c_gate_ctrl)
+               fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
+       fc->fe->ops.i2c_gate_ctrl = NULL;
+
+       if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
+                       &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
+               goto fail;
+
+       return 1;
+
+fail:
+       /* Reset for next frontend to try */
+       fc->fc_i2c_adap[0].no_base_addr = 0;
+       return 0;
+}
+#else
+#define cablestar2_attach NULL
+#endif
+
+static struct {
+       flexcop_device_type_t type;
+       int (*attach)(struct flexcop_device *, struct i2c_adapter *);
+} flexcop_frontends[] = {
+       { FC_SKY_REV27, skystar2_rev27_attach },
+       { FC_SKY_REV28, skystar2_rev28_attach },
+       { FC_SKY_REV26, skystar2_rev26_attach },
+       { FC_AIR_DVBT, airstar_dvbt_attach },
+       { FC_AIR_ATSC2, airstar_atsc2_attach },
+       { FC_AIR_ATSC3, airstar_atsc3_attach },
+       { FC_AIR_ATSC1, airstar_atsc1_attach },
+       { FC_CABLE, cablestar2_attach },
+       { FC_SKY_REV23, skystar2_rev23_attach },
+};
+
+/* try to figure out the frontend */
+int flexcop_frontend_init(struct flexcop_device *fc)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
+               if (!flexcop_frontends[i].attach)
+                       continue;
+               /* type needs to be set before, because of some workarounds
+                * done based on the probed card type */
+               fc->dev_type = flexcop_frontends[i].type;
+               if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
+                       goto fe_found;
+               /* Clean up partially attached frontend */
+               if (fc->fe) {
+                       dvb_frontend_detach(fc->fe);
+                       fc->fe = NULL;
+               }
+       }
+       fc->dev_type = FC_UNK;
+       err("no frontend driver found for this B2C2/FlexCop adapter");
+       return -ENODEV;
+
+fe_found:
+       info("found '%s' .", fc->fe->ops.info.name);
+       if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
+               err("frontend registration failed!");
+               dvb_frontend_detach(fc->fe);
+               fc->fe = NULL;
+               return -EINVAL;
+       }
+       fc->init_state |= FC_STATE_FE_INIT;
+       return 0;
+}
+
+void flexcop_frontend_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_FE_INIT) {
+               dvb_unregister_frontend(fc->fe);
+               dvb_frontend_detach(fc->fe);
+       }
+       fc->init_state &= ~FC_STATE_FE_INIT;
+}
diff --git a/drivers/media/pci/b2c2/flexcop-hw-filter.c b/drivers/media/pci/b2c2/flexcop-hw-filter.c
new file mode 100644 (file)
index 0000000..77e4547
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and control functions
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
+       deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
+}
+
+void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
+}
+
+static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
+}
+
+void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
+{
+       flexcop_ibi_value v418, v41c;
+       v41c = fc->read_ibi_reg(fc, mac_address_41c);
+
+       v418.mac_address_418.MAC1 = mac[0];
+       v418.mac_address_418.MAC2 = mac[1];
+       v418.mac_address_418.MAC3 = mac[2];
+       v418.mac_address_418.MAC6 = mac[3];
+       v41c.mac_address_41c.MAC7 = mac[4];
+       v41c.mac_address_41c.MAC8 = mac[5];
+
+       fc->write_ibi_reg(fc, mac_address_418, v418);
+       fc->write_ibi_reg(fc, mac_address_41c, v41c);
+}
+
+void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
+}
+
+static void flexcop_pid_group_filter(struct flexcop_device *fc,
+               u16 pid, u16 mask)
+{
+       /* index_reg_310.extra_index_reg need to 0 or 7 to work */
+       flexcop_ibi_value v30c;
+       v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
+       v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
+       fc->write_ibi_reg(fc, pid_filter_30c, v30c);
+}
+
+static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
+{
+       flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
+}
+
+/* this fancy define reduces the code size of the quite similar PID controlling of
+ * the first 6 PIDs
+ */
+
+#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
+       flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
+v208 = fc->read_ibi_reg(fc, ctrl_208); \
+vpid.vregname.field = onoff ? pid : 0x1fff; \
+vpid.vregname.trans_field = transval; \
+v208.ctrl_208.enablefield = onoff; \
+fc->write_ibi_reg(fc, vregname, vpid); \
+fc->write_ibi_reg(fc, ctrl_208, v208);
+
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
+                       Stream1_trans, 0);
+}
+
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
+                       Stream2_trans, 0);
+}
+
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
+}
+
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
+}
+
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
+}
+
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
+               u16 pid, int onoff)
+{
+       pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
+}
+
+static void flexcop_pid_control(struct flexcop_device *fc,
+               int index, u16 pid, int onoff)
+{
+       if (pid == 0x2000)
+               return;
+
+       deb_ts("setting pid: %5d %04x at index %d '%s'\n",
+                       pid, pid, index, onoff ? "on" : "off");
+
+       /* We could use bit magic here to reduce source code size.
+        * I decided against it, but to use the real register names */
+       switch (index) {
+       case 0:
+               flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
+               break;
+       case 1:
+               flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
+               break;
+       case 2:
+               flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
+               break;
+       case 3:
+               flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
+               break;
+       case 4:
+               flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
+               break;
+       case 5:
+               flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
+               break;
+       default:
+               if (fc->has_32_hw_pid_filter && index < 38) {
+                       flexcop_ibi_value vpid, vid;
+
+                       /* set the index */
+                       vid = fc->read_ibi_reg(fc, index_reg_310);
+                       vid.index_reg_310.index_reg = index - 6;
+                       fc->write_ibi_reg(fc, index_reg_310, vid);
+
+                       vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
+                       vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+                       vpid.pid_n_reg_314.PID_enable_bit = onoff;
+                       fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
+               }
+               break;
+       }
+}
+
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
+{
+       if (fc->fullts_streaming_state != onoff) {
+               deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
+               flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
+               flexcop_pid_group_filter_ctrl(fc, onoff);
+               fc->fullts_streaming_state = onoff;
+       }
+       return 0;
+}
+
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+               struct dvb_demux_feed *dvbdmxfeed, int onoff)
+{
+       int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
+
+       fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
+       if (dvbdmxfeed->index >= max_pid_filter)
+               fc->extra_feedcount += onoff ? 1 : -1;
+
+       /* toggle complete-TS-streaming when:
+        * - pid_filtering is not enabled and it is the first or last feed requested
+        * - pid_filtering is enabled,
+        *   - but the number of requested feeds is exceeded
+        *   - or the requested pid is 0x2000 */
+
+       if (!fc->pid_filtering && fc->feedcount == onoff)
+               flexcop_toggle_fullts_streaming(fc, onoff);
+
+       if (fc->pid_filtering) {
+               flexcop_pid_control \
+                       (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
+
+               if (fc->extra_feedcount > 0)
+                       flexcop_toggle_fullts_streaming(fc, 1);
+               else if (dvbdmxfeed->pid == 0x2000)
+                       flexcop_toggle_fullts_streaming(fc, onoff);
+               else
+                       flexcop_toggle_fullts_streaming(fc, 0);
+       }
+
+       /* if it was the first or last feed request change the stream-status */
+       if (fc->feedcount == onoff) {
+               flexcop_rcv_data_ctrl(fc, onoff);
+               if (fc->stream_control) /* device specific stream control */
+                       fc->stream_control(fc, onoff);
+
+               /* feeding stopped -> reset the flexcop filter*/
+               if (onoff == 0) {
+                       flexcop_reset_block_300(fc);
+                       flexcop_hw_filter_init(fc);
+               }
+       }
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_pid_feed_control);
+
+void flexcop_hw_filter_init(struct flexcop_device *fc)
+{
+       int i;
+       flexcop_ibi_value v;
+       for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
+               flexcop_pid_control(fc, i, 0x1fff, 0);
+
+       flexcop_pid_group_filter(fc, 0, 0x1fe0);
+       flexcop_pid_group_filter_ctrl(fc, 0);
+
+       v = fc->read_ibi_reg(fc, pid_filter_308);
+       v.pid_filter_308.EMM_filter_4 = 1;
+       v.pid_filter_308.EMM_filter_6 = 0;
+       fc->write_ibi_reg(fc, pid_filter_308, v);
+
+       flexcop_null_filter_ctrl(fc, 1);
+}
diff --git a/drivers/media/pci/b2c2/flexcop-i2c.c b/drivers/media/pci/b2c2/flexcop-i2c.c
new file mode 100644 (file)
index 0000000..965d5eb
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+#define FC_MAX_I2C_RETRIES 100000
+
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+               flexcop_ibi_value *r100)
+{
+       int i;
+       flexcop_ibi_value r;
+
+       r100->tw_sm_c_100.working_start = 1;
+       deb_i2c("r100 before: %08x\n",r100->raw);
+
+       fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
+       fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
+
+       for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
+               r = fc->read_ibi_reg(fc, tw_sm_c_100);
+
+               if (!r.tw_sm_c_100.no_base_addr_ack_error) {
+                       if (r.tw_sm_c_100.st_done) {
+                               *r100 = r;
+                               deb_i2c("i2c success\n");
+                               return 0;
+                       }
+               } else {
+                       deb_i2c("suffering from an i2c ack_error\n");
+                       return -EREMOTEIO;
+               }
+       }
+       deb_i2c("tried %d times i2c operation, "
+                       "never finished or too many ack errors.\n", i);
+       return -EREMOTEIO;
+}
+
+static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
+               flexcop_ibi_value r100, u8 *buf)
+{
+       flexcop_ibi_value r104;
+       int len = r100.tw_sm_c_100.total_bytes,
+               /* remember total_bytes is buflen-1 */
+               ret;
+
+       /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+        * correctly:
+        *
+        * the ITD1000 is behind an i2c-gate which closes automatically
+        * after an i2c-transaction the STV0297 needs 2 consecutive reads
+        * one with no_base_addr = 0 and one with 1
+        *
+        * those two work-arounds are conflictin: we check for the card
+        * type, it is set when probing the ITD1000 */
+       if (i2c->fc->dev_type == FC_SKY_REV27)
+               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+
+       ret = flexcop_i2c_operation(i2c->fc, &r100);
+       if (ret != 0) {
+               deb_i2c("Retrying operation\n");
+               r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+               ret = flexcop_i2c_operation(i2c->fc, &r100);
+       }
+       if (ret != 0) {
+               deb_i2c("read failed. %d\n", ret);
+               return ret;
+       }
+
+       buf[0] = r100.tw_sm_c_100.data1_reg;
+
+       if (len > 0) {
+               r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
+               deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
+
+               /* there is at least one more byte, otherwise we wouldn't be here */
+               buf[1] = r104.tw_sm_c_104.data2_reg;
+               if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
+               if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
+       }
+       return 0;
+}
+
+static int flexcop_i2c_write4(struct flexcop_device *fc,
+               flexcop_ibi_value r100, u8 *buf)
+{
+       flexcop_ibi_value r104;
+       int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
+       r104.raw = 0;
+
+       /* there is at least one byte, otherwise we wouldn't be here */
+       r100.tw_sm_c_100.data1_reg = buf[0];
+       r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
+       r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
+       r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
+
+       deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
+
+       /* write the additional i2c data before doing the actual i2c operation */
+       fc->write_ibi_reg(fc, tw_sm_c_104, r104);
+       return flexcop_i2c_operation(fc, &r100);
+}
+
+int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
+               flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+{
+       int ret;
+
+#ifdef DUMP_I2C_MESSAGES
+       int i;
+#endif
+
+       u16 bytes_to_transfer;
+       flexcop_ibi_value r100;
+
+       deb_i2c("op = %d\n",op);
+       r100.raw = 0;
+       r100.tw_sm_c_100.chipaddr = chipaddr;
+       r100.tw_sm_c_100.twoWS_rw = op;
+       r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
+
+#ifdef DUMP_I2C_MESSAGES
+       printk(KERN_DEBUG "%d ", i2c->port);
+       if (op == FC_READ)
+               printk("rd(");
+       else
+               printk("wr(");
+       printk("%02x): %02x ", chipaddr, addr);
+#endif
+
+       /* in that case addr is the only value ->
+        * we write it twice as baseaddr and val0
+        * BBTI is doing it like that for ISL6421 at least */
+       if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
+               buf = &addr;
+               len = 1;
+       }
+
+       while (len != 0) {
+               bytes_to_transfer = len > 4 ? 4 : len;
+
+               r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
+               r100.tw_sm_c_100.baseaddr = addr;
+
+               if (op == FC_READ)
+                       ret = flexcop_i2c_read4(i2c, r100, buf);
+               else
+                       ret = flexcop_i2c_write4(i2c->fc, r100, buf);
+
+#ifdef DUMP_I2C_MESSAGES
+               for (i = 0; i < bytes_to_transfer; i++)
+                       printk("%02x ", buf[i]);
+#endif
+
+               if (ret < 0)
+                       return ret;
+
+               buf  += bytes_to_transfer;
+               addr += bytes_to_transfer;
+               len  -= bytes_to_transfer;
+       }
+
+#ifdef DUMP_I2C_MESSAGES
+       printk("\n");
+#endif
+
+       return 0;
+}
+/* exported for PCI i2c */
+EXPORT_SYMBOL(flexcop_i2c_request);
+
+/* master xfer callback for demodulator */
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msgs[], int num)
+{
+       struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
+       int i, ret = 0;
+
+       /* Some drivers use 1 byte or 0 byte reads as probes, which this
+        * driver doesn't support.  These probes will always fail, so this
+        * hack makes them always succeed.  If one knew how, it would of
+        * course be better to actually do the read.  */
+       if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
+               return 1;
+
+       if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
+               return -ERESTARTSYS;
+
+       for (i = 0; i < num; i++) {
+               /* reading */
+               if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
+                       ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
+                                       msgs[i].buf[0], msgs[i+1].buf,
+                                       msgs[i+1].len);
+                       i++; /* skip the following message */
+               } else /* writing */
+                       ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
+                                       msgs[i].buf[0], &msgs[i].buf[1],
+                                       msgs[i].len - 1);
+               if (ret < 0) {
+                       deb_i2c("i2c master_xfer failed");
+                       break;
+               }
+       }
+
+       mutex_unlock(&i2c->fc->i2c_mutex);
+
+       if (ret == 0)
+               ret = num;
+       return ret;
+}
+
+static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm flexcop_algo = {
+       .master_xfer    = flexcop_master_xfer,
+       .functionality  = flexcop_i2c_func,
+};
+
+int flexcop_i2c_init(struct flexcop_device *fc)
+{
+       int ret;
+       mutex_init(&fc->i2c_mutex);
+
+       fc->fc_i2c_adap[0].fc = fc;
+       fc->fc_i2c_adap[1].fc = fc;
+       fc->fc_i2c_adap[2].fc = fc;
+       fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
+       fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
+       fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
+
+       strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
+                       sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+       strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
+                       sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+       strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
+                       sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+
+       i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
+       i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
+       i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
+
+       fc->fc_i2c_adap[0].i2c_adap.algo =
+               fc->fc_i2c_adap[1].i2c_adap.algo =
+               fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
+       fc->fc_i2c_adap[0].i2c_adap.algo_data =
+               fc->fc_i2c_adap[1].i2c_adap.algo_data =
+               fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
+       fc->fc_i2c_adap[0].i2c_adap.dev.parent =
+               fc->fc_i2c_adap[1].i2c_adap.dev.parent =
+               fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
+
+       ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+       if (ret < 0)
+               goto adap_1_failed;
+
+       ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
+       if (ret < 0)
+               goto adap_2_failed;
+
+       fc->init_state |= FC_STATE_I2C_INIT;
+       return 0;
+
+adap_2_failed:
+       i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+adap_1_failed:
+       i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+       return ret;
+}
+
+void flexcop_i2c_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_I2C_INIT) {
+               i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
+               i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+               i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+       }
+       fc->init_state &= ~FC_STATE_I2C_INIT;
+}
diff --git a/drivers/media/pci/b2c2/flexcop-misc.c b/drivers/media/pci/b2c2/flexcop-misc.c
new file mode 100644 (file)
index 0000000..f06f3a9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+void flexcop_determine_revision(struct flexcop_device *fc)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
+
+       switch (v.misc_204.Rev_N_sig_revision_hi) {
+       case 0x2:
+               deb_info("found a FlexCopII.\n");
+               fc->rev = FLEXCOP_II;
+               break;
+       case 0x3:
+               deb_info("found a FlexCopIIb.\n");
+               fc->rev = FLEXCOP_IIB;
+               break;
+       case 0x0:
+               deb_info("found a FlexCopIII.\n");
+               fc->rev = FLEXCOP_III;
+               break;
+       default:
+               err("unknown FlexCop Revision: %x. Please report this to "
+                               "linux-dvb@linuxtv.org.",
+                               v.misc_204.Rev_N_sig_revision_hi);
+               break;
+       }
+
+       if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
+               deb_info("this FlexCop has "
+                               "the additional 32 hardware pid filter.\n");
+       else
+               deb_info("this FlexCop has "
+                               "the 6 basic main hardware pid filter.\n");
+       /* bus parts have to decide if hw pid filtering is used or not. */
+}
+
+static const char *flexcop_revision_names[] = {
+       "Unknown chip",
+       "FlexCopII",
+       "FlexCopIIb",
+       "FlexCopIII",
+};
+
+static const char *flexcop_device_names[] = {
+       [FC_UNK]        = "Unknown device",
+       [FC_CABLE]      = "Cable2PC/CableStar 2 DVB-C",
+       [FC_AIR_DVBT]   = "Air2PC/AirStar 2 DVB-T",
+       [FC_AIR_ATSC1]  = "Air2PC/AirStar 2 ATSC 1st generation",
+       [FC_AIR_ATSC2]  = "Air2PC/AirStar 2 ATSC 2nd generation",
+       [FC_AIR_ATSC3]  = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
+       [FC_SKY_REV23]  = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
+       [FC_SKY_REV26]  = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
+       [FC_SKY_REV27]  = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
+       [FC_SKY_REV28]  = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
+};
+
+static const char *flexcop_bus_names[] = {
+       "USB",
+       "PCI",
+};
+
+void flexcop_device_name(struct flexcop_device *fc,
+               const char *prefix, const char *suffix)
+{
+       info("%s '%s' at the '%s' bus controlled by a '%s' %s",
+                       prefix, flexcop_device_names[fc->dev_type],
+                       flexcop_bus_names[fc->bus_type],
+                       flexcop_revision_names[fc->rev], suffix);
+}
+
+void flexcop_dump_reg(struct flexcop_device *fc,
+               flexcop_ibi_register reg, int num)
+{
+       flexcop_ibi_value v;
+       int i;
+       for (i = 0; i < num; i++) {
+               v = fc->read_ibi_reg(fc, reg+4*i);
+               deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
+       }
+       deb_rdump("\n");
+}
+EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
new file mode 100644 (file)
index 0000000..44f8fb5
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-pci.c - covers the PCI part including DMA transfers
+ * see flexcop.c for copyright information
+ */
+
+#define FC_LOG_PREFIX "flexcop-pci"
+#include "flexcop-common.h"
+
+static int enable_pid_filtering = 1;
+module_param(enable_pid_filtering, int, 0444);
+MODULE_PARM_DESC(enable_pid_filtering,
+       "enable hardware pid filtering: supported values: 0 (fullts), 1");
+
+static int irq_chk_intv = 100;
+module_param(irq_chk_intv, int, 0644);
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
+
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+       do { if ((debug & level)) printk(args); } while (0)
+#define DEBSTATUS ""
+#else
+#define dprintk(level,args...)
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_reg(args...) dprintk(0x02, args)
+#define deb_ts(args...) dprintk(0x04, args)
+#define deb_irq(args...) dprintk(0x08, args)
+#define deb_chk(args...) dprintk(0x10, args)
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,
+       "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
+       DEBSTATUS);
+
+#define DRIVER_VERSION "0.1"
+#define DRIVER_NAME "flexcop-pci"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+
+struct flexcop_pci {
+       struct pci_dev *pdev;
+
+#define FC_PCI_INIT     0x01
+#define FC_PCI_DMA_INIT 0x02
+       int init_state;
+
+       void __iomem *io_mem;
+       u32 irq;
+       /* buffersize (at least for DMA1, need to be % 188 == 0,
+        * this logic is required */
+#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
+#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
+       struct flexcop_dma dma[2];
+
+       int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
+       u32 last_dma1_cur_pos;
+       /* position of the pointer last time the timer/packet irq occurred */
+       int count;
+       int count_prev;
+       int stream_problem;
+
+       spinlock_t irq_lock;
+       unsigned long last_irq;
+
+       struct delayed_work irq_check_work;
+       struct flexcop_device *fc_dev;
+};
+
+static int lastwreg, lastwval, lastrreg, lastrval;
+
+static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
+               flexcop_ibi_register r)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+       flexcop_ibi_value v;
+       v.raw = readl(fc_pci->io_mem + r);
+
+       if (lastrreg != r || lastrval != v.raw) {
+               lastrreg = r; lastrval = v.raw;
+               deb_reg("new rd: %3x: %08x\n", r, v.raw);
+       }
+
+       return v;
+}
+
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
+               flexcop_ibi_register r, flexcop_ibi_value v)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+
+       if (lastwreg != r || lastwval != v.raw) {
+               lastwreg = r; lastwval = v.raw;
+               deb_reg("new wr: %3x: %08x\n", r, v.raw);
+       }
+
+       writel(v.raw, fc_pci->io_mem + r);
+       return 0;
+}
+
+static void flexcop_pci_irq_check_work(struct work_struct *work)
+{
+       struct flexcop_pci *fc_pci =
+               container_of(work, struct flexcop_pci, irq_check_work.work);
+       struct flexcop_device *fc = fc_pci->fc_dev;
+
+       if (fc->feedcount) {
+
+               if (fc_pci->count == fc_pci->count_prev) {
+                       deb_chk("no IRQ since the last check\n");
+                       if (fc_pci->stream_problem++ == 3) {
+                               struct dvb_demux_feed *feed;
+                               deb_info("flexcop-pci: stream problem, resetting pid filter\n");
+
+                               spin_lock_irq(&fc->demux.lock);
+                               list_for_each_entry(feed, &fc->demux.feed_list,
+                                               list_head) {
+                                       flexcop_pid_feed_control(fc, feed, 0);
+                               }
+
+                               list_for_each_entry(feed, &fc->demux.feed_list,
+                                               list_head) {
+                                       flexcop_pid_feed_control(fc, feed, 1);
+                               }
+                               spin_unlock_irq(&fc->demux.lock);
+
+                               fc_pci->stream_problem = 0;
+                       }
+               } else {
+                       fc_pci->stream_problem = 0;
+                       fc_pci->count_prev = fc_pci->count;
+               }
+       }
+
+       schedule_delayed_work(&fc_pci->irq_check_work,
+                       msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
+}
+
+/* When PID filtering is turned on, we use the timer IRQ, because small amounts
+ * of data need to be passed to the user space instantly as well. When PID
+ * filtering is turned off, we use the page-change-IRQ */
+static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
+{
+       struct flexcop_pci *fc_pci = dev_id;
+       struct flexcop_device *fc = fc_pci->fc_dev;
+       unsigned long flags;
+       flexcop_ibi_value v;
+       irqreturn_t ret = IRQ_HANDLED;
+
+       spin_lock_irqsave(&fc_pci->irq_lock, flags);
+       v = fc->read_ibi_reg(fc, irq_20c);
+
+       /* errors */
+       if (v.irq_20c.Data_receiver_error)
+               deb_chk("data receiver error\n");
+       if (v.irq_20c.Continuity_error_flag)
+               deb_chk("Contunuity error flag is set\n");
+       if (v.irq_20c.LLC_SNAP_FLAG_set)
+               deb_chk("LLC_SNAP_FLAG_set is set\n");
+       if (v.irq_20c.Transport_Error)
+               deb_chk("Transport error\n");
+
+       if ((fc_pci->count % 1000) == 0)
+               deb_chk("%d valid irq took place so far\n", fc_pci->count);
+
+       if (v.irq_20c.DMA1_IRQ_Status == 1) {
+               if (fc_pci->active_dma1_addr == 0)
+                       flexcop_pass_dmx_packets(fc_pci->fc_dev,
+                                       fc_pci->dma[0].cpu_addr0,
+                                       fc_pci->dma[0].size / 188);
+               else
+                       flexcop_pass_dmx_packets(fc_pci->fc_dev,
+                                       fc_pci->dma[0].cpu_addr1,
+                                       fc_pci->dma[0].size / 188);
+
+               deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
+               fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
+               /* for the timer IRQ we only can use buffer dmx feeding, because we don't have
+                * complete TS packets when reading from the DMA memory */
+       } else if (v.irq_20c.DMA1_Timer_Status == 1) {
+               dma_addr_t cur_addr =
+                       fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
+               u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
+
+               deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
+                       "last_cur_pos: %08x ",
+                               jiffies_to_usecs(jiffies - fc_pci->last_irq),
+                               v.raw, (unsigned long long)cur_addr, cur_pos,
+                               fc_pci->last_dma1_cur_pos);
+               fc_pci->last_irq = jiffies;
+
+               /* buffer end was reached, restarted from the beginning
+                * pass the data from last_cur_pos to the buffer end to the demux
+                */
+               if (cur_pos < fc_pci->last_dma1_cur_pos) {
+                       deb_irq(" end was reached: passing %d bytes ",
+                               (fc_pci->dma[0].size*2 - 1) -
+                               fc_pci->last_dma1_cur_pos);
+                       flexcop_pass_dmx_data(fc_pci->fc_dev,
+                               fc_pci->dma[0].cpu_addr0 +
+                                       fc_pci->last_dma1_cur_pos,
+                               (fc_pci->dma[0].size*2) -
+                                       fc_pci->last_dma1_cur_pos);
+                       fc_pci->last_dma1_cur_pos = 0;
+               }
+
+               if (cur_pos > fc_pci->last_dma1_cur_pos) {
+                       deb_irq(" passing %d bytes ",
+                               cur_pos - fc_pci->last_dma1_cur_pos);
+                       flexcop_pass_dmx_data(fc_pci->fc_dev,
+                               fc_pci->dma[0].cpu_addr0 +
+                                       fc_pci->last_dma1_cur_pos,
+                               cur_pos - fc_pci->last_dma1_cur_pos);
+               }
+               deb_irq("\n");
+
+               fc_pci->last_dma1_cur_pos = cur_pos;
+               fc_pci->count++;
+       } else {
+               deb_irq("isr for flexcop called, "
+                       "apparently without reason (%08x)\n", v.raw);
+               ret = IRQ_NONE;
+       }
+
+       spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
+       return ret;
+}
+
+static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
+{
+       struct flexcop_pci *fc_pci = fc->bus_specific;
+       if (onoff) {
+               flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
+               flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
+               flexcop_dma_config_timer(fc, FC_DMA_1, 0);
+               flexcop_dma_xfer_control(fc, FC_DMA_1,
+                               FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
+               deb_irq("DMA xfer enabled\n");
+
+               fc_pci->last_dma1_cur_pos = 0;
+               flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
+               deb_irq("IRQ enabled\n");
+               fc_pci->count_prev = fc_pci->count;
+       } else {
+               flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
+               deb_irq("IRQ disabled\n");
+
+               flexcop_dma_xfer_control(fc, FC_DMA_1,
+                        FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
+               deb_irq("DMA xfer disabled\n");
+       }
+       return 0;
+}
+
+static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
+{
+       int ret;
+       ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+                       FC_DEFAULT_DMA1_BUFSIZE);
+       if (ret != 0)
+               return ret;
+
+       ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+                       FC_DEFAULT_DMA2_BUFSIZE);
+       if (ret != 0) {
+               flexcop_dma_free(&fc_pci->dma[0]);
+               return ret;
+       }
+
+       flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
+                       FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+       flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
+                       FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
+       fc_pci->init_state |= FC_PCI_DMA_INIT;
+       return ret;
+}
+
+static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
+{
+       if (fc_pci->init_state & FC_PCI_DMA_INIT) {
+               flexcop_dma_free(&fc_pci->dma[0]);
+               flexcop_dma_free(&fc_pci->dma[1]);
+       }
+       fc_pci->init_state &= ~FC_PCI_DMA_INIT;
+}
+
+static int flexcop_pci_init(struct flexcop_pci *fc_pci)
+{
+       int ret;
+
+       info("card revision %x", fc_pci->pdev->revision);
+
+       if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
+               return ret;
+       pci_set_master(fc_pci->pdev);
+
+       if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
+               goto err_pci_disable_device;
+
+       fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);
+
+       if (!fc_pci->io_mem) {
+               err("cannot map io memory\n");
+               ret = -EIO;
+               goto err_pci_release_regions;
+       }
+
+       pci_set_drvdata(fc_pci->pdev, fc_pci);
+       spin_lock_init(&fc_pci->irq_lock);
+       if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
+                                       IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
+               goto err_pci_iounmap;
+
+       fc_pci->init_state |= FC_PCI_INIT;
+       return ret;
+
+err_pci_iounmap:
+       pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
+       pci_set_drvdata(fc_pci->pdev, NULL);
+err_pci_release_regions:
+       pci_release_regions(fc_pci->pdev);
+err_pci_disable_device:
+       pci_disable_device(fc_pci->pdev);
+       return ret;
+}
+
+static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
+{
+       if (fc_pci->init_state & FC_PCI_INIT) {
+               free_irq(fc_pci->pdev->irq, fc_pci);
+               pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
+               pci_set_drvdata(fc_pci->pdev, NULL);
+               pci_release_regions(fc_pci->pdev);
+               pci_disable_device(fc_pci->pdev);
+       }
+       fc_pci->init_state &= ~FC_PCI_INIT;
+}
+
+static int flexcop_pci_probe(struct pci_dev *pdev,
+               const struct pci_device_id *ent)
+{
+       struct flexcop_device *fc;
+       struct flexcop_pci *fc_pci;
+       int ret = -ENOMEM;
+
+       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) {
+               err("out of memory\n");
+               return -ENOMEM;
+       }
+
+       /* general flexcop init */
+       fc_pci = fc->bus_specific;
+       fc_pci->fc_dev = fc;
+
+       fc->read_ibi_reg = flexcop_pci_read_ibi_reg;
+       fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
+       fc->i2c_request = flexcop_i2c_request;
+       fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
+       fc->stream_control = flexcop_pci_stream_control;
+
+       if (enable_pid_filtering)
+               info("will use the HW PID filter.");
+       else
+               info("will pass the complete TS to the demuxer.");
+
+       fc->pid_filtering = enable_pid_filtering;
+       fc->bus_type = FC_PCI;
+       fc->dev = &pdev->dev;
+       fc->owner = THIS_MODULE;
+
+       /* bus specific part */
+       fc_pci->pdev = pdev;
+       if ((ret = flexcop_pci_init(fc_pci)) != 0)
+               goto err_kfree;
+
+       /* init flexcop */
+       if ((ret = flexcop_device_initialize(fc)) != 0)
+               goto err_pci_exit;
+
+       /* init dma */
+       if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
+               goto err_fc_exit;
+
+       INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
+
+       if (irq_chk_intv > 0)
+               schedule_delayed_work(&fc_pci->irq_check_work,
+                               msecs_to_jiffies(irq_chk_intv < 100 ?
+                                       100 :
+                                       irq_chk_intv));
+       return ret;
+
+err_fc_exit:
+       flexcop_device_exit(fc);
+err_pci_exit:
+       flexcop_pci_exit(fc_pci);
+err_kfree:
+       flexcop_device_kfree(fc);
+       return ret;
+}
+
+/* in theory every _exit function should be called exactly two times,
+ * here and in the bail-out-part of the _init-function
+ */
+static void flexcop_pci_remove(struct pci_dev *pdev)
+{
+       struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
+
+       if (irq_chk_intv > 0)
+               cancel_delayed_work(&fc_pci->irq_check_work);
+
+       flexcop_pci_dma_exit(fc_pci);
+       flexcop_device_exit(fc_pci->fc_dev);
+       flexcop_pci_exit(fc_pci);
+       flexcop_device_kfree(fc_pci->fc_dev);
+}
+
+static struct pci_device_id flexcop_pci_tbl[] = {
+       { PCI_DEVICE(0x13d0, 0x2103) },
+       { },
+};
+
+MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
+
+static struct pci_driver flexcop_pci_driver = {
+       .name     = "b2c2_flexcop_pci",
+       .id_table = flexcop_pci_tbl,
+       .probe    = flexcop_pci_probe,
+       .remove   = flexcop_pci_remove,
+};
+
+static int __init flexcop_pci_module_init(void)
+{
+       return pci_register_driver(&flexcop_pci_driver);
+}
+
+static void __exit flexcop_pci_module_exit(void)
+{
+       pci_unregister_driver(&flexcop_pci_driver);
+}
+
+module_init(flexcop_pci_module_init);
+module_exit(flexcop_pci_module_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/b2c2/flexcop-reg.h b/drivers/media/pci/b2c2/flexcop-reg.h
new file mode 100644 (file)
index 0000000..dc4528d
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
+ * see flexcop.c for copyright information
+ */
+#ifndef __FLEXCOP_REG_H__
+#define __FLEXCOP_REG_H__
+
+typedef enum {
+       FLEXCOP_UNK = 0,
+       FLEXCOP_II,
+       FLEXCOP_IIB,
+       FLEXCOP_III,
+} flexcop_revision_t;
+
+typedef enum {
+       FC_UNK = 0,
+       FC_CABLE,
+       FC_AIR_DVBT,
+       FC_AIR_ATSC1,
+       FC_AIR_ATSC2,
+       FC_AIR_ATSC3,
+       FC_SKY_REV23,
+       FC_SKY_REV26,
+       FC_SKY_REV27,
+       FC_SKY_REV28,
+} flexcop_device_type_t;
+
+typedef enum {
+       FC_USB = 0,
+       FC_PCI,
+} flexcop_bus_t;
+
+/* FlexCop IBI Registers */
+#if defined(__LITTLE_ENDIAN)
+#include "flexcop_ibi_value_le.h"
+#else
+#if defined(__BIG_ENDIAN)
+#include "flexcop_ibi_value_be.h"
+#else
+#error no endian defined
+#endif
+#endif
+
+#define fc_data_Tag_ID_DVB  0x3e
+#define fc_data_Tag_ID_ATSC 0x3f
+#define fc_data_Tag_ID_IDSB 0x8b
+
+#define fc_key_code_default 0x1
+#define fc_key_code_even    0x2
+#define fc_key_code_odd     0x3
+
+extern flexcop_ibi_value ibi_zero;
+
+typedef enum {
+       FC_I2C_PORT_DEMOD  = 1,
+       FC_I2C_PORT_EEPROM = 2,
+       FC_I2C_PORT_TUNER  = 3,
+} flexcop_i2c_port_t;
+
+typedef enum {
+       FC_WRITE = 0,
+       FC_READ  = 1,
+} flexcop_access_op_t;
+
+typedef enum {
+       FC_SRAM_DEST_NET   = 1,
+       FC_SRAM_DEST_CAI   = 2,
+       FC_SRAM_DEST_CAO   = 4,
+       FC_SRAM_DEST_MEDIA = 8
+} flexcop_sram_dest_t;
+
+typedef enum {
+       FC_SRAM_DEST_TARGET_WAN_USB = 0,
+       FC_SRAM_DEST_TARGET_DMA1    = 1,
+       FC_SRAM_DEST_TARGET_DMA2    = 2,
+       FC_SRAM_DEST_TARGET_FC3_CA  = 3
+} flexcop_sram_dest_target_t;
+
+typedef enum {
+       FC_SRAM_2_32KB  = 0, /*  64KB */
+       FC_SRAM_1_32KB  = 1, /*  32KB - default fow FCII */
+       FC_SRAM_1_128KB = 2, /* 128KB */
+       FC_SRAM_1_48KB  = 3, /*  48KB - default for FCIII */
+} flexcop_sram_type_t;
+
+typedef enum {
+       FC_WAN_SPEED_4MBITS  = 0,
+       FC_WAN_SPEED_8MBITS  = 1,
+       FC_WAN_SPEED_12MBITS = 2,
+       FC_WAN_SPEED_16MBITS = 3,
+} flexcop_wan_speed_t;
+
+typedef enum {
+       FC_DMA_1 = 1,
+       FC_DMA_2 = 2,
+} flexcop_dma_index_t;
+
+typedef enum {
+       FC_DMA_SUBADDR_0 = 1,
+       FC_DMA_SUBADDR_1 = 2,
+} flexcop_dma_addr_index_t;
+
+/* names of the particular registers */
+typedef enum {
+       dma1_000            = 0x000,
+       dma1_004            = 0x004,
+       dma1_008            = 0x008,
+       dma1_00c            = 0x00c,
+       dma2_010            = 0x010,
+       dma2_014            = 0x014,
+       dma2_018            = 0x018,
+       dma2_01c            = 0x01c,
+
+       tw_sm_c_100         = 0x100,
+       tw_sm_c_104         = 0x104,
+       tw_sm_c_108         = 0x108,
+       tw_sm_c_10c         = 0x10c,
+       tw_sm_c_110         = 0x110,
+
+       lnb_switch_freq_200 = 0x200,
+       misc_204            = 0x204,
+       ctrl_208            = 0x208,
+       irq_20c             = 0x20c,
+       sw_reset_210        = 0x210,
+       misc_214            = 0x214,
+       mbox_v8_to_host_218 = 0x218,
+       mbox_host_to_v8_21c = 0x21c,
+
+       pid_filter_300      = 0x300,
+       pid_filter_304      = 0x304,
+       pid_filter_308      = 0x308,
+       pid_filter_30c      = 0x30c,
+       index_reg_310       = 0x310,
+       pid_n_reg_314       = 0x314,
+       mac_low_reg_318     = 0x318,
+       mac_high_reg_31c    = 0x31c,
+
+       data_tag_400        = 0x400,
+       card_id_408         = 0x408,
+       card_id_40c         = 0x40c,
+       mac_address_418     = 0x418,
+       mac_address_41c     = 0x41c,
+
+       ci_600              = 0x600,
+       pi_604              = 0x604,
+       pi_608              = 0x608,
+       dvb_reg_60c         = 0x60c,
+
+       sram_ctrl_reg_700   = 0x700,
+       net_buf_reg_704     = 0x704,
+       cai_buf_reg_708     = 0x708,
+       cao_buf_reg_70c     = 0x70c,
+       media_buf_reg_710   = 0x710,
+       sram_dest_reg_714   = 0x714,
+       net_buf_reg_718     = 0x718,
+       wan_ctrl_reg_71c    = 0x71c,
+} flexcop_ibi_register;
+
+#define flexcop_set_ibi_value(reg,attr,val) { \
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
+       v.reg.attr = val; \
+       fc->write_ibi_reg(fc,reg,v); \
+}
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop-sram.c b/drivers/media/pci/b2c2/flexcop-sram.c
new file mode 100644 (file)
index 0000000..f2199e4
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-sram.c - functions for controlling the SRAM
+ * see flexcop.c for copyright information
+ */
+#include "flexcop.h"
+
+static void flexcop_sram_set_chip(struct flexcop_device *fc,
+               flexcop_sram_type_t type)
+{
+       flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
+}
+
+int flexcop_sram_init(struct flexcop_device *fc)
+{
+       switch (fc->rev) {
+       case FLEXCOP_II:
+       case FLEXCOP_IIB:
+               flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
+               break;
+       case FLEXCOP_III:
+               flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+                flexcop_sram_dest_target_t target)
+{
+       flexcop_ibi_value v;
+       v = fc->read_ibi_reg(fc, sram_dest_reg_714);
+
+       if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
+               err("SRAM destination target to available on FlexCopII(b)\n");
+               return -EINVAL;
+       }
+       deb_sram("sram dest: %x target: %x\n", dest, target);
+
+       if (dest & FC_SRAM_DEST_NET)
+               v.sram_dest_reg_714.NET_Dest = target;
+       if (dest & FC_SRAM_DEST_CAI)
+               v.sram_dest_reg_714.CAI_Dest = target;
+       if (dest & FC_SRAM_DEST_CAO)
+               v.sram_dest_reg_714.CAO_Dest = target;
+       if (dest & FC_SRAM_DEST_MEDIA)
+               v.sram_dest_reg_714.MEDIA_Dest = target;
+
+       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
+       udelay(1000); /* TODO delay really necessary */
+
+       return 0;
+}
+EXPORT_SYMBOL(flexcop_sram_set_dest);
+
+void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
+{
+       flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
+}
+EXPORT_SYMBOL(flexcop_wan_set_speed);
+
+void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
+{
+       flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+       v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
+       v.sram_dest_reg_714.ctrl_sramdma = sramdma;
+       v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
+       fc->write_ibi_reg(fc,sram_dest_reg_714,v);
+}
+EXPORT_SYMBOL(flexcop_sram_ctrl);
+
+#if 0
+static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+{
+       int i, retries;
+       u32 command;
+
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04000000 | (*buf << 0x10);
+
+               retries = 2;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __func__);
+
+               write_reg_dw(adapter, 0x700, command);
+
+               buf++;
+               addr++;
+       }
+}
+
+static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+{
+       int i, retries;
+       u32 command, value;
+
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04008000;
+
+               retries = 10000;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __func__);
+
+               write_reg_dw(adapter, 0x700, command);
+
+               retries = 10000;
+
+               while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __func__);
+
+               value = read_reg_dw(adapter, 0x700) >> 0x10;
+
+               *buf = (value & 0xff);
+
+               addr++;
+               buf++;
+       }
+}
+
+static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+{
+       u32 bank;
+
+       bank = 0;
+
+       if (adapter->dw_sram_type == 0x20000) {
+               bank = (addr & 0x18000) << 0x0d;
+       }
+
+       if (adapter->dw_sram_type == 0x00000) {
+               if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+       flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
+}
+
+static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+{
+       u32 bank;
+       bank = 0;
+
+       if (adapter->dw_sram_type == 0x20000) {
+               bank = (addr & 0x18000) << 0x0d;
+       }
+
+       if (adapter->dw_sram_type == 0x00000) {
+               if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+       flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
+}
+
+static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+{
+       u32 length;
+       while (len != 0) {
+               length = len;
+               /* check if the address range belongs to the same
+                * 32K memory chip. If not, the data is read
+                * from one chip at a time */
+               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
+                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+
+               sram_read_chunk(adapter, addr, buf, length);
+               addr = addr + length;
+               buf = buf + length;
+               len = len - length;
+       }
+}
+
+static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+{
+       u32 length;
+       while (len != 0) {
+               length = len;
+
+               /* check if the address range belongs to the same
+                * 32K memory chip. If not, the data is
+                * written to one chip at a time */
+               if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
+                       length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+
+               sram_write_chunk(adapter, addr, buf, length);
+               addr = addr + length;
+               buf = buf + length;
+               len = len - length;
+       }
+}
+
+static void sram_set_size(struct adapter *adapter, u32 mask)
+{
+       write_reg_dw(adapter, 0x71c,
+                       (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+}
+
+static void sram_init(struct adapter *adapter)
+{
+       u32 tmp;
+       tmp = read_reg_dw(adapter, 0x71c);
+       write_reg_dw(adapter, 0x71c, 1);
+
+       if (read_reg_dw(adapter, 0x71c) != 0) {
+               write_reg_dw(adapter, 0x71c, tmp);
+               adapter->dw_sram_type = tmp & 0x30000;
+               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
+       } else {
+               adapter->dw_sram_type = 0x10000;
+               ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
+       }
+}
+
+static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
+{
+       u8 tmp1, tmp2;
+       dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
+
+       sram_set_size(adapter, mask);
+       sram_init(adapter);
+
+       tmp2 = 0xa5;
+       tmp1 = 0x4f;
+
+       sram_write(adapter, addr, &tmp2, 1);
+       sram_write(adapter, addr + 4, &tmp1, 1);
+
+       tmp2 = 0;
+       mdelay(20);
+
+       sram_read(adapter, addr, &tmp2, 1);
+       sram_read(adapter, addr, &tmp2, 1);
+
+       dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
+
+       if (tmp2 != 0xa5)
+               return 0;
+
+       tmp2 = 0x5a;
+       tmp1 = 0xf4;
+
+       sram_write(adapter, addr, &tmp2, 1);
+       sram_write(adapter, addr + 4, &tmp1, 1);
+
+       tmp2 = 0;
+       mdelay(20);
+
+       sram_read(adapter, addr, &tmp2, 1);
+       sram_read(adapter, addr, &tmp2, 1);
+
+       dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
+
+       if (tmp2 != 0x5a)
+               return 0;
+       return 1;
+}
+
+static u32 sram_length(struct adapter *adapter)
+{
+       if (adapter->dw_sram_type == 0x10000)
+               return 32768; /* 32K */
+       if (adapter->dw_sram_type == 0x00000)
+               return 65536; /* 64K */
+       if (adapter->dw_sram_type == 0x20000)
+               return 131072; /* 128K */
+       return 32768; /* 32K */
+}
+
+/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
+   - for 128K there are 4x32K chips at bank 0,1,2,3.
+   - for  64K there are 2x32K chips at bank 1,2.
+   - for  32K there is one 32K chip at bank 0.
+
+   FlexCop works only with one bank at a time. The bank is selected
+   by bits 28-29 of the 0x700 register.
+
+   bank 0 covers addresses 0x00000-0x07fff
+   bank 1 covers addresses 0x08000-0x0ffff
+   bank 2 covers addresses 0x10000-0x17fff
+   bank 3 covers addresses 0x18000-0x1ffff */
+
+static int flexcop_sram_detect(struct flexcop_device *fc)
+{
+       flexcop_ibi_value r208, r71c_0, vr71c_1;
+       r208 = fc->read_ibi_reg(fc, ctrl_208);
+       fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
+
+       r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
+       write_reg_dw(adapter, 0x71c, 1);
+       tmp3 = read_reg_dw(adapter, 0x71c);
+       dprintk("%s: tmp3 = %x\n", __func__, tmp3);
+       write_reg_dw(adapter, 0x71c, tmp2);
+
+       // check for internal SRAM ???
+       tmp3--;
+       if (tmp3 != 0) {
+               sram_set_size(adapter, 0x10000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 32K\n", __func__);
+               return 32;
+       }
+
+       if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
+               sram_set_size(adapter, 0x20000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 128K\n", __func__);
+               return 128;
+       }
+
+       if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
+               sram_set_size(adapter, 0x00000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 64K\n", __func__);
+               return 64;
+       }
+
+       if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
+               sram_set_size(adapter, 0x10000);
+               sram_init(adapter);
+               write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 32K\n", __func__);
+               return 32;
+       }
+
+       sram_set_size(adapter, 0x10000);
+       sram_init(adapter);
+       write_reg_dw(adapter, 0x208, tmp);
+       dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
+       return 0;
+}
+
+static void sll_detect_sram_size(struct adapter *adapter)
+{
+       sram_detect_for_flex2(adapter);
+}
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop-usb.c b/drivers/media/pci/b2c2/flexcop-usb.c
new file mode 100644 (file)
index 0000000..8b6275f
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.c - covers the USB part
+ * see flexcop.c for copyright information
+ */
+#define FC_LOG_PREFIX "flexcop_usb"
+#include "flexcop-usb.h"
+#include "flexcop-common.h"
+
+/* Version information */
+#define DRIVER_VERSION "0.1"
+#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+
+/* debug */
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+       do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
+       int i; \
+       for (i = 0; i < l; i++) \
+               method("%02x ", b[i]); \
+       method("\n"); \
+} while (0)
+
+#define DEBSTATUS ""
+#else
+#define dprintk(level, args...)
+#define debug_dump(b, l, method)
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
+               "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+#undef DEBSTATUS
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_ts(args...) dprintk(0x02, args)
+#define deb_ctrl(args...) dprintk(0x04, args)
+#define deb_i2c(args...) dprintk(0x08, args)
+#define deb_v8(args...) dprintk(0x10, args)
+
+/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
+ * in the IBI address, to make the V8 code simpler.
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
+ *                  in general: 0000 0HHH 000L LL00
+ * IBI ADDRESS FORMAT:                    RHHH BLLL
+ *
+ * where R is the read(1)/write(0) bit, B is the busy bit
+ * and HHH and LLL are the two sets of three bits from the PCI address.
+ */
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
+       (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
+       (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+
+/*
+ * DKT 020228
+ * - forget about this VENDOR_BUFFER_SIZE, read and write register
+ *   deal with DWORD or 4 bytes, that should be should from now on
+ * - from now on, we don't support anything older than firm 1.00
+ *   I eliminated the write register as a 2 trip of writing hi word and lo word
+ *   and force this to write only 4 bytes at a time.
+ *   NOTE: this should work with all the firmware from 1.00 and newer
+ */
+static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read)
+{
+       struct flexcop_usb *fc_usb = fc->bus_specific;
+       u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
+       u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
+       u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
+               (read ? 0x80 : 0);
+
+       int len = usb_control_msg(fc_usb->udev,
+                       read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
+                       request,
+                       request_type, /* 0xc0 read or 0x40 write */
+                       wAddress,
+                       0,
+                       val,
+                       sizeof(u32),
+                       B2C2_WAIT_FOR_OPERATION_RDW * HZ);
+
+       if (len != sizeof(u32)) {
+               err("error while %s dword from %d (%d).", read ? "reading" :
+                               "writing", wAddress, wRegOffsPCI);
+               return -EIO;
+       }
+       return 0;
+}
+/*
+ * DKT 010817 - add support for V8 memory read/write and flash update
+ */
+static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
+               flexcop_usb_request_t req, u8 page, u16 wAddress,
+               u8 *pbBuffer, u32 buflen)
+{
+       u8 request_type = USB_TYPE_VENDOR;
+       u16 wIndex;
+       int nWaitTime, pipe, len;
+       wIndex = page << 8;
+
+       switch (req) {
+       case B2C2_USB_READ_V8_MEM:
+               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+               request_type |= USB_DIR_IN;
+               pipe = B2C2_USB_CTRL_PIPE_IN;
+               break;
+       case B2C2_USB_WRITE_V8_MEM:
+               wIndex |= pbBuffer[0];
+               request_type |= USB_DIR_OUT;
+               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+               pipe = B2C2_USB_CTRL_PIPE_OUT;
+               break;
+       case B2C2_USB_FLASH_BLOCK:
+               request_type |= USB_DIR_OUT;
+               nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+               pipe = B2C2_USB_CTRL_PIPE_OUT;
+               break;
+       default:
+               deb_info("unsupported request for v8_mem_req %x.\n", req);
+               return -EINVAL;
+       }
+       deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+                       wAddress, wIndex, buflen);
+
+       len = usb_control_msg(fc_usb->udev, pipe,
+                       req,
+                       request_type,
+                       wAddress,
+                       wIndex,
+                       pbBuffer,
+                       buflen,
+                       nWaitTime * HZ);
+
+       debug_dump(pbBuffer, len, deb_v8);
+       return len == buflen ? 0 : -EIO;
+}
+
+#define bytes_left_to_read_on_page(paddr,buflen) \
+       ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+        ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
+               flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
+               u32 addr, int extended, u8 *buf, u32 len)
+{
+       int i,ret = 0;
+       u16 wMax;
+       u32 pagechunk = 0;
+
+       switch(req) {
+       case B2C2_USB_READ_V8_MEM:
+               wMax = USB_MEM_READ_MAX;
+               break;
+       case B2C2_USB_WRITE_V8_MEM:
+               wMax = USB_MEM_WRITE_MAX;
+               break;
+       case B2C2_USB_FLASH_BLOCK:
+               wMax = USB_FLASH_MAX;
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+       for (i = 0; i < len;) {
+               pagechunk =
+                       wMax < bytes_left_to_read_on_page(addr, len) ?
+                               wMax :
+                               bytes_left_to_read_on_page(addr, len);
+               deb_info("%x\n",
+                       (addr & V8_MEMORY_PAGE_MASK) |
+                               (V8_MEMORY_EXTENDED*extended));
+
+               ret = flexcop_usb_v8_memory_req(fc_usb, req,
+                       page_start + (addr / V8_MEMORY_PAGE_SIZE),
+                       (addr & V8_MEMORY_PAGE_MASK) |
+                               (V8_MEMORY_EXTENDED*extended),
+                       &buf[i], pagechunk);
+
+               if (ret < 0)
+                       return ret;
+               addr += pagechunk;
+               len -= pagechunk;
+       }
+       return 0;
+}
+
+static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
+{
+       return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
+               V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
+               fc->dvb_adapter.proposed_mac, 6);
+}
+
+#if 0
+static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
+               flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
+               u16 buflen, u8 *pvBuffer)
+{
+       u16 wValue;
+       u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
+       int nWaitTime = 2,
+           pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
+       wValue = (func << 8) | extra;
+
+       len = usb_control_msg(fc_usb->udev,pipe,
+                       B2C2_USB_UTILITY,
+                       request_type,
+                       wValue,
+                       wIndex,
+                       pvBuffer,
+                       buflen,
+                       nWaitTime * HZ);
+       return len == buflen ? 0 : -EIO;
+}
+#endif
+
+/* usb i2c stuff */
+static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
+               flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
+               u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
+{
+       struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
+       u16 wValue, wIndex;
+       int nWaitTime,pipe,len;
+       u8 request_type = USB_TYPE_VENDOR;
+
+       switch (func) {
+       case USB_FUNC_I2C_WRITE:
+       case USB_FUNC_I2C_MULTIWRITE:
+       case USB_FUNC_I2C_REPEATWRITE:
+               /* DKT 020208 - add this to support special case of DiSEqC */
+       case USB_FUNC_I2C_CHECKWRITE:
+               pipe = B2C2_USB_CTRL_PIPE_OUT;
+               nWaitTime = 2;
+               request_type |= USB_DIR_OUT;
+               break;
+       case USB_FUNC_I2C_READ:
+       case USB_FUNC_I2C_REPEATREAD:
+               pipe = B2C2_USB_CTRL_PIPE_IN;
+               nWaitTime = 2;
+               request_type |= USB_DIR_IN;
+               break;
+       default:
+               deb_info("unsupported function for i2c_req %x\n", func);
+               return -EINVAL;
+       }
+       wValue = (func << 8) | (i2c->port << 4);
+       wIndex = (chipaddr << 8 ) | addr;
+
+       deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
+                       func, request_type, req,
+                       wValue & 0xff, wValue >> 8,
+                       wIndex & 0xff, wIndex >> 8);
+
+       len = usb_control_msg(fc_usb->udev,pipe,
+                       req,
+                       request_type,
+                       wValue,
+                       wIndex,
+                       buf,
+                       buflen,
+                       nWaitTime * HZ);
+       return len == buflen ? 0 : -EREMOTEIO;
+}
+
+/* actual bus specific access functions,
+   make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
+       flexcop_ibi_register reg)
+{
+       flexcop_ibi_value val;
+       val.raw = 0;
+       flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
+       return val;
+}
+
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
+               flexcop_ibi_register reg, flexcop_ibi_value val)
+{
+       return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
+}
+
+static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
+               flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+{
+       if (op == FC_READ)
+               return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
+                               USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
+       else
+               return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
+                               USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
+}
+
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
+       u8 *buffer, int buffer_length)
+{
+       u8 *b;
+       int l;
+
+       deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
+               fc_usb->tmp_buffer_length, buffer_length);
+
+       if (fc_usb->tmp_buffer_length > 0) {
+               memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
+                               buffer_length);
+               fc_usb->tmp_buffer_length += buffer_length;
+               b = fc_usb->tmp_buffer;
+               l = fc_usb->tmp_buffer_length;
+       } else {
+               b=buffer;
+               l=buffer_length;
+       }
+
+       while (l >= 190) {
+               if (*b == 0xff) {
+                       switch (*(b+1) & 0x03) {
+                       case 0x01: /* media packet */
+                               if (*(b+2) == 0x47)
+                                       flexcop_pass_dmx_packets(
+                                                       fc_usb->fc_dev, b+2, 1);
+                               else
+                                       deb_ts("not ts packet %*ph\n", 4, b+2);
+                               b += 190;
+                               l -= 190;
+                               break;
+                       default:
+                               deb_ts("wrong packet type\n");
+                               l = 0;
+                               break;
+                       }
+               } else {
+                       deb_ts("wrong header\n");
+                       l = 0;
+               }
+       }
+
+       if (l>0)
+               memcpy(fc_usb->tmp_buffer, b, l);
+       fc_usb->tmp_buffer_length = l;
+}
+
+static void flexcop_usb_urb_complete(struct urb *urb)
+{
+       struct flexcop_usb *fc_usb = urb->context;
+       int i;
+
+       if (urb->actual_length > 0)
+               deb_ts("urb completed, bufsize: %d actlen; %d\n",
+                       urb->transfer_buffer_length, urb->actual_length);
+
+       for (i = 0; i < urb->number_of_packets; i++) {
+               if (urb->iso_frame_desc[i].status < 0) {
+                       err("iso frame descriptor %d has an error: %d\n", i,
+                               urb->iso_frame_desc[i].status);
+               } else
+                       if (urb->iso_frame_desc[i].actual_length > 0) {
+                               deb_ts("passed %d bytes to the demux\n",
+                                       urb->iso_frame_desc[i].actual_length);
+
+                               flexcop_usb_process_frame(fc_usb,
+                                       urb->transfer_buffer +
+                                               urb->iso_frame_desc[i].offset,
+                                       urb->iso_frame_desc[i].actual_length);
+                       }
+               urb->iso_frame_desc[i].status = 0;
+               urb->iso_frame_desc[i].actual_length = 0;
+       }
+       usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff)
+{
+       /* submit/kill iso packets */
+       return 0;
+}
+
+static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
+{
+       int i;
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
+               if (fc_usb->iso_urb[i] != NULL) {
+                       deb_ts("unlinking/killing urb no. %d\n",i);
+                       usb_kill_urb(fc_usb->iso_urb[i]);
+                       usb_free_urb(fc_usb->iso_urb[i]);
+               }
+
+       if (fc_usb->iso_buffer != NULL)
+               pci_free_consistent(NULL,
+                       fc_usb->buffer_size, fc_usb->iso_buffer,
+                       fc_usb->dma_addr);
+}
+
+static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
+{
+       u16 frame_size = le16_to_cpu(
+               fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
+       int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
+               frame_size, i, j, ret;
+       int buffer_offset = 0;
+
+       deb_ts("creating %d iso-urbs with %d frames "
+                       "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
+                       B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
+
+       fc_usb->iso_buffer = pci_alloc_consistent(NULL,
+                       bufsize, &fc_usb->dma_addr);
+       if (fc_usb->iso_buffer == NULL)
+               return -ENOMEM;
+
+       memset(fc_usb->iso_buffer, 0, bufsize);
+       fc_usb->buffer_size = bufsize;
+
+       /* creating iso urbs */
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+               fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+                       GFP_ATOMIC);
+               if (fc_usb->iso_urb[i] == NULL) {
+                       ret = -ENOMEM;
+                       goto urb_error;
+               }
+       }
+
+       /* initialising and submitting iso urbs */
+       for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+               int frame_offset = 0;
+               struct urb *urb = fc_usb->iso_urb[i];
+               deb_ts("initializing and submitting urb no. %d "
+                       "(buf_offset: %d).\n", i, buffer_offset);
+
+               urb->dev = fc_usb->udev;
+               urb->context = fc_usb;
+               urb->complete = flexcop_usb_urb_complete;
+               urb->pipe = B2C2_USB_DATA_PIPE;
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->interval = 1;
+               urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
+               urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
+               urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset;
+
+               buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
+               for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
+                       deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
+                                       i, j, frame_offset);
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = frame_size;
+                       frame_offset += frame_size;
+               }
+
+               if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
+                       err("submitting urb %d failed with %d.", i, ret);
+                       goto urb_error;
+               }
+               deb_ts("submitted urb no. %d.\n",i);
+       }
+
+       /* SRAM */
+       flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
+                       FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
+                       FC_SRAM_DEST_TARGET_WAN_USB);
+       flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
+       flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
+       return 0;
+
+urb_error:
+       flexcop_usb_transfer_exit(fc_usb);
+       return ret;
+}
+
+static int flexcop_usb_init(struct flexcop_usb *fc_usb)
+{
+       /* use the alternate setting with the larges buffer */
+       usb_set_interface(fc_usb->udev,0,1);
+       switch (fc_usb->udev->speed) {
+       case USB_SPEED_LOW:
+               err("cannot handle USB speed because it is too slow.");
+               return -ENODEV;
+               break;
+       case USB_SPEED_FULL:
+               info("running at FULL speed.");
+               break;
+       case USB_SPEED_HIGH:
+               info("running at HIGH speed.");
+               break;
+       case USB_SPEED_UNKNOWN: /* fall through */
+       default:
+               err("cannot handle USB speed because it is unknown.");
+               return -ENODEV;
+       }
+       usb_set_intfdata(fc_usb->uintf, fc_usb);
+       return 0;
+}
+
+static void flexcop_usb_exit(struct flexcop_usb *fc_usb)
+{
+       usb_set_intfdata(fc_usb->uintf, NULL);
+}
+
+static int flexcop_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct flexcop_usb *fc_usb = NULL;
+       struct flexcop_device *fc = NULL;
+       int ret;
+
+       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
+               err("out of memory\n");
+               return -ENOMEM;
+       }
+
+       /* general flexcop init */
+       fc_usb = fc->bus_specific;
+       fc_usb->fc_dev = fc;
+
+       fc->read_ibi_reg  = flexcop_usb_read_ibi_reg;
+       fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
+       fc->i2c_request = flexcop_usb_i2c_request;
+       fc->get_mac_addr = flexcop_usb_get_mac_addr;
+
+       fc->stream_control = flexcop_usb_stream_control;
+
+       fc->pid_filtering = 1;
+       fc->bus_type = FC_USB;
+
+       fc->dev = &udev->dev;
+       fc->owner = THIS_MODULE;
+
+       /* bus specific part */
+       fc_usb->udev = udev;
+       fc_usb->uintf = intf;
+       if ((ret = flexcop_usb_init(fc_usb)) != 0)
+               goto err_kfree;
+
+       /* init flexcop */
+       if ((ret = flexcop_device_initialize(fc)) != 0)
+               goto err_usb_exit;
+
+       /* xfer init */
+       if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
+               goto err_fc_exit;
+
+       info("%s successfully initialized and connected.", DRIVER_NAME);
+       return 0;
+
+err_fc_exit:
+       flexcop_device_exit(fc);
+err_usb_exit:
+       flexcop_usb_exit(fc_usb);
+err_kfree:
+       flexcop_device_kfree(fc);
+       return ret;
+}
+
+static void flexcop_usb_disconnect(struct usb_interface *intf)
+{
+       struct flexcop_usb *fc_usb = usb_get_intfdata(intf);
+       flexcop_usb_transfer_exit(fc_usb);
+       flexcop_device_exit(fc_usb->fc_dev);
+       flexcop_usb_exit(fc_usb);
+       flexcop_device_kfree(fc_usb->fc_dev);
+       info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
+}
+
+static struct usb_device_id flexcop_usb_table [] = {
+       { USB_DEVICE(0x0af7, 0x0101) },
+       { }
+};
+MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver flexcop_usb_driver = {
+       .name           = "b2c2_flexcop_usb",
+       .probe          = flexcop_usb_probe,
+       .disconnect = flexcop_usb_disconnect,
+       .id_table       = flexcop_usb_table,
+};
+
+module_usb_driver(flexcop_usb_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/b2c2/flexcop-usb.h b/drivers/media/pci/b2c2/flexcop-usb.h
new file mode 100644 (file)
index 0000000..92529a9
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
+#ifndef __FLEXCOP_USB_H_INCLUDED__
+#define __FLEXCOP_USB_H_INCLUDED__
+
+#include <linux/usb.h>
+
+/* transfer parameters */
+#define B2C2_USB_FRAMES_PER_ISO 4
+#define B2C2_USB_NUM_ISO_URB 4
+
+#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
+
+struct flexcop_usb {
+       struct usb_device *udev;
+       struct usb_interface *uintf;
+
+       u8 *iso_buffer;
+       int buffer_size;
+       dma_addr_t dma_addr;
+
+       struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+       struct flexcop_device *fc_dev;
+
+       u8 tmp_buffer[1023+190];
+       int tmp_buffer_length;
+};
+
+#if 0
+/* request types TODO What is its use?*/
+typedef enum {
+
+} flexcop_usb_request_type_t;
+#endif
+
+/* request */
+typedef enum {
+       B2C2_USB_WRITE_V8_MEM = 0x04,
+       B2C2_USB_READ_V8_MEM  = 0x05,
+       B2C2_USB_READ_REG     = 0x08,
+       B2C2_USB_WRITE_REG    = 0x0A,
+       B2C2_USB_WRITEREGHI   = 0x0B,
+       B2C2_USB_FLASH_BLOCK  = 0x10,
+       B2C2_USB_I2C_REQUEST  = 0x11,
+       B2C2_USB_UTILITY      = 0x12,
+} flexcop_usb_request_t;
+
+/* function definition for I2C_REQUEST */
+typedef enum {
+       USB_FUNC_I2C_WRITE       = 0x01,
+       USB_FUNC_I2C_MULTIWRITE  = 0x02,
+       USB_FUNC_I2C_READ        = 0x03,
+       USB_FUNC_I2C_REPEATWRITE = 0x04,
+       USB_FUNC_GET_DESCRIPTOR  = 0x05,
+       USB_FUNC_I2C_REPEATREAD  = 0x06,
+       /* DKT 020208 - add this to support special case of DiSEqC */
+       USB_FUNC_I2C_CHECKWRITE  = 0x07,
+       USB_FUNC_I2C_CHECKRESULT = 0x08,
+} flexcop_usb_i2c_function_t;
+
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
+typedef enum {
+       UTILITY_SET_FILTER          = 0x01,
+       UTILITY_DATA_ENABLE         = 0x02,
+       UTILITY_FLEX_MULTIWRITE     = 0x03,
+       UTILITY_SET_BUFFER_SIZE     = 0x04,
+       UTILITY_FLEX_OPERATOR       = 0x05,
+       UTILITY_FLEX_RESET300_START = 0x06,
+       UTILITY_FLEX_RESET300_STOP  = 0x07,
+       UTILITY_FLEX_RESET300       = 0x08,
+       UTILITY_SET_ISO_SIZE        = 0x09,
+       UTILITY_DATA_RESET          = 0x0A,
+       UTILITY_GET_DATA_STATUS     = 0x10,
+       UTILITY_GET_V8_REG          = 0x11,
+       /* DKT 020326 - add function for v1.14 */
+       UTILITY_SRAM_WRITE          = 0x12,
+       UTILITY_SRAM_READ           = 0x13,
+       UTILITY_SRAM_TESTFILL       = 0x14,
+       UTILITY_SRAM_TESTSET        = 0x15,
+       UTILITY_SRAM_TESTVERIFY     = 0x16,
+} flexcop_usb_utility_function_t;
+
+#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
+
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
+
+typedef enum {
+       V8_MEMORY_PAGE_DVB_CI = 0x20,
+       V8_MEMORY_PAGE_DVB_DS = 0x40,
+       V8_MEMORY_PAGE_MULTI2 = 0x60,
+       V8_MEMORY_PAGE_FLASH  = 0x80
+} flexcop_usb_mem_page_t;
+
+#define V8_MEMORY_EXTENDED (1 << 15)
+#define USB_MEM_READ_MAX   32
+#define USB_MEM_WRITE_MAX   1
+#define USB_FLASH_MAX       8
+#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
+#define V8_MEMORY_PAGE_MASK 0x7FFF
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop.c b/drivers/media/pci/b2c2/flexcop.c
new file mode 100644 (file)
index 0000000..b1e8c99
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ *
+ * Acknowledgements:
+ *   John Jurrius from BBTI, Inc. for extensive support
+ *                    with code examples and data books
+ *   Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ *
+ * Contributions to the skystar2-driver have been done by
+ *   Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ *   Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ *   Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ *   Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
+ *               filtering)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "flexcop.h"
+
+#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
+
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define DEBSTATUS ""
+#else
+#define DEBSTATUS " (debugging is not enabled)"
+#endif
+
+int b2c2_flexcop_debug;
+module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
+MODULE_PARM_DESC(debug,
+               "set debug level (1=info,2=tuner,4=i2c,8=ts,"
+               "16=sram,32=reg (|-able))."
+               DEBSTATUS);
+#undef DEBSTATUS
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* global zero for ibi values */
+flexcop_ibi_value ibi_zero;
+
+static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
+       return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
+}
+
+static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct flexcop_device *fc = dvbdmxfeed->demux->priv;
+       return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
+}
+
+static int flexcop_dvb_init(struct flexcop_device *fc)
+{
+       int ret = dvb_register_adapter(&fc->dvb_adapter,
+                       "FlexCop Digital TV device", fc->owner,
+                       fc->dev, adapter_nr);
+       if (ret < 0) {
+               err("error registering DVB adapter");
+               return ret;
+       }
+       fc->dvb_adapter.priv = fc;
+
+       fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
+                       | DMX_MEMORY_BASED_FILTERING);
+       fc->demux.priv = fc;
+       fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
+       fc->demux.start_feed = flexcop_dvb_start_feed;
+       fc->demux.stop_feed = flexcop_dvb_stop_feed;
+       fc->demux.write_to_decoder = NULL;
+
+       ret = dvb_dmx_init(&fc->demux);
+       if (ret < 0) {
+               err("dvb_dmx failed: error %d", ret);
+               goto err_dmx;
+       }
+
+       fc->hw_frontend.source = DMX_FRONTEND_0;
+
+       fc->dmxdev.filternum = fc->demux.feednum;
+       fc->dmxdev.demux = &fc->demux.dmx;
+       fc->dmxdev.capabilities = 0;
+       ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter);
+       if (ret < 0) {
+               err("dvb_dmxdev_init failed: error %d", ret);
+               goto err_dmx_dev;
+       }
+
+       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
+       if (ret < 0) {
+               err("adding hw_frontend to dmx failed: error %d", ret);
+               goto err_dmx_add_hw_frontend;
+       }
+
+       fc->mem_frontend.source = DMX_MEMORY_FE;
+       ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
+       if (ret < 0) {
+               err("adding mem_frontend to dmx failed: error %d", ret);
+               goto err_dmx_add_mem_frontend;
+       }
+
+       ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
+       if (ret < 0) {
+               err("connect frontend failed: error %d", ret);
+               goto err_connect_frontend;
+       }
+
+       ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
+       if (ret < 0) {
+               err("dvb_net_init failed: error %d", ret);
+               goto err_net;
+       }
+
+       fc->init_state |= FC_STATE_DVB_INIT;
+       return 0;
+
+err_net:
+       fc->demux.dmx.disconnect_frontend(&fc->demux.dmx);
+err_connect_frontend:
+       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
+err_dmx_add_mem_frontend:
+       fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
+err_dmx_add_hw_frontend:
+       dvb_dmxdev_release(&fc->dmxdev);
+err_dmx_dev:
+       dvb_dmx_release(&fc->demux);
+err_dmx:
+       dvb_unregister_adapter(&fc->dvb_adapter);
+       return ret;
+}
+
+static void flexcop_dvb_exit(struct flexcop_device *fc)
+{
+       if (fc->init_state & FC_STATE_DVB_INIT) {
+               dvb_net_release(&fc->dvbnet);
+
+               fc->demux.dmx.close(&fc->demux.dmx);
+               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+                       &fc->mem_frontend);
+               fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+                       &fc->hw_frontend);
+               dvb_dmxdev_release(&fc->dmxdev);
+               dvb_dmx_release(&fc->demux);
+               dvb_unregister_adapter(&fc->dvb_adapter);
+               deb_info("deinitialized dvb stuff\n");
+       }
+       fc->init_state &= ~FC_STATE_DVB_INIT;
+}
+
+/* these methods are necessary to achieve the long-term-goal of hiding the
+ * struct flexcop_device from the bus-parts */
+void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
+{
+       dvb_dmx_swfilter(&fc->demux, buf, len);
+}
+EXPORT_SYMBOL(flexcop_pass_dmx_data);
+
+void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
+{
+       dvb_dmx_swfilter_packets(&fc->demux, buf, no);
+}
+EXPORT_SYMBOL(flexcop_pass_dmx_packets);
+
+static void flexcop_reset(struct flexcop_device *fc)
+{
+       flexcop_ibi_value v210, v204;
+
+       /* reset the flexcop itself */
+       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+       v210.raw = 0;
+       v210.sw_reset_210.reset_block_000 = 1;
+       v210.sw_reset_210.reset_block_100 = 1;
+       v210.sw_reset_210.reset_block_200 = 1;
+       v210.sw_reset_210.reset_block_300 = 1;
+       v210.sw_reset_210.reset_block_400 = 1;
+       v210.sw_reset_210.reset_block_500 = 1;
+       v210.sw_reset_210.reset_block_600 = 1;
+       v210.sw_reset_210.reset_block_700 = 1;
+       v210.sw_reset_210.Block_reset_enable = 0xb2;
+       v210.sw_reset_210.Special_controls = 0xc259;
+       fc->write_ibi_reg(fc,sw_reset_210,v210);
+       msleep(1);
+
+       /* reset the periphical devices */
+
+       v204 = fc->read_ibi_reg(fc,misc_204);
+       v204.misc_204.Per_reset_sig = 0;
+       fc->write_ibi_reg(fc,misc_204,v204);
+       msleep(1);
+       v204.misc_204.Per_reset_sig = 1;
+       fc->write_ibi_reg(fc,misc_204,v204);
+}
+
+void flexcop_reset_block_300(struct flexcop_device *fc)
+{
+       flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
+                         v210 = fc->read_ibi_reg(fc, sw_reset_210);
+
+       deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
+       fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+       v210.sw_reset_210.reset_block_300 = 1;
+       v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+       fc->write_ibi_reg(fc,sw_reset_210,v210);
+       fc->write_ibi_reg(fc,ctrl_208,v208_save);
+}
+
+struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
+{
+       void *bus;
+       struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+                               GFP_KERNEL);
+       if (!fc) {
+               err("no memory");
+               return NULL;
+       }
+
+       bus = kzalloc(bus_specific_len, GFP_KERNEL);
+       if (!bus) {
+               err("no memory");
+               kfree(fc);
+               return NULL;
+       }
+
+       fc->bus_specific = bus;
+
+       return fc;
+}
+EXPORT_SYMBOL(flexcop_device_kmalloc);
+
+void flexcop_device_kfree(struct flexcop_device *fc)
+{
+       kfree(fc->bus_specific);
+       kfree(fc);
+}
+EXPORT_SYMBOL(flexcop_device_kfree);
+
+int flexcop_device_initialize(struct flexcop_device *fc)
+{
+       int ret;
+       ibi_zero.raw = 0;
+
+       flexcop_reset(fc);
+       flexcop_determine_revision(fc);
+       flexcop_sram_init(fc);
+       flexcop_hw_filter_init(fc);
+       flexcop_smc_ctrl(fc, 0);
+
+       ret = flexcop_dvb_init(fc);
+       if (ret)
+               goto error;
+
+       /* i2c has to be done before doing EEProm stuff -
+        * because the EEProm is accessed via i2c */
+       ret = flexcop_i2c_init(fc);
+       if (ret)
+               goto error;
+
+       /* do the MAC address reading after initializing the dvb_adapter */
+       if (fc->get_mac_addr(fc, 0) == 0) {
+               u8 *b = fc->dvb_adapter.proposed_mac;
+               info("MAC address = %pM", b);
+               flexcop_set_mac_filter(fc,b);
+               flexcop_mac_filter_ctrl(fc,1);
+       } else
+               warn("reading of MAC address failed.\n");
+
+       ret = flexcop_frontend_init(fc);
+       if (ret)
+               goto error;
+
+       flexcop_device_name(fc,"initialization of","complete");
+       return 0;
+
+error:
+       flexcop_device_exit(fc);
+       return ret;
+}
+EXPORT_SYMBOL(flexcop_device_initialize);
+
+void flexcop_device_exit(struct flexcop_device *fc)
+{
+       flexcop_frontend_exit(fc);
+       flexcop_i2c_exit(fc);
+       flexcop_dvb_exit(fc);
+}
+EXPORT_SYMBOL(flexcop_device_exit);
+
+static int flexcop_module_init(void)
+{
+       info(DRIVER_NAME " loaded successfully");
+       return 0;
+}
+
+static void flexcop_module_cleanup(void)
+{
+       info(DRIVER_NAME " unloaded successfully");
+}
+
+module_init(flexcop_module_init);
+module_exit(flexcop_module_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/b2c2/flexcop.h b/drivers/media/pci/b2c2/flexcop.h
new file mode 100644 (file)
index 0000000..897b10c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.h - private header file for all flexcop-chip-source files
+ * see flexcop.c for copyright information
+ */
+#ifndef __FLEXCOP_H__
+#define __FLEXCOP_H___
+
+#define FC_LOG_PREFIX "b2c2-flexcop"
+#include "flexcop-common.h"
+
+extern int b2c2_flexcop_debug;
+
+/* debug */
+#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+#define dprintk(level,args...) \
+       do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
+#else
+#define dprintk(level,args...)
+#endif
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_tuner(args...) dprintk(0x02, args)
+#define deb_i2c(args...) dprintk(0x04, args)
+#define deb_ts(args...) dprintk(0x08, args)
+#define deb_sram(args...) dprintk(0x10, args)
+#define deb_rdump(args...) dprintk(0x20, args)
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop_ibi_value_be.h b/drivers/media/pci/b2c2/flexcop_ibi_value_be.h
new file mode 100644 (file)
index 0000000..8f64bdb
--- /dev/null
@@ -0,0 +1,455 @@
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * register descriptions
+ * see flexcop.c for copyright information
+ */
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+       u32 raw;
+
+       struct {
+               u32 dma_address0                   :30;
+               u32 dma_0No_update                 : 1;
+               u32 dma_0start                     : 1;
+       } dma_0x0;
+
+       struct {
+               u32 dma_addr_size                  :24;
+               u32 DMA_maxpackets                 : 8;
+       } dma_0x4_remap;
+
+       struct {
+               u32 dma_addr_size                  :24;
+               u32 unused                         : 1;
+               u32 dma1timer                      : 7;
+       } dma_0x4_read;
+
+       struct {
+               u32 dma_addr_size                  :24;
+               u32 dmatimer                       : 7;
+               u32 unused                         : 1;
+       } dma_0x4_write;
+
+       struct {
+               u32 dma_cur_addr                   :30;
+               u32 unused                         : 2;
+       } dma_0x8;
+
+       struct {
+               u32 dma_address1                   :30;
+               u32 remap_enable                   : 1;
+               u32 dma_1start                     : 1;
+       } dma_0xc;
+
+       struct {
+               u32 st_done                        : 1;
+               u32 no_base_addr_ack_error         : 1;
+               u32 twoWS_port_reg                 : 2;
+               u32 total_bytes                    : 2;
+               u32 twoWS_rw                       : 1;
+               u32 working_start                  : 1;
+               u32 data1_reg                      : 8;
+               u32 baseaddr                       : 8;
+               u32 reserved1                      : 1;
+               u32 chipaddr                       : 7;
+       } tw_sm_c_100;
+
+       struct {
+               u32 unused                         : 6;
+               u32 force_stop                     : 1;
+               u32 exlicit_stops                  : 1;
+               u32 data4_reg                      : 8;
+               u32 data3_reg                      : 8;
+               u32 data2_reg                      : 8;
+       } tw_sm_c_104;
+
+       struct {
+               u32 reserved2                      :19;
+               u32 tlo1                           : 5;
+               u32 reserved1                      : 2;
+               u32 thi1                           : 6;
+       } tw_sm_c_108;
+
+       struct {
+               u32 reserved2                      :19;
+               u32 tlo1                           : 5;
+               u32 reserved1                      : 2;
+               u32 thi1                           : 6;
+       } tw_sm_c_10c;
+
+       struct {
+               u32 reserved2                      :19;
+               u32 tlo1                           : 5;
+               u32 reserved1                      : 2;
+               u32 thi1                           : 6;
+       } tw_sm_c_110;
+
+       struct {
+               u32 LNB_CTLPrescaler_sig           : 2;
+               u32 LNB_CTLLowCount_sig            :15;
+               u32 LNB_CTLHighCount_sig           :15;
+       } lnb_switch_freq_200;
+
+       struct {
+               u32 Rev_N_sig_reserved2            : 1;
+               u32 Rev_N_sig_caps                 : 1;
+               u32 Rev_N_sig_reserved1            : 2;
+               u32 Rev_N_sig_revision_hi          : 4;
+               u32 reserved                       :20;
+               u32 Per_reset_sig                  : 1;
+               u32 LNB_L_H_sig                    : 1;
+               u32 ACPI3_sig                      : 1;
+               u32 ACPI1_sig                      : 1;
+       } misc_204;
+
+       struct {
+               u32 unused                         : 9;
+               u32 Mailbox_from_V8_Enable_sig     : 1;
+               u32 DMA2_Size_IRQ_Enable_sig       : 1;
+               u32 DMA1_Size_IRQ_Enable_sig       : 1;
+               u32 DMA2_Timer_Enable_sig          : 1;
+               u32 DMA2_IRQ_Enable_sig            : 1;
+               u32 DMA1_Timer_Enable_sig          : 1;
+               u32 DMA1_IRQ_Enable_sig            : 1;
+               u32 Rcv_Data_sig                   : 1;
+               u32 MAC_filter_Mode_sig            : 1;
+               u32 Multi2_Enable_sig              : 1;
+               u32 Per_CA_Enable_sig              : 1;
+               u32 SMC_Enable_sig                 : 1;
+               u32 CA_Enable_sig                  : 1;
+               u32 WAN_CA_Enable_sig              : 1;
+               u32 WAN_Enable_sig                 : 1;
+               u32 Mask_filter_sig                : 1;
+               u32 Null_filter_sig                : 1;
+               u32 ECM_filter_sig                 : 1;
+               u32 EMM_filter_sig                 : 1;
+               u32 PMT_filter_sig                 : 1;
+               u32 PCR_filter_sig                 : 1;
+               u32 Stream2_filter_sig             : 1;
+               u32 Stream1_filter_sig             : 1;
+       } ctrl_208;
+
+       struct {
+               u32 reserved                       :21;
+               u32 Transport_Error                : 1;
+               u32 LLC_SNAP_FLAG_set              : 1;
+               u32 Continuity_error_flag          : 1;
+               u32 Data_receiver_error            : 1;
+               u32 Mailbox_from_V8_Status_sig     : 1;
+               u32 DMA2_Size_IRQ_Status           : 1;
+               u32 DMA1_Size_IRQ_Status           : 1;
+               u32 DMA2_Timer_Status              : 1;
+               u32 DMA2_IRQ_Status                : 1;
+               u32 DMA1_Timer_Status              : 1;
+               u32 DMA1_IRQ_Status                : 1;
+       } irq_20c;
+
+       struct {
+               u32 Special_controls               :16;
+               u32 Block_reset_enable             : 8;
+               u32 reset_block_700                : 1;
+               u32 reset_block_600                : 1;
+               u32 reset_block_500                : 1;
+               u32 reset_block_400                : 1;
+               u32 reset_block_300                : 1;
+               u32 reset_block_200                : 1;
+               u32 reset_block_100                : 1;
+               u32 reset_block_000                : 1;
+       } sw_reset_210;
+
+       struct {
+               u32 unused2                        :20;
+               u32 polarity_PS_ERR_sig            : 1;
+               u32 polarity_PS_SYNC_sig           : 1;
+               u32 polarity_PS_VALID_sig          : 1;
+               u32 polarity_PS_CLK_sig            : 1;
+               u32 unused1                        : 3;
+               u32 s2p_sel_sig                    : 1;
+               u32 section_pkg_enable_sig         : 1;
+               u32 halt_V8_sig                    : 1;
+               u32 v2WS_oe_sig                    : 1;
+               u32 vuart_oe_sig                   : 1;
+       } misc_214;
+
+       struct {
+               u32 Mailbox_from_V8                :32;
+       } mbox_v8_to_host_218;
+
+       struct {
+               u32 sysramaccess_busmuster         : 1;
+               u32 sysramaccess_write             : 1;
+               u32 unused                         : 7;
+               u32 sysramaccess_addr              :15;
+               u32 sysramaccess_data              : 8;
+       } mbox_host_to_v8_21c;
+
+       struct {
+               u32 debug_fifo_problem             : 1;
+               u32 debug_flag_write_status00      : 1;
+               u32 Stream2_trans                  : 1;
+               u32 Stream2_PID                    :13;
+               u32 debug_flag_pid_saved           : 1;
+               u32 MAC_Multicast_filter           : 1;
+               u32 Stream1_trans                  : 1;
+               u32 Stream1_PID                    :13;
+       } pid_filter_300;
+
+       struct {
+               u32 reserved                       : 2;
+               u32 PMT_trans                      : 1;
+               u32 PMT_PID                        :13;
+               u32 debug_overrun2                 : 1;
+               u32 debug_overrun3                 : 1;
+               u32 PCR_trans                      : 1;
+               u32 PCR_PID                        :13;
+       } pid_filter_304;
+
+       struct {
+               u32 reserved                       : 2;
+               u32 ECM_trans                      : 1;
+               u32 ECM_PID                        :13;
+               u32 EMM_filter_6                   : 1;
+               u32 EMM_filter_4                   : 1;
+               u32 EMM_trans                      : 1;
+               u32 EMM_PID                        :13;
+       } pid_filter_308;
+
+       struct {
+               u32 unused2                        : 3;
+               u32 Group_mask                     :13;
+               u32 unused1                        : 2;
+               u32 Group_trans                    : 1;
+               u32 Group_PID                      :13;
+       } pid_filter_30c_ext_ind_0_7;
+
+       struct {
+               u32 unused                         :15;
+               u32 net_master_read                :17;
+       } pid_filter_30c_ext_ind_1;
+
+       struct {
+               u32 unused                         :15;
+               u32 net_master_write               :17;
+       } pid_filter_30c_ext_ind_2;
+
+       struct {
+               u32 unused                         :15;
+               u32 next_net_master_write          :17;
+       } pid_filter_30c_ext_ind_3;
+
+       struct {
+               u32 reserved2                      : 5;
+               u32 stack_read                     :10;
+               u32 reserved1                      : 6;
+               u32 state_write                    :10;
+               u32 unused1                        : 1;
+       } pid_filter_30c_ext_ind_4;
+
+       struct {
+               u32 unused                         :22;
+               u32 stack_cnt                      :10;
+       } pid_filter_30c_ext_ind_5;
+
+       struct {
+               u32 unused                         : 4;
+               u32 data_size_reg                  :12;
+               u32 write_status4                  : 2;
+               u32 write_status1                  : 2;
+               u32 pid_fsm_save_reg300            : 2;
+               u32 pid_fsm_save_reg4              : 2;
+               u32 pid_fsm_save_reg3              : 2;
+               u32 pid_fsm_save_reg2              : 2;
+               u32 pid_fsm_save_reg1              : 2;
+               u32 pid_fsm_save_reg0              : 2;
+       } pid_filter_30c_ext_ind_6;
+
+       struct {
+               u32 unused                         :22;
+               u32 pass_alltables                 : 1;
+               u32 AB_select                      : 1;
+               u32 extra_index_reg                : 3;
+               u32 index_reg                      : 5;
+       } index_reg_310;
+
+       struct {
+               u32 reserved                       :17;
+               u32 PID_enable_bit                 : 1;
+               u32 PID_trans                      : 1;
+               u32 PID                            :13;
+       } pid_n_reg_314;
+
+       struct {
+               u32 reserved                       : 6;
+               u32 HighAB_bit                     : 1;
+               u32 Enable_bit                     : 1;
+               u32 A6_byte                        : 8;
+               u32 A5_byte                        : 8;
+               u32 A4_byte                        : 8;
+       } mac_low_reg_318;
+
+       struct {
+               u32 reserved                       : 8;
+               u32 A3_byte                        : 8;
+               u32 A2_byte                        : 8;
+               u32 A1_byte                        : 8;
+       } mac_high_reg_31c;
+
+       struct {
+               u32 data_Tag_ID                    :16;
+               u32 reserved                       :16;
+       } data_tag_400;
+
+       struct {
+               u32 Card_IDbyte3                   : 8;
+               u32 Card_IDbyte4                   : 8;
+               u32 Card_IDbyte5                   : 8;
+               u32 Card_IDbyte6                   : 8;
+       } card_id_408;
+
+       struct {
+               u32 Card_IDbyte1                   : 8;
+               u32 Card_IDbyte2                   : 8;
+       } card_id_40c;
+
+       struct {
+               u32 MAC6                           : 8;
+               u32 MAC3                           : 8;
+               u32 MAC2                           : 8;
+               u32 MAC1                           : 8;
+       } mac_address_418;
+
+       struct {
+               u32 reserved                       :16;
+               u32 MAC8                           : 8;
+               u32 MAC7                           : 8;
+       } mac_address_41c;
+
+       struct {
+               u32 reserved                       :21;
+               u32 txbuffempty                    : 1;
+               u32 ReceiveByteFrameError          : 1;
+               u32 ReceiveDataReady               : 1;
+               u32 transmitter_data_byte          : 8;
+       } ci_600;
+
+       struct {
+               u32 pi_component_reg               : 3;
+               u32 pi_rw                          : 1;
+               u32 pi_ha                          :20;
+               u32 pi_d                           : 8;
+       } pi_604;
+
+       struct {
+               u32 pi_busy_n                      : 1;
+               u32 pi_wait_n                      : 1;
+               u32 pi_timeout_status              : 1;
+               u32 pi_CiMax_IRQ_n                 : 1;
+               u32 config_cclk                    : 1;
+               u32 config_cs_n                    : 1;
+               u32 config_wr_n                    : 1;
+               u32 config_Prog_n                  : 1;
+               u32 config_Init_stat               : 1;
+               u32 config_Done_stat               : 1;
+               u32 pcmcia_b_mod_pwr_n             : 1;
+               u32 pcmcia_a_mod_pwr_n             : 1;
+               u32 reserved                       : 3;
+               u32 Timer_addr                     : 5;
+               u32 unused                         : 1;
+               u32 timer_data                     : 7;
+               u32 Timer_Load_req                 : 1;
+               u32 Timer_Read_req                 : 1;
+               u32 oncecycle_read                 : 1;
+               u32 serialReset                    : 1;
+       } pi_608;
+
+       struct {
+               u32 reserved                       : 6;
+               u32 rw_flag                        : 1;
+               u32 dvb_en                         : 1;
+               u32 key_array_row                  : 5;
+               u32 key_array_col                  : 3;
+               u32 key_code                       : 2;
+               u32 key_enable                     : 1;
+               u32 PID                            :13;
+       } dvb_reg_60c;
+
+       struct {
+               u32 start_sram_ibi                 : 1;
+               u32 reserved2                      : 1;
+               u32 ce_pin_reg                     : 1;
+               u32 oe_pin_reg                     : 1;
+               u32 reserved1                      : 3;
+               u32 sc_xfer_bit                    : 1;
+               u32 sram_data                      : 8;
+               u32 sram_rw                        : 1;
+               u32 sram_addr                      :15;
+       } sram_ctrl_reg_700;
+
+       struct {
+               u32 net_addr_write                 :16;
+               u32 net_addr_read                  :16;
+       } net_buf_reg_704;
+
+       struct {
+               u32 cai_cnt                        : 4;
+               u32 reserved2                      : 6;
+               u32 cai_write                      :11;
+               u32 reserved1                      : 5;
+               u32 cai_read                       :11;
+       } cai_buf_reg_708;
+
+       struct {
+               u32 cao_cnt                        : 4;
+               u32 reserved2                      : 6;
+               u32 cap_write                      :11;
+               u32 reserved1                      : 5;
+               u32 cao_read                       :11;
+       } cao_buf_reg_70c;
+
+       struct {
+               u32 media_cnt                      : 4;
+               u32 reserved2                      : 6;
+               u32 media_write                    :11;
+               u32 reserved1                      : 5;
+               u32 media_read                     :11;
+       } media_buf_reg_710;
+
+       struct {
+               u32 reserved                       :17;
+               u32 ctrl_maximumfill               : 1;
+               u32 ctrl_sramdma                   : 1;
+               u32 ctrl_usb_wan                   : 1;
+               u32 cao_ovflow_error               : 1;
+               u32 cai_ovflow_error               : 1;
+               u32 media_ovflow_error             : 1;
+               u32 net_ovflow_error               : 1;
+               u32 MEDIA_Dest                     : 2;
+               u32 CAO_Dest                       : 2;
+               u32 CAI_Dest                       : 2;
+               u32 NET_Dest                       : 2;
+       } sram_dest_reg_714;
+
+       struct {
+               u32 reserved3                      :11;
+               u32 net_addr_write                 : 1;
+               u32 reserved2                      : 3;
+               u32 net_addr_read                  : 1;
+               u32 reserved1                      : 4;
+               u32 net_cnt                        :12;
+       } net_buf_reg_718;
+
+       struct {
+               u32 reserved3                      : 4;
+               u32 wan_pkt_frame                  : 4;
+               u32 reserved2                      : 4;
+               u32 sram_memmap                    : 2;
+               u32 sram_chip                      : 2;
+               u32 wan_wait_state                 : 8;
+               u32 reserved1                      : 6;
+               u32 wan_speed_sig                  : 2;
+       } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/pci/b2c2/flexcop_ibi_value_le.h b/drivers/media/pci/b2c2/flexcop_ibi_value_le.h
new file mode 100644 (file)
index 0000000..c75830d
--- /dev/null
@@ -0,0 +1,455 @@
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * register descriptions
+ * see flexcop.c for copyright information
+ */
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+       u32 raw;
+
+       struct {
+               u32 dma_0start                     : 1;
+               u32 dma_0No_update                 : 1;
+               u32 dma_address0                   :30;
+       } dma_0x0;
+
+       struct {
+               u32 DMA_maxpackets                 : 8;
+               u32 dma_addr_size                  :24;
+       } dma_0x4_remap;
+
+       struct {
+               u32 dma1timer                      : 7;
+               u32 unused                         : 1;
+               u32 dma_addr_size                  :24;
+       } dma_0x4_read;
+
+       struct {
+               u32 unused                         : 1;
+               u32 dmatimer                       : 7;
+               u32 dma_addr_size                  :24;
+       } dma_0x4_write;
+
+       struct {
+               u32 unused                         : 2;
+               u32 dma_cur_addr                   :30;
+       } dma_0x8;
+
+       struct {
+               u32 dma_1start                     : 1;
+               u32 remap_enable                   : 1;
+               u32 dma_address1                   :30;
+       } dma_0xc;
+
+       struct {
+               u32 chipaddr                       : 7;
+               u32 reserved1                      : 1;
+               u32 baseaddr                       : 8;
+               u32 data1_reg                      : 8;
+               u32 working_start                  : 1;
+               u32 twoWS_rw                       : 1;
+               u32 total_bytes                    : 2;
+               u32 twoWS_port_reg                 : 2;
+               u32 no_base_addr_ack_error         : 1;
+               u32 st_done                        : 1;
+       } tw_sm_c_100;
+
+       struct {
+               u32 data2_reg                      : 8;
+               u32 data3_reg                      : 8;
+               u32 data4_reg                      : 8;
+               u32 exlicit_stops                  : 1;
+               u32 force_stop                     : 1;
+               u32 unused                         : 6;
+       } tw_sm_c_104;
+
+       struct {
+               u32 thi1                           : 6;
+               u32 reserved1                      : 2;
+               u32 tlo1                           : 5;
+               u32 reserved2                      :19;
+       } tw_sm_c_108;
+
+       struct {
+               u32 thi1                           : 6;
+               u32 reserved1                      : 2;
+               u32 tlo1                           : 5;
+               u32 reserved2                      :19;
+       } tw_sm_c_10c;
+
+       struct {
+               u32 thi1                           : 6;
+               u32 reserved1                      : 2;
+               u32 tlo1                           : 5;
+               u32 reserved2                      :19;
+       } tw_sm_c_110;
+
+       struct {
+               u32 LNB_CTLHighCount_sig           :15;
+               u32 LNB_CTLLowCount_sig            :15;
+               u32 LNB_CTLPrescaler_sig           : 2;
+       } lnb_switch_freq_200;
+
+       struct {
+               u32 ACPI1_sig                      : 1;
+               u32 ACPI3_sig                      : 1;
+               u32 LNB_L_H_sig                    : 1;
+               u32 Per_reset_sig                  : 1;
+               u32 reserved                       :20;
+               u32 Rev_N_sig_revision_hi          : 4;
+               u32 Rev_N_sig_reserved1            : 2;
+               u32 Rev_N_sig_caps                 : 1;
+               u32 Rev_N_sig_reserved2            : 1;
+       } misc_204;
+
+       struct {
+               u32 Stream1_filter_sig             : 1;
+               u32 Stream2_filter_sig             : 1;
+               u32 PCR_filter_sig                 : 1;
+               u32 PMT_filter_sig                 : 1;
+               u32 EMM_filter_sig                 : 1;
+               u32 ECM_filter_sig                 : 1;
+               u32 Null_filter_sig                : 1;
+               u32 Mask_filter_sig                : 1;
+               u32 WAN_Enable_sig                 : 1;
+               u32 WAN_CA_Enable_sig              : 1;
+               u32 CA_Enable_sig                  : 1;
+               u32 SMC_Enable_sig                 : 1;
+               u32 Per_CA_Enable_sig              : 1;
+               u32 Multi2_Enable_sig              : 1;
+               u32 MAC_filter_Mode_sig            : 1;
+               u32 Rcv_Data_sig                   : 1;
+               u32 DMA1_IRQ_Enable_sig            : 1;
+               u32 DMA1_Timer_Enable_sig          : 1;
+               u32 DMA2_IRQ_Enable_sig            : 1;
+               u32 DMA2_Timer_Enable_sig          : 1;
+               u32 DMA1_Size_IRQ_Enable_sig       : 1;
+               u32 DMA2_Size_IRQ_Enable_sig       : 1;
+               u32 Mailbox_from_V8_Enable_sig     : 1;
+               u32 unused                         : 9;
+       } ctrl_208;
+
+       struct {
+               u32 DMA1_IRQ_Status                : 1;
+               u32 DMA1_Timer_Status              : 1;
+               u32 DMA2_IRQ_Status                : 1;
+               u32 DMA2_Timer_Status              : 1;
+               u32 DMA1_Size_IRQ_Status           : 1;
+               u32 DMA2_Size_IRQ_Status           : 1;
+               u32 Mailbox_from_V8_Status_sig     : 1;
+               u32 Data_receiver_error            : 1;
+               u32 Continuity_error_flag          : 1;
+               u32 LLC_SNAP_FLAG_set              : 1;
+               u32 Transport_Error                : 1;
+               u32 reserved                       :21;
+       } irq_20c;
+
+       struct {
+               u32 reset_block_000                : 1;
+               u32 reset_block_100                : 1;
+               u32 reset_block_200                : 1;
+               u32 reset_block_300                : 1;
+               u32 reset_block_400                : 1;
+               u32 reset_block_500                : 1;
+               u32 reset_block_600                : 1;
+               u32 reset_block_700                : 1;
+               u32 Block_reset_enable             : 8;
+               u32 Special_controls               :16;
+       } sw_reset_210;
+
+       struct {
+               u32 vuart_oe_sig                   : 1;
+               u32 v2WS_oe_sig                    : 1;
+               u32 halt_V8_sig                    : 1;
+               u32 section_pkg_enable_sig         : 1;
+               u32 s2p_sel_sig                    : 1;
+               u32 unused1                        : 3;
+               u32 polarity_PS_CLK_sig            : 1;
+               u32 polarity_PS_VALID_sig          : 1;
+               u32 polarity_PS_SYNC_sig           : 1;
+               u32 polarity_PS_ERR_sig            : 1;
+               u32 unused2                        :20;
+       } misc_214;
+
+       struct {
+               u32 Mailbox_from_V8                :32;
+       } mbox_v8_to_host_218;
+
+       struct {
+               u32 sysramaccess_data              : 8;
+               u32 sysramaccess_addr              :15;
+               u32 unused                         : 7;
+               u32 sysramaccess_write             : 1;
+               u32 sysramaccess_busmuster         : 1;
+       } mbox_host_to_v8_21c;
+
+       struct {
+               u32 Stream1_PID                    :13;
+               u32 Stream1_trans                  : 1;
+               u32 MAC_Multicast_filter           : 1;
+               u32 debug_flag_pid_saved           : 1;
+               u32 Stream2_PID                    :13;
+               u32 Stream2_trans                  : 1;
+               u32 debug_flag_write_status00      : 1;
+               u32 debug_fifo_problem             : 1;
+       } pid_filter_300;
+
+       struct {
+               u32 PCR_PID                        :13;
+               u32 PCR_trans                      : 1;
+               u32 debug_overrun3                 : 1;
+               u32 debug_overrun2                 : 1;
+               u32 PMT_PID                        :13;
+               u32 PMT_trans                      : 1;
+               u32 reserved                       : 2;
+       } pid_filter_304;
+
+       struct {
+               u32 EMM_PID                        :13;
+               u32 EMM_trans                      : 1;
+               u32 EMM_filter_4                   : 1;
+               u32 EMM_filter_6                   : 1;
+               u32 ECM_PID                        :13;
+               u32 ECM_trans                      : 1;
+               u32 reserved                       : 2;
+       } pid_filter_308;
+
+       struct {
+               u32 Group_PID                      :13;
+               u32 Group_trans                    : 1;
+               u32 unused1                        : 2;
+               u32 Group_mask                     :13;
+               u32 unused2                        : 3;
+       } pid_filter_30c_ext_ind_0_7;
+
+       struct {
+               u32 net_master_read                :17;
+               u32 unused                         :15;
+       } pid_filter_30c_ext_ind_1;
+
+       struct {
+               u32 net_master_write               :17;
+               u32 unused                         :15;
+       } pid_filter_30c_ext_ind_2;
+
+       struct {
+               u32 next_net_master_write          :17;
+               u32 unused                         :15;
+       } pid_filter_30c_ext_ind_3;
+
+       struct {
+               u32 unused1                        : 1;
+               u32 state_write                    :10;
+               u32 reserved1                      : 6;
+               u32 stack_read                     :10;
+               u32 reserved2                      : 5;
+       } pid_filter_30c_ext_ind_4;
+
+       struct {
+               u32 stack_cnt                      :10;
+               u32 unused                         :22;
+       } pid_filter_30c_ext_ind_5;
+
+       struct {
+               u32 pid_fsm_save_reg0              : 2;
+               u32 pid_fsm_save_reg1              : 2;
+               u32 pid_fsm_save_reg2              : 2;
+               u32 pid_fsm_save_reg3              : 2;
+               u32 pid_fsm_save_reg4              : 2;
+               u32 pid_fsm_save_reg300            : 2;
+               u32 write_status1                  : 2;
+               u32 write_status4                  : 2;
+               u32 data_size_reg                  :12;
+               u32 unused                         : 4;
+       } pid_filter_30c_ext_ind_6;
+
+       struct {
+               u32 index_reg                      : 5;
+               u32 extra_index_reg                : 3;
+               u32 AB_select                      : 1;
+               u32 pass_alltables                 : 1;
+               u32 unused                         :22;
+       } index_reg_310;
+
+       struct {
+               u32 PID                            :13;
+               u32 PID_trans                      : 1;
+               u32 PID_enable_bit                 : 1;
+               u32 reserved                       :17;
+       } pid_n_reg_314;
+
+       struct {
+               u32 A4_byte                        : 8;
+               u32 A5_byte                        : 8;
+               u32 A6_byte                        : 8;
+               u32 Enable_bit                     : 1;
+               u32 HighAB_bit                     : 1;
+               u32 reserved                       : 6;
+       } mac_low_reg_318;
+
+       struct {
+               u32 A1_byte                        : 8;
+               u32 A2_byte                        : 8;
+               u32 A3_byte                        : 8;
+               u32 reserved                       : 8;
+       } mac_high_reg_31c;
+
+       struct {
+               u32 reserved                       :16;
+               u32 data_Tag_ID                    :16;
+       } data_tag_400;
+
+       struct {
+               u32 Card_IDbyte6                   : 8;
+               u32 Card_IDbyte5                   : 8;
+               u32 Card_IDbyte4                   : 8;
+               u32 Card_IDbyte3                   : 8;
+       } card_id_408;
+
+       struct {
+               u32 Card_IDbyte2                   : 8;
+               u32 Card_IDbyte1                   : 8;
+       } card_id_40c;
+
+       struct {
+               u32 MAC1                           : 8;
+               u32 MAC2                           : 8;
+               u32 MAC3                           : 8;
+               u32 MAC6                           : 8;
+       } mac_address_418;
+
+       struct {
+               u32 MAC7                           : 8;
+               u32 MAC8                           : 8;
+               u32 reserved                       :16;
+       } mac_address_41c;
+
+       struct {
+               u32 transmitter_data_byte          : 8;
+               u32 ReceiveDataReady               : 1;
+               u32 ReceiveByteFrameError          : 1;
+               u32 txbuffempty                    : 1;
+               u32 reserved                       :21;
+       } ci_600;
+
+       struct {
+               u32 pi_d                           : 8;
+               u32 pi_ha                          :20;
+               u32 pi_rw                          : 1;
+               u32 pi_component_reg               : 3;
+       } pi_604;
+
+       struct {
+               u32 serialReset                    : 1;
+               u32 oncecycle_read                 : 1;
+               u32 Timer_Read_req                 : 1;
+               u32 Timer_Load_req                 : 1;
+               u32 timer_data                     : 7;
+               u32 unused                         : 1;
+               u32 Timer_addr                     : 5;
+               u32 reserved                       : 3;
+               u32 pcmcia_a_mod_pwr_n             : 1;
+               u32 pcmcia_b_mod_pwr_n             : 1;
+               u32 config_Done_stat               : 1;
+               u32 config_Init_stat               : 1;
+               u32 config_Prog_n                  : 1;
+               u32 config_wr_n                    : 1;
+               u32 config_cs_n                    : 1;
+               u32 config_cclk                    : 1;
+               u32 pi_CiMax_IRQ_n                 : 1;
+               u32 pi_timeout_status              : 1;
+               u32 pi_wait_n                      : 1;
+               u32 pi_busy_n                      : 1;
+       } pi_608;
+
+       struct {
+               u32 PID                            :13;
+               u32 key_enable                     : 1;
+               u32 key_code                       : 2;
+               u32 key_array_col                  : 3;
+               u32 key_array_row                  : 5;
+               u32 dvb_en                         : 1;
+               u32 rw_flag                        : 1;
+               u32 reserved                       : 6;
+       } dvb_reg_60c;
+
+       struct {
+               u32 sram_addr                      :15;
+               u32 sram_rw                        : 1;
+               u32 sram_data                      : 8;
+               u32 sc_xfer_bit                    : 1;
+               u32 reserved1                      : 3;
+               u32 oe_pin_reg                     : 1;
+               u32 ce_pin_reg                     : 1;
+               u32 reserved2                      : 1;
+               u32 start_sram_ibi                 : 1;
+       } sram_ctrl_reg_700;
+
+       struct {
+               u32 net_addr_read                  :16;
+               u32 net_addr_write                 :16;
+       } net_buf_reg_704;
+
+       struct {
+               u32 cai_read                       :11;
+               u32 reserved1                      : 5;
+               u32 cai_write                      :11;
+               u32 reserved2                      : 6;
+               u32 cai_cnt                        : 4;
+       } cai_buf_reg_708;
+
+       struct {
+               u32 cao_read                       :11;
+               u32 reserved1                      : 5;
+               u32 cap_write                      :11;
+               u32 reserved2                      : 6;
+               u32 cao_cnt                        : 4;
+       } cao_buf_reg_70c;
+
+       struct {
+               u32 media_read                     :11;
+               u32 reserved1                      : 5;
+               u32 media_write                    :11;
+               u32 reserved2                      : 6;
+               u32 media_cnt                      : 4;
+       } media_buf_reg_710;
+
+       struct {
+               u32 NET_Dest                       : 2;
+               u32 CAI_Dest                       : 2;
+               u32 CAO_Dest                       : 2;
+               u32 MEDIA_Dest                     : 2;
+               u32 net_ovflow_error               : 1;
+               u32 media_ovflow_error             : 1;
+               u32 cai_ovflow_error               : 1;
+               u32 cao_ovflow_error               : 1;
+               u32 ctrl_usb_wan                   : 1;
+               u32 ctrl_sramdma                   : 1;
+               u32 ctrl_maximumfill               : 1;
+               u32 reserved                       :17;
+       } sram_dest_reg_714;
+
+       struct {
+               u32 net_cnt                        :12;
+               u32 reserved1                      : 4;
+               u32 net_addr_read                  : 1;
+               u32 reserved2                      : 3;
+               u32 net_addr_write                 : 1;
+               u32 reserved3                      :11;
+       } net_buf_reg_718;
+
+       struct {
+               u32 wan_speed_sig                  : 2;
+               u32 reserved1                      : 6;
+               u32 wan_wait_state                 : 8;
+               u32 sram_chip                      : 2;
+               u32 sram_memmap                    : 2;
+               u32 reserved2                      : 4;
+               u32 wan_pkt_frame                  : 4;
+               u32 reserved3                      : 4;
+       } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig
new file mode 100644 (file)
index 0000000..8668e63
--- /dev/null
@@ -0,0 +1,22 @@
+config DVB_BT8XX
+       tristate "BT8xx based PCI cards"
+       depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_SP887X if !DVB_FE_CUSTOMISE
+       select DVB_NXT6000 if !DVB_FE_CUSTOMISE
+       select DVB_CX24110 if !DVB_FE_CUSTOMISE
+       select DVB_OR51211 if !DVB_FE_CUSTOMISE
+       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+       help
+         Support for PCI cards based on the Bt8xx PCI bridge. Examples are
+         the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
+         the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
+         some AVerMedia cards.
+
+         Since these cards have no MPEG decoder onboard, they transmit
+         only compressed MPEG data over the PCI bus, so you need
+         an external software decoder to watch TV on your computer.
+
+         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
new file mode 100644 (file)
index 0000000..36591ae
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/video/bt8xx
+ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
new file mode 100644 (file)
index 0000000..b34fa95
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
+ *
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
+ *
+ * large parts based on the bttv driver
+ * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@metzlerbros.de)
+ *                        & Marcus Metzler (mocm@metzlerbros.de)
+ * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <linux/ioport.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "bt878.h"
+#include "dst_priv.h"
+
+
+/**************************************/
+/* Miscellaneous utility  definitions */
+/**************************************/
+
+static unsigned int bt878_verbose = 1;
+static unsigned int bt878_debug;
+
+module_param_named(verbose, bt878_verbose, int, 0444);
+MODULE_PARM_DESC(verbose,
+                "verbose startup messages, default is 1 (yes)");
+module_param_named(debug, bt878_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off).");
+
+int bt878_num;
+struct bt878 bt878[BT878_MAX];
+
+EXPORT_SYMBOL(bt878_num);
+EXPORT_SYMBOL(bt878);
+
+#define btwrite(dat,adr)    bmtwrite((dat), (bt->bt878_mem+(adr)))
+#define btread(adr)         bmtread(bt->bt878_mem+(adr))
+
+#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
+#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
+#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
+
+#if defined(dprintk)
+#undef dprintk
+#endif
+#define dprintk(fmt, arg...) \
+       do { \
+               if (bt878_debug) \
+                       printk(KERN_DEBUG fmt, ##arg); \
+       } while (0)
+
+static void bt878_mem_free(struct bt878 *bt)
+{
+       if (bt->buf_cpu) {
+               pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
+                                   bt->buf_dma);
+               bt->buf_cpu = NULL;
+       }
+
+       if (bt->risc_cpu) {
+               pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
+                                   bt->risc_dma);
+               bt->risc_cpu = NULL;
+       }
+}
+
+static int bt878_mem_alloc(struct bt878 *bt)
+{
+       if (!bt->buf_cpu) {
+               bt->buf_size = 128 * 1024;
+
+               bt->buf_cpu =
+                   pci_alloc_consistent(bt->dev, bt->buf_size,
+                                        &bt->buf_dma);
+
+               if (!bt->buf_cpu)
+                       return -ENOMEM;
+
+               memset(bt->buf_cpu, 0, bt->buf_size);
+       }
+
+       if (!bt->risc_cpu) {
+               bt->risc_size = PAGE_SIZE;
+               bt->risc_cpu =
+                   pci_alloc_consistent(bt->dev, bt->risc_size,
+                                        &bt->risc_dma);
+
+               if (!bt->risc_cpu) {
+                       bt878_mem_free(bt);
+                       return -ENOMEM;
+               }
+
+               memset(bt->risc_cpu, 0, bt->risc_size);
+       }
+
+       return 0;
+}
+
+/* RISC instructions */
+#define RISC_WRITE             (0x01 << 28)
+#define RISC_JUMP              (0x07 << 28)
+#define RISC_SYNC              (0x08 << 28)
+
+/* RISC bits */
+#define RISC_WR_SOL            (1 << 27)
+#define RISC_WR_EOL            (1 << 26)
+#define RISC_IRQ               (1 << 24)
+#define RISC_STATUS(status)    ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
+#define RISC_SYNC_RESYNC       (1 << 15)
+#define RISC_SYNC_FM1          0x06
+#define RISC_SYNC_VRO          0x0C
+
+#define RISC_FLUSH()           bt->risc_pos = 0
+#define RISC_INSTR(instr)      bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
+
+static int bt878_make_risc(struct bt878 *bt)
+{
+       bt->block_bytes = bt->buf_size >> 4;
+       bt->block_count = 1 << 4;
+       bt->line_bytes = bt->block_bytes;
+       bt->line_count = bt->block_count;
+
+       while (bt->line_bytes > 4095) {
+               bt->line_bytes >>= 1;
+               bt->line_count <<= 1;
+       }
+
+       if (bt->line_count > 255) {
+               printk(KERN_ERR "bt878: buffer size error!\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
+{
+       u32 buf_pos = 0;
+       u32 line;
+
+       RISC_FLUSH();
+       RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
+       RISC_INSTR(0);
+
+       dprintk("bt878: risc len lines %u, bytes per line %u\n",
+                       bt->line_count, bt->line_bytes);
+       for (line = 0; line < bt->line_count; line++) {
+               // At the beginning of every block we issue an IRQ with previous (finished) block number set
+               if (!(buf_pos % bt->block_bytes))
+                       RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
+                                  RISC_IRQ |
+                                  RISC_STATUS(((buf_pos /
+                                                bt->block_bytes) +
+                                               (bt->block_count -
+                                                1)) %
+                                              bt->block_count) | bt->
+                                  line_bytes);
+               else
+                       RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
+                                  bt->line_bytes);
+               RISC_INSTR(bt->buf_dma + buf_pos);
+               buf_pos += bt->line_bytes;
+       }
+
+       RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
+       RISC_INSTR(0);
+
+       RISC_INSTR(RISC_JUMP);
+       RISC_INSTR(bt->risc_dma);
+
+       btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
+}
+
+/*****************************/
+/* Start/Stop grabbing funcs */
+/*****************************/
+
+void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
+               u32 irq_err_ignore)
+{
+       u32 int_mask;
+
+       dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
+       /* complete the writing of the risc dma program now we have
+        * the card specifics
+        */
+       bt878_risc_program(bt, op_sync_orin);
+       controlreg &= ~0x1f;
+       controlreg |= 0x1b;
+
+       btwrite(bt->risc_dma, BT878_ARISC_START);
+
+       /* original int mask had :
+        *    6    2    8    4    0
+        * 1111 1111 1000 0000 0000
+        * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
+        * Hacked for DST to:
+        * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
+        */
+       int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
+               BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
+               BT878_AFBUS | BT878_ARISCI;
+
+
+       /* ignore pesky bits */
+       int_mask &= ~irq_err_ignore;
+
+       btwrite(int_mask, BT878_AINT_MASK);
+       btwrite(controlreg, BT878_AGPIO_DMA_CTL);
+}
+
+void bt878_stop(struct bt878 *bt)
+{
+       u32 stat;
+       int i = 0;
+
+       dprintk("bt878 debug: bt878_stop\n");
+
+       btwrite(0, BT878_AINT_MASK);
+       btand(~0x13, BT878_AGPIO_DMA_CTL);
+
+       do {
+               stat = btread(BT878_AINT_STAT);
+               if (!(stat & BT878_ARISC_EN))
+                       break;
+               i++;
+       } while (i < 500);
+
+       dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
+               bt->nr, i, stat);
+}
+
+EXPORT_SYMBOL(bt878_start);
+EXPORT_SYMBOL(bt878_stop);
+
+/*****************************/
+/* Interrupt service routine */
+/*****************************/
+
+static irqreturn_t bt878_irq(int irq, void *dev_id)
+{
+       u32 stat, astat, mask;
+       int count;
+       struct bt878 *bt;
+
+       bt = (struct bt878 *) dev_id;
+
+       count = 0;
+       while (1) {
+               stat = btread(BT878_AINT_STAT);
+               mask = btread(BT878_AINT_MASK);
+               if (!(astat = (stat & mask)))
+                       return IRQ_NONE;        /* this interrupt is not for me */
+/*             dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
+               btwrite(astat, BT878_AINT_STAT);        /* try to clear interrupt condition */
+
+
+               if (astat & (BT878_ASCERR | BT878_AOCERR)) {
+                       if (bt878_verbose) {
+                               printk(KERN_INFO
+                                      "bt878(%d): irq%s%s risc_pc=%08x\n",
+                                      bt->nr,
+                                      (astat & BT878_ASCERR) ? " SCERR" :
+                                      "",
+                                      (astat & BT878_AOCERR) ? " OCERR" :
+                                      "", btread(BT878_ARISC_PC));
+                       }
+               }
+               if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
+                       if (bt878_verbose) {
+                               printk(KERN_INFO
+                                    "bt878(%d): irq%s%s%s risc_pc=%08x\n",
+                                    bt->nr,
+                                    (astat & BT878_APABORT) ? " PABORT" :
+                                    "",
+                                    (astat & BT878_ARIPERR) ? " RIPERR" :
+                                    "",
+                                    (astat & BT878_APPERR) ? " PPERR" :
+                                    "", btread(BT878_ARISC_PC));
+                       }
+               }
+               if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
+                       if (bt878_verbose) {
+                               printk(KERN_INFO
+                                    "bt878(%d): irq%s%s%s risc_pc=%08x\n",
+                                    bt->nr,
+                                    (astat & BT878_AFDSR) ? " FDSR" : "",
+                                    (astat & BT878_AFTRGT) ? " FTRGT" :
+                                    "",
+                                    (astat & BT878_AFBUS) ? " FBUS" : "",
+                                    btread(BT878_ARISC_PC));
+                       }
+               }
+               if (astat & BT878_ARISCI) {
+                       bt->finished_block = (stat & BT878_ARISCS) >> 28;
+                       tasklet_schedule(&bt->tasklet);
+                       break;
+               }
+               count++;
+               if (count > 20) {
+                       btwrite(0, BT878_AINT_MASK);
+                       printk(KERN_ERR
+                              "bt878(%d): IRQ lockup, cleared int mask\n",
+                              bt->nr);
+                       break;
+               }
+       }
+       return IRQ_HANDLED;
+}
+
+int
+bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
+{
+       int retval;
+
+       retval = 0;
+       if (mutex_lock_interruptible(&bt->gpio_lock))
+               return -ERESTARTSYS;
+       /* special gpio signal */
+       switch (cmd) {
+           case DST_IG_ENABLE:
+               // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
+               retval = bttv_gpio_enable(bt->bttv_nr,
+                               mp->enb.mask,
+                               mp->enb.enable);
+               break;
+           case DST_IG_WRITE:
+               // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
+               retval = bttv_write_gpio(bt->bttv_nr,
+                               mp->outp.mask,
+                               mp->outp.highvals);
+
+               break;
+           case DST_IG_READ:
+               /* read */
+               retval =  bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
+               // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
+               break;
+           case DST_IG_TS:
+               /* Set packet size */
+               bt->TS_Size = mp->psize;
+               break;
+
+           default:
+               retval = -EINVAL;
+               break;
+       }
+       mutex_unlock(&bt->gpio_lock);
+       return retval;
+}
+
+EXPORT_SYMBOL(bt878_device_control);
+
+#define BROOKTREE_878_DEVICE(vend, dev, name) \
+       { \
+               .vendor = PCI_VENDOR_ID_BROOKTREE, \
+               .device = PCI_DEVICE_ID_BROOKTREE_878, \
+               .subvendor = (vend), .subdevice = (dev), \
+               .driver_data = (unsigned long) name \
+       }
+
+static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
+       BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"),
+       BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"),
+       BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"),
+       BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"),
+       BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"),
+       BROOKTREE_878_DEVICE(0x270f, 0xfc00,
+                               "ChainTech digitop DST-1000 DVB-S"),
+       BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"),
+       BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"),
+       BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"),
+       BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"),
+       BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"),
+       BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"),
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
+
+static const char * __devinit card_name(const struct pci_device_id *id)
+{
+       return id->driver_data ? (const char *)id->driver_data : "Unknown";
+}
+
+/***********************/
+/* PCI device handling */
+/***********************/
+
+static int __devinit bt878_probe(struct pci_dev *dev,
+                                const struct pci_device_id *pci_id)
+{
+       int result = 0;
+       unsigned char lat;
+       struct bt878 *bt;
+#if defined(__powerpc__)
+       unsigned int cmd;
+#endif
+       unsigned int cardid;
+
+       printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
+              bt878_num);
+       if (bt878_num >= BT878_MAX) {
+               printk(KERN_ERR "bt878: Too many devices inserted\n");
+               result = -ENOMEM;
+               goto fail0;
+       }
+       if (pci_enable_device(dev))
+               return -EIO;
+
+       cardid = dev->subsystem_device << 16;
+       cardid |= dev->subsystem_vendor;
+
+       printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n",
+                               __func__, cardid, card_name(pci_id));
+
+       bt = &bt878[bt878_num];
+       bt->dev = dev;
+       bt->nr = bt878_num;
+       bt->shutdown = 0;
+
+       bt->id = dev->device;
+       bt->irq = dev->irq;
+       bt->bt878_adr = pci_resource_start(dev, 0);
+       if (!request_mem_region(pci_resource_start(dev, 0),
+                               pci_resource_len(dev, 0), "bt878")) {
+               result = -EBUSY;
+               goto fail0;
+       }
+
+       bt->revision = dev->revision;
+       pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+
+
+       printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
+              bt878_num, bt->id, bt->revision, dev->bus->number,
+              PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+       printk("irq: %d, latency: %d, memory: 0x%lx\n",
+              bt->irq, lat, bt->bt878_adr);
+
+
+#if defined(__powerpc__)
+       /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
+       /* response on cards with no firmware is not enabled by OF */
+       pci_read_config_dword(dev, PCI_COMMAND, &cmd);
+       cmd = (cmd | PCI_COMMAND_MEMORY);
+       pci_write_config_dword(dev, PCI_COMMAND, cmd);
+#endif
+
+#ifdef __sparc__
+       bt->bt878_mem = (unsigned char *) bt->bt878_adr;
+#else
+       bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
+#endif
+
+       /* clear interrupt mask */
+       btwrite(0, BT848_INT_MASK);
+
+       result = request_irq(bt->irq, bt878_irq,
+                            IRQF_SHARED | IRQF_DISABLED, "bt878",
+                            (void *) bt);
+       if (result == -EINVAL) {
+               printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
+                      bt878_num);
+               goto fail1;
+       }
+       if (result == -EBUSY) {
+               printk(KERN_ERR
+                      "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
+                      bt878_num, bt->irq);
+               goto fail1;
+       }
+       if (result < 0)
+               goto fail1;
+
+       pci_set_master(dev);
+       pci_set_drvdata(dev, bt);
+
+       if ((result = bt878_mem_alloc(bt))) {
+               printk(KERN_ERR "bt878: failed to allocate memory!\n");
+               goto fail2;
+       }
+
+       bt878_make_risc(bt);
+       btwrite(0, BT878_AINT_MASK);
+       bt878_num++;
+
+       return 0;
+
+      fail2:
+       free_irq(bt->irq, bt);
+      fail1:
+       release_mem_region(pci_resource_start(bt->dev, 0),
+                          pci_resource_len(bt->dev, 0));
+      fail0:
+       pci_disable_device(dev);
+       return result;
+}
+
+static void __devexit bt878_remove(struct pci_dev *pci_dev)
+{
+       u8 command;
+       struct bt878 *bt = pci_get_drvdata(pci_dev);
+
+       if (bt878_verbose)
+               printk(KERN_INFO "bt878(%d): unloading\n", bt->nr);
+
+       /* turn off all capturing, DMA and IRQs */
+       btand(~0x13, BT878_AGPIO_DMA_CTL);
+
+       /* first disable interrupts before unmapping the memory! */
+       btwrite(0, BT878_AINT_MASK);
+       btwrite(~0U, BT878_AINT_STAT);
+
+       /* disable PCI bus-mastering */
+       pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
+       /* Should this be &=~ ?? */
+       command &= ~PCI_COMMAND_MASTER;
+       pci_write_config_byte(bt->dev, PCI_COMMAND, command);
+
+       free_irq(bt->irq, bt);
+       printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
+       if (bt->bt878_mem)
+               iounmap(bt->bt878_mem);
+
+       release_mem_region(pci_resource_start(bt->dev, 0),
+                          pci_resource_len(bt->dev, 0));
+       /* wake up any waiting processes
+          because shutdown flag is set, no new processes (in this queue)
+          are expected
+        */
+       bt->shutdown = 1;
+       bt878_mem_free(bt);
+
+       pci_set_drvdata(pci_dev, NULL);
+       pci_disable_device(pci_dev);
+       return;
+}
+
+static struct pci_driver bt878_pci_driver = {
+      .name    = "bt878",
+      .id_table = bt878_pci_tbl,
+      .probe   = bt878_probe,
+      .remove  = __devexit_p(bt878_remove),
+};
+
+/*******************************/
+/* Module management functions */
+/*******************************/
+
+static int __init bt878_init_module(void)
+{
+       bt878_num = 0;
+
+       printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
+              (BT878_VERSION_CODE >> 16) & 0xff,
+              (BT878_VERSION_CODE >> 8) & 0xff,
+              BT878_VERSION_CODE & 0xff);
+
+       return pci_register_driver(&bt878_pci_driver);
+}
+
+static void __exit bt878_cleanup_module(void)
+{
+       pci_unregister_driver(&bt878_pci_driver);
+}
+
+module_init(bt878_init_module);
+module_exit(bt878_cleanup_module);
+
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/pci/bt8xx/bt878.h b/drivers/media/pci/bt8xx/bt878.h
new file mode 100644 (file)
index 0000000..d19b592
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+    bt878.h - Bt878 audio module (register offsets)
+
+    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
+
+    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 _BT878_H_
+#define _BT878_H_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
+#include "bt848.h"
+#include "bttv.h"
+
+#define BT878_VERSION_CODE 0x000000
+
+#define BT878_AINT_STAT                0x100
+#define BT878_ARISCS           (0xf<<28)
+#define BT878_ARISC_EN         (1<<27)
+#define BT878_ASCERR           (1<<19)
+#define BT878_AOCERR           (1<<18)
+#define BT878_APABORT          (1<<17)
+#define BT878_ARIPERR          (1<<16)
+#define BT878_APPERR           (1<<15)
+#define BT878_AFDSR            (1<<14)
+#define BT878_AFTRGT           (1<<13)
+#define BT878_AFBUS            (1<<12)
+#define BT878_ARISCI           (1<<11)
+#define BT878_AOFLOW           (1<<3)
+
+#define BT878_AINT_MASK                0x104
+
+#define BT878_AGPIO_DMA_CTL    0x10c
+#define BT878_A_GAIN           (0xf<<28)
+#define BT878_A_G2X            (1<<27)
+#define BT878_A_PWRDN          (1<<26)
+#define BT878_A_SEL            (3<<24)
+#define BT878_DA_SCE           (1<<23)
+#define BT878_DA_LRI           (1<<22)
+#define BT878_DA_MLB           (1<<21)
+#define BT878_DA_LRD           (0x1f<<16)
+#define BT878_DA_DPM           (1<<15)
+#define BT878_DA_SBR           (1<<14)
+#define BT878_DA_ES2           (1<<13)
+#define BT878_DA_LMT           (1<<12)
+#define BT878_DA_SDR           (0xf<<8)
+#define BT878_DA_IOM           (3<<6)
+#define BT878_DA_APP           (1<<5)
+#define BT878_ACAP_EN          (1<<4)
+#define BT878_PKTP             (3<<2)
+#define BT878_RISC_EN          (1<<1)
+#define BT878_FIFO_EN          1
+
+#define BT878_APACK_LEN                0x110
+#define BT878_AFP_LEN          (0xff<<16)
+#define BT878_ALP_LEN          0xfff
+
+#define BT878_ARISC_START      0x114
+
+#define BT878_ARISC_PC         0x120
+
+/* BT878 FUNCTION 0 REGISTERS */
+#define BT878_GPIO_DMA_CTL     0x10c
+
+/* Interrupt register */
+#define BT878_INT_STAT         0x100
+#define BT878_INT_MASK         0x104
+#define BT878_I2CRACK          (1<<25)
+#define BT878_I2CDONE          (1<<8)
+
+#define BT878_MAX 4
+
+#define BT878_RISC_SYNC_MASK   (1 << 15)
+
+
+#define BTTV_BOARD_UNKNOWN                 0x00
+#define BTTV_BOARD_PINNACLESAT             0x5e
+#define BTTV_BOARD_NEBULA_DIGITV           0x68
+#define BTTV_BOARD_PC_HDTV                 0x70
+#define BTTV_BOARD_TWINHAN_DST             0x71
+#define BTTV_BOARD_AVDVBT_771              0x7b
+#define BTTV_BOARD_AVDVBT_761              0x7c
+#define BTTV_BOARD_DVICO_DVBT_LITE         0x80
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+
+extern int bt878_num;
+
+struct bt878 {
+       struct mutex gpio_lock;
+       unsigned int nr;
+       unsigned int bttv_nr;
+       struct i2c_adapter *adapter;
+       struct pci_dev *dev;
+       unsigned int id;
+       unsigned int TS_Size;
+       unsigned char revision;
+       unsigned int irq;
+       unsigned long bt878_adr;
+       volatile void __iomem *bt878_mem; /* function 1 */
+
+       volatile u32 finished_block;
+       volatile u32 last_block;
+       u32 block_count;
+       u32 block_bytes;
+       u32 line_bytes;
+       u32 line_count;
+
+       u32 buf_size;
+       u8 *buf_cpu;
+       dma_addr_t buf_dma;
+
+       u32 risc_size;
+       __le32 *risc_cpu;
+       dma_addr_t risc_dma;
+       u32 risc_pos;
+
+       struct tasklet_struct tasklet;
+       int shutdown;
+};
+
+extern struct bt878 bt878[BT878_MAX];
+
+void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
+               u32 irq_err_ignore);
+void bt878_stop(struct bt878 *bt);
+
+#if defined(__powerpc__)       /* big-endian */
+static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
+{
+       st_le32(addr, val);
+       eieio();
+}
+
+#define bmtwrite(dat,adr)  io_st_le32((adr),(dat))
+#define bmtread(adr)       ld_le32((adr))
+#else
+#define bmtwrite(dat,adr)  writel((dat), (adr))
+#define bmtread(adr)       readl(adr)
+#endif
+
+#endif
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
new file mode 100644 (file)
index 0000000..430b3eb
--- /dev/null
@@ -0,0 +1,1873 @@
+/*
+       Frontend/Card driver for TwinHan DST Frontend
+       Copyright (C) 2003 Jamie Honan
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <asm/div64.h>
+#include "dvb_frontend.h"
+#include "dst_priv.h"
+#include "dst_common.h"
+
+static unsigned int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+
+static unsigned int dst_addons;
+module_param(dst_addons, int, 0644);
+MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
+
+static unsigned int dst_algo;
+module_param(dst_algo, int, 0644);
+MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
+
+#define HAS_LOCK               1
+#define ATTEMPT_TUNE           2
+#define HAS_POWER              4
+
+#define DST_ERROR              0
+#define DST_NOTICE             1
+#define DST_INFO               2
+#define DST_DEBUG              3
+
+#define dprintk(x, y, z, format, arg...) do {                          \
+       if (z) {                                                        \
+               if      ((x > DST_ERROR) && (x > y))                    \
+                       printk(KERN_ERR "dst(%d) %s: " format "\n",     \
+                               state->bt->nr, __func__ , ##arg);       \
+               else if ((x > DST_NOTICE) && (x > y))                   \
+                       printk(KERN_NOTICE "dst(%d) %s: " format "\n",  \
+                               state->bt->nr, __func__ , ##arg);       \
+               else if ((x > DST_INFO) && (x > y))                     \
+                       printk(KERN_INFO "dst(%d) %s: " format "\n",    \
+                               state->bt->nr, __func__ , ##arg);       \
+               else if ((x > DST_DEBUG) && (x > y))                    \
+                       printk(KERN_DEBUG "dst(%d) %s: " format "\n",   \
+                               state->bt->nr,  __func__ , ##arg);      \
+       } else {                                                        \
+               if (x > y)                                              \
+                       printk(format, ##arg);                          \
+       }                                                               \
+} while(0)
+
+static int dst_command(struct dst_state *state, u8 *data, u8 len);
+
+static void dst_packsize(struct dst_state *state, int psize)
+{
+       union dst_gpio_packet bits;
+
+       bits.psize = psize;
+       bt878_device_control(state->bt, DST_IG_TS, &bits);
+}
+
+static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb,
+                        u32 outhigh, int delay)
+{
+       union dst_gpio_packet enb;
+       union dst_gpio_packet bits;
+       int err;
+
+       enb.enb.mask = mask;
+       enb.enb.enable = enbb;
+
+       dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
+       if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
+               dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
+               return -EREMOTEIO;
+       }
+       udelay(1000);
+       /* because complete disabling means no output, no need to do output packet */
+       if (enbb == 0)
+               return 0;
+       if (delay)
+               msleep(10);
+       bits.outp.mask = enbb;
+       bits.outp.highvals = outhigh;
+       if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
+               dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int dst_gpio_inb(struct dst_state *state, u8 *result)
+{
+       union dst_gpio_packet rd_packet;
+       int err;
+
+       *result = 0;
+       if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err);
+               return -EREMOTEIO;
+       }
+       *result = (u8) rd_packet.rd.value;
+
+       return 0;
+}
+
+int rdc_reset_state(struct dst_state *state)
+{
+       dprintk(verbose, DST_INFO, 1, "Resetting state machine");
+       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               return -1;
+       }
+       msleep(10);
+       if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               msleep(10);
+               return -1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(rdc_reset_state);
+
+static int rdc_8820_reset(struct dst_state *state)
+{
+       dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
+       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               return -1;
+       }
+       udelay(1000);
+       if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int dst_pio_enable(struct dst_state *state)
+{
+       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               return -1;
+       }
+       udelay(1000);
+
+       return 0;
+}
+
+int dst_pio_disable(struct dst_state *state)
+{
+       if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
+               return -1;
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               udelay(1000);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_pio_disable);
+
+int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
+{
+       u8 reply;
+       int i;
+
+       for (i = 0; i < 200; i++) {
+               if (dst_gpio_inb(state, &reply) < 0) {
+                       dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
+                       return -1;
+               }
+               if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
+                       dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
+                       return 1;
+               }
+               msleep(10);
+       }
+       dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_wait_dst_ready);
+
+int dst_error_recovery(struct dst_state *state)
+{
+       dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
+       dst_pio_disable(state);
+       msleep(10);
+       dst_pio_enable(state);
+       msleep(10);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_error_recovery);
+
+int dst_error_bailout(struct dst_state *state)
+{
+       dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
+       rdc_8820_reset(state);
+       dst_pio_disable(state);
+       msleep(10);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_error_bailout);
+
+int dst_comm_init(struct dst_state *state)
+{
+       dprintk(verbose, DST_INFO, 1, "Initializing DST.");
+       if ((dst_pio_enable(state)) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
+               return -1;
+       }
+       if ((rdc_reset_state(state)) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
+               return -1;
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               msleep(100);
+       else
+               msleep(5);
+
+       return 0;
+}
+EXPORT_SYMBOL(dst_comm_init);
+
+int write_dst(struct dst_state *state, u8 *data, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address,
+               .flags = 0,
+               .buf = data,
+               .len = len
+       };
+
+       int err;
+       u8 cnt, i;
+
+       dprintk(verbose, DST_NOTICE, 0, "writing [ ");
+       for (i = 0; i < len; i++)
+               dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
+       dprintk(verbose, DST_NOTICE, 0, "]\n");
+
+       for (cnt = 0; cnt < 2; cnt++) {
+               if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
+                       dst_error_recovery(state);
+                       continue;
+               } else
+                       break;
+       }
+       if (cnt >= 2) {
+               dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
+               dst_error_bailout(state);
+
+               return -1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(write_dst);
+
+int read_dst(struct dst_state *state, u8 *ret, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address,
+               .flags = I2C_M_RD,
+               .buf = ret,
+               .len = len
+       };
+
+       int err;
+       int cnt;
+
+       for (cnt = 0; cnt < 2; cnt++) {
+               if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
+                       dst_error_recovery(state);
+                       continue;
+               } else
+                       break;
+       }
+       if (cnt >= 2) {
+               dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
+               dst_error_bailout(state);
+
+               return -1;
+       }
+       dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
+       for (err = 1; err < len; err++)
+               dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
+       if (err > 1)
+               dprintk(verbose, DST_DEBUG, 0, "\n");
+
+       return 0;
+}
+EXPORT_SYMBOL(read_dst);
+
+static int dst_set_polarization(struct dst_state *state)
+{
+       switch (state->voltage) {
+       case SEC_VOLTAGE_13:    /*      Vertical        */
+               dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
+               state->tx_tuna[8] &= ~0x40;
+               break;
+       case SEC_VOLTAGE_18:    /*      Horizontal      */
+               dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
+               state->tx_tuna[8] |= 0x40;
+               break;
+       case SEC_VOLTAGE_OFF:
+               break;
+       }
+
+       return 0;
+}
+
+static int dst_set_freq(struct dst_state *state, u32 freq)
+{
+       state->frequency = freq;
+       dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
+
+       if (state->dst_type == DST_TYPE_IS_SAT) {
+               freq = freq / 1000;
+               if (freq < 950 || freq > 2150)
+                       return -EINVAL;
+               state->tx_tuna[2] = (freq >> 8);
+               state->tx_tuna[3] = (u8) freq;
+               state->tx_tuna[4] = 0x01;
+               state->tx_tuna[8] &= ~0x04;
+               if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+                       if (freq < 1531)
+                               state->tx_tuna[8] |= 0x04;
+               }
+       } else if (state->dst_type == DST_TYPE_IS_TERR) {
+               freq = freq / 1000;
+               if (freq < 137000 || freq > 858000)
+                       return -EINVAL;
+               state->tx_tuna[2] = (freq >> 16) & 0xff;
+               state->tx_tuna[3] = (freq >> 8) & 0xff;
+               state->tx_tuna[4] = (u8) freq;
+       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
+               freq = freq / 1000;
+               state->tx_tuna[2] = (freq >> 16) & 0xff;
+               state->tx_tuna[3] = (freq >> 8) & 0xff;
+               state->tx_tuna[4] = (u8) freq;
+       } else if (state->dst_type == DST_TYPE_IS_ATSC) {
+               freq = freq / 1000;
+               if (freq < 51000 || freq > 858000)
+                       return -EINVAL;
+               state->tx_tuna[2] = (freq >> 16) & 0xff;
+               state->tx_tuna[3] = (freq >>  8) & 0xff;
+               state->tx_tuna[4] = (u8) freq;
+               state->tx_tuna[5] = 0x00;               /*      ATSC    */
+               state->tx_tuna[6] = 0x00;
+               if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
+                       state->tx_tuna[7] = 0x00;       /*      Digital */
+       } else
+               return -EINVAL;
+
+       return 0;
+}
+
+static int dst_set_bandwidth(struct dst_state *state, u32 bandwidth)
+{
+       state->bandwidth = bandwidth;
+
+       if (state->dst_type != DST_TYPE_IS_TERR)
+               return -EOPNOTSUPP;
+
+       switch (bandwidth) {
+       case 6000000:
+               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+                       state->tx_tuna[7] = 0x06;
+               else {
+                       state->tx_tuna[6] = 0x06;
+                       state->tx_tuna[7] = 0x00;
+               }
+               break;
+       case 7000000:
+               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+                       state->tx_tuna[7] = 0x07;
+               else {
+                       state->tx_tuna[6] = 0x07;
+                       state->tx_tuna[7] = 0x00;
+               }
+               break;
+       case 8000000:
+               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+                       state->tx_tuna[7] = 0x08;
+               else {
+                       state->tx_tuna[6] = 0x08;
+                       state->tx_tuna[7] = 0x00;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
+{
+       state->inversion = inversion;
+       switch (inversion) {
+       case INVERSION_OFF:     /*      Inversion = Normal      */
+               state->tx_tuna[8] &= ~0x80;
+               break;
+       case INVERSION_ON:
+               state->tx_tuna[8] |= 0x80;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
+{
+       state->fec = fec;
+       return 0;
+}
+
+static fe_code_rate_t dst_get_fec(struct dst_state *state)
+{
+       return state->fec;
+}
+
+static int dst_set_symbolrate(struct dst_state *state, u32 srate)
+{
+       u32 symcalc;
+       u64 sval;
+
+       state->symbol_rate = srate;
+       if (state->dst_type == DST_TYPE_IS_TERR) {
+               return -EOPNOTSUPP;
+       }
+       dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
+       srate /= 1000;
+       if (state->dst_type == DST_TYPE_IS_SAT) {
+               if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
+                       sval = srate;
+                       sval <<= 20;
+                       do_div(sval, 88000);
+                       symcalc = (u32) sval;
+                       dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
+                       state->tx_tuna[5] = (u8) (symcalc >> 12);
+                       state->tx_tuna[6] = (u8) (symcalc >> 4);
+                       state->tx_tuna[7] = (u8) (symcalc << 4);
+               } else {
+                       state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
+                       state->tx_tuna[6] = (u8) (srate >> 8);
+                       state->tx_tuna[7] = (u8) srate;
+               }
+               state->tx_tuna[8] &= ~0x20;
+               if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+                       if (srate > 8000)
+                               state->tx_tuna[8] |= 0x20;
+               }
+       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
+               dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name);
+               if (!strncmp(state->fw_name, "DCTNEW", 6)) {
+                       state->tx_tuna[5] = (u8) (srate >> 8);
+                       state->tx_tuna[6] = (u8) srate;
+                       state->tx_tuna[7] = 0x00;
+               } else if (!strncmp(state->fw_name, "DCT-CI", 6)) {
+                       state->tx_tuna[5] = 0x00;
+                       state->tx_tuna[6] = (u8) (srate >> 8);
+                       state->tx_tuna[7] = (u8) srate;
+               }
+       }
+       return 0;
+}
+
+static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
+{
+       if (state->dst_type != DST_TYPE_IS_CABLE)
+               return -EOPNOTSUPP;
+
+       state->modulation = modulation;
+       switch (modulation) {
+       case QAM_16:
+               state->tx_tuna[8] = 0x10;
+               break;
+       case QAM_32:
+               state->tx_tuna[8] = 0x20;
+               break;
+       case QAM_64:
+               state->tx_tuna[8] = 0x40;
+               break;
+       case QAM_128:
+               state->tx_tuna[8] = 0x80;
+               break;
+       case QAM_256:
+               if (!strncmp(state->fw_name, "DCTNEW", 6))
+                       state->tx_tuna[8] = 0xff;
+               else if (!strncmp(state->fw_name, "DCT-CI", 6))
+                       state->tx_tuna[8] = 0x00;
+               break;
+       case QPSK:
+       case QAM_AUTO:
+       case VSB_8:
+       case VSB_16:
+       default:
+               return -EINVAL;
+
+       }
+
+       return 0;
+}
+
+static fe_modulation_t dst_get_modulation(struct dst_state *state)
+{
+       return state->modulation;
+}
+
+
+u8 dst_check_sum(u8 *buf, u32 len)
+{
+       u32 i;
+       u8 val = 0;
+       if (!len)
+               return 0;
+       for (i = 0; i < len; i++) {
+               val += buf[i];
+       }
+       return ((~val) + 1);
+}
+EXPORT_SYMBOL(dst_check_sum);
+
+static void dst_type_flags_print(struct dst_state *state)
+{
+       u32 type_flags = state->type_flags;
+
+       dprintk(verbose, DST_ERROR, 0, "DST type flags :");
+       if (type_flags & DST_TYPE_HAS_TS188)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188);
+       if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
+       if (type_flags & DST_TYPE_HAS_TS204)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
+       if (type_flags & DST_TYPE_HAS_VLF)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF);
+       if (type_flags & DST_TYPE_HAS_SYMDIV)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
+       if (type_flags & DST_TYPE_HAS_FW_1)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
+       if (type_flags & DST_TYPE_HAS_FW_2)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
+       if (type_flags & DST_TYPE_HAS_FW_3)
+               dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
+       dprintk(verbose, DST_ERROR, 0, "\n");
+}
+
+
+static int dst_type_print(struct dst_state *state, u8 type)
+{
+       char *otype;
+       switch (type) {
+       case DST_TYPE_IS_SAT:
+               otype = "satellite";
+               break;
+
+       case DST_TYPE_IS_TERR:
+               otype = "terrestrial";
+               break;
+
+       case DST_TYPE_IS_CABLE:
+               otype = "cable";
+               break;
+
+       case DST_TYPE_IS_ATSC:
+               otype = "atsc";
+               break;
+
+       default:
+               dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
+               return -EINVAL;
+       }
+       dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
+
+       return 0;
+}
+
+static struct tuner_types tuner_list[] = {
+       {
+               .tuner_type = TUNER_TYPE_L64724,
+               .tuner_name = "L 64724",
+               .board_name = "UNKNOWN",
+               .fw_name    = "UNKNOWN"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_STV0299,
+               .tuner_name = "STV 0299",
+               .board_name = "VP1020",
+               .fw_name    = "DST-MOT"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_STV0299,
+               .tuner_name = "STV 0299",
+               .board_name = "VP1020",
+               .fw_name    = "DST-03T"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_MB86A15,
+               .tuner_name = "MB 86A15",
+               .board_name = "VP1022",
+               .fw_name    = "DST-03T"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_MB86A15,
+               .tuner_name = "MB 86A15",
+               .board_name = "VP1025",
+               .fw_name    = "DST-03T"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_STV0299,
+               .tuner_name = "STV 0299",
+               .board_name = "VP1030",
+               .fw_name    = "DST-CI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_STV0299,
+               .tuner_name = "STV 0299",
+               .board_name = "VP1030",
+               .fw_name    = "DSTMCI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP2021",
+               .fw_name    = "DCTNEW"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP2030",
+               .fw_name    = "DCT-CI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP2031",
+               .fw_name    = "DCT-CI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP2040",
+               .fw_name    = "DCT-CI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP3020",
+               .fw_name    = "DTTFTA"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP3021",
+               .fw_name    = "DTTFTA"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_TDA10046,
+               .tuner_name = "TDA10046",
+               .board_name = "VP3040",
+               .fw_name    = "DTT-CI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_UNKNOWN,
+               .tuner_name = "UNKNOWN",
+               .board_name = "VP3051",
+               .fw_name    = "DTTNXT"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_NXT200x,
+               .tuner_name = "NXT200x",
+               .board_name = "VP3220",
+               .fw_name    = "ATSCDI"
+       },
+
+       {
+               .tuner_type = TUNER_TYPE_NXT200x,
+               .tuner_name = "NXT200x",
+               .board_name = "VP3250",
+               .fw_name    = "ATSCAD"
+       },
+};
+
+/*
+       Known cards list
+       Satellite
+       -------------------
+                 200103A
+       VP-1020   DST-MOT       LG(old), TS=188
+
+       VP-1020   DST-03T       LG(new), TS=204
+       VP-1022   DST-03T       LG(new), TS=204
+       VP-1025   DST-03T       LG(new), TS=204
+
+       VP-1030   DSTMCI,       LG(new), TS=188
+       VP-1032   DSTMCI,       LG(new), TS=188
+
+       Cable
+       -------------------
+       VP-2030   DCT-CI,       Samsung, TS=204
+       VP-2021   DCT-CI,       Unknown, TS=204
+       VP-2031   DCT-CI,       Philips, TS=188
+       VP-2040   DCT-CI,       Philips, TS=188, with CA daughter board
+       VP-2040   DCT-CI,       Philips, TS=204, without CA daughter board
+
+       Terrestrial
+       -------------------
+       VP-3050  DTTNXT                  TS=188
+       VP-3040  DTT-CI,        Philips, TS=188
+       VP-3040  DTT-CI,        Philips, TS=204
+
+       ATSC
+       -------------------
+       VP-3220  ATSCDI,                 TS=188
+       VP-3250  ATSCAD,                 TS=188
+
+*/
+
+static struct dst_types dst_tlist[] = {
+       {
+               .device_id = "200103A",
+               .offset = 0,
+               .dst_type =  DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-020",
+               .offset = 0,
+               .dst_type =  DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-030",
+               .offset =  0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-03T",
+               .offset = 0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
+               .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
+                                                        | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
+               .tuner_type = TUNER_TYPE_MULTI
+        },
+
+       {
+               .device_id = "DST-MOT",
+               .offset =  0,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },      /*      obsolete        */
+
+       {
+               .device_id = "DST-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
+               .dst_feature = DST_TYPE_HAS_CA,
+               .tuner_type = 0
+       },      /*      An OEM board    */
+
+       {
+               .device_id = "DSTMCI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF,
+               .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
+                                                       | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
+               .tuner_type = TUNER_TYPE_MULTI
+       },
+
+       {
+               .device_id = "DSTFCI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_SAT,
+               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },      /* unknown to vendor    */
+
+       {
+               .device_id = "DCT-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_CABLE,
+               .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF,
+               .dst_feature = DST_TYPE_HAS_CA,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "DCTNEW",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_CABLE,
+               .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "DTT-CI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF,
+               .dst_feature = DST_TYPE_HAS_CA,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "DTTDIG",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "DTTNXT",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_TERR,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = DST_TYPE_HAS_ANALOG,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "ATSCDI",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_ATSC,
+               .type_flags = DST_TYPE_HAS_FW_2,
+               .dst_feature = 0,
+               .tuner_type = 0
+       },
+
+       {
+               .device_id = "ATSCAD",
+               .offset = 1,
+               .dst_type = DST_TYPE_IS_ATSC,
+               .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+               .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
+               .tuner_type = 0
+       },
+
+       { }
+
+};
+
+static int dst_get_mac(struct dst_state *state)
+{
+       u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       get_mac[7] = dst_check_sum(get_mac, 7);
+       if (dst_command(state, get_mac, 8) < 0) {
+               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+               return -1;
+       }
+       memset(&state->mac_address, '\0', 8);
+       memcpy(&state->mac_address, &state->rxbuffer, 6);
+       dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address);
+
+       return 0;
+}
+
+static int dst_fw_ver(struct dst_state *state)
+{
+       u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       get_ver[7] = dst_check_sum(get_ver, 7);
+       if (dst_command(state, get_ver, 8) < 0) {
+               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+               return -1;
+       }
+       memcpy(&state->fw_version, &state->rxbuffer, 8);
+       dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
+               state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
+               state->fw_version[1],
+               state->fw_version[5], state->fw_version[6],
+               state->fw_version[4], state->fw_version[3], state->fw_version[2]);
+
+       return 0;
+}
+
+static int dst_card_type(struct dst_state *state)
+{
+       int j;
+       struct tuner_types *p_tuner_list = NULL;
+
+       u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       get_type[7] = dst_check_sum(get_type, 7);
+       if (dst_command(state, get_type, 8) < 0) {
+               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+               return -1;
+       }
+       memset(&state->card_info, '\0', 8);
+       memcpy(&state->card_info, &state->rxbuffer, 7);
+       dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
+
+       for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
+               if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
+                       state->tuner_type = p_tuner_list->tuner_type;
+                       dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]",
+                               p_tuner_list->tuner_name, p_tuner_list->tuner_type);
+               }
+       }
+
+       return 0;
+}
+
+static int dst_get_vendor(struct dst_state *state)
+{
+       u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       get_vendor[7] = dst_check_sum(get_vendor, 7);
+       if (dst_command(state, get_vendor, 8) < 0) {
+               dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+               return -1;
+       }
+       memset(&state->vendor, '\0', 8);
+       memcpy(&state->vendor, &state->rxbuffer, 7);
+       dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
+
+       return 0;
+}
+
+static void debug_dst_buffer(struct dst_state *state)
+{
+       int i;
+
+       if (verbose > 2) {
+               printk("%s: [", __func__);
+               for (i = 0; i < 8; i++)
+                       printk(" %02x", state->rxbuffer[i]);
+               printk("]\n");
+       }
+}
+
+static int dst_check_stv0299(struct dst_state *state)
+{
+       u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+       check_stv0299[7] = dst_check_sum(check_stv0299, 7);
+       if (dst_command(state, check_stv0299, 8) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed");
+               return -1;
+       }
+       debug_dst_buffer(state);
+
+       if (memcmp(&check_stv0299, &state->rxbuffer, 8)) {
+               dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM");
+               state->tuner_type = TUNER_TYPE_STV0299;
+               return 0;
+       }
+
+       return -1;
+}
+
+static int dst_check_mb86a15(struct dst_state *state)
+{
+       u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+       check_mb86a15[7] = dst_check_sum(check_mb86a15, 7);
+       if (dst_command(state, check_mb86a15, 8) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed");
+               return -1;
+       }
+       debug_dst_buffer(state);
+
+       if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM");
+               state->tuner_type = TUNER_TYPE_MB86A15;
+               return 0;
+       }
+
+       return -1;
+}
+
+static int dst_get_tuner_info(struct dst_state *state)
+{
+       u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+       get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
+       get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
+       dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
+       if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
+               if (dst_command(state, get_tuner_1, 8) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
+                       goto force;
+               }
+       } else {
+               if (dst_command(state, get_tuner_2, 8) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
+                       goto force;
+               }
+       }
+       memcpy(&state->board_info, &state->rxbuffer, 8);
+       if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
+               dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
+       }
+       if (state->board_info[0] == 0xbc) {
+               if (state->dst_type != DST_TYPE_IS_ATSC)
+                       state->type_flags |= DST_TYPE_HAS_TS188;
+               else
+                       state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
+
+               if (state->board_info[1] == 0x01) {
+                       state->dst_hw_cap |= DST_TYPE_HAS_DBOARD;
+                       dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard");
+               }
+       }
+
+       return 0;
+force:
+       if (!strncmp(state->fw_name, "DCT-CI", 6)) {
+               state->type_flags |= DST_TYPE_HAS_TS204;
+               dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name);
+       }
+
+       return -1;
+}
+
+static int dst_get_device_id(struct dst_state *state)
+{
+       u8 reply;
+
+       int i, j;
+       struct dst_types *p_dst_type = NULL;
+       struct tuner_types *p_tuner_list = NULL;
+
+       u8 use_dst_type = 0;
+       u32 use_type_flags = 0;
+
+       static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
+
+       state->tuner_type = 0;
+       device_type[7] = dst_check_sum(device_type, 7);
+
+       if (write_dst(state, device_type, FIXED_COMM))
+               return -1;              /*      Write failed            */
+       if ((dst_pio_disable(state)) < 0)
+               return -1;
+       if (read_dst(state, &reply, GET_ACK))
+               return -1;              /*      Read failure            */
+       if (reply != ACK) {
+               dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
+               return -1;              /*      Unack'd write           */
+       }
+       if (!dst_wait_dst_ready(state, DEVICE_INIT))
+               return -1;              /*      DST not ready yet       */
+       if (read_dst(state, state->rxbuffer, FIXED_COMM))
+               return -1;
+
+       dst_pio_disable(state);
+       if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
+               dprintk(verbose, DST_INFO, 1, "Checksum failure!");
+               return -1;              /*      Checksum failure        */
+       }
+       state->rxbuffer[7] = '\0';
+
+       for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
+               if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
+                       use_type_flags = p_dst_type->type_flags;
+                       use_dst_type = p_dst_type->dst_type;
+
+                       /*      Card capabilities       */
+                       state->dst_hw_cap = p_dst_type->dst_feature;
+                       dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id);
+                       strncpy(&state->fw_name[0], p_dst_type->device_id, 6);
+                       /*      Multiple tuners         */
+                       if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) {
+                               switch (use_dst_type) {
+                               case DST_TYPE_IS_SAT:
+                                       /*      STV0299 check   */
+                                       if (dst_check_stv0299(state) < 0) {
+                                               dprintk(verbose, DST_ERROR, 1, "Unsupported");
+                                               state->tuner_type = TUNER_TYPE_MB86A15;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                               }
+                               if (dst_check_mb86a15(state) < 0)
+                                       dprintk(verbose, DST_ERROR, 1, "Unsupported");
+                       /*      Single tuner            */
+                       } else {
+                               state->tuner_type = p_dst_type->tuner_type;
+                       }
+                       for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
+                               if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) &&
+                                       p_tuner_list->tuner_type == state->tuner_type) {
+                                       dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]",
+                                               p_dst_type->device_id, p_tuner_list->tuner_name);
+                               }
+                       }
+                       break;
+               }
+       }
+
+       if (i >= ARRAY_SIZE(dst_tlist)) {
+               dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
+               dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
+               use_dst_type = DST_TYPE_IS_SAT;
+               use_type_flags = DST_TYPE_HAS_SYMDIV;
+       }
+       dst_type_print(state, use_dst_type);
+       state->type_flags = use_type_flags;
+       state->dst_type = use_dst_type;
+       dst_type_flags_print(state);
+
+       return 0;
+}
+
+static int dst_probe(struct dst_state *state)
+{
+       mutex_init(&state->dst_mutex);
+       if (dst_addons & DST_TYPE_HAS_CA) {
+               if ((rdc_8820_reset(state)) < 0) {
+                       dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
+                       return -1;
+               }
+               msleep(4000);
+       } else {
+               msleep(100);
+       }
+       if ((dst_comm_init(state)) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
+               return -1;
+       }
+       msleep(100);
+       if (dst_get_device_id(state) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "unknown device.");
+               return -1;
+       }
+       if (dst_get_mac(state) < 0) {
+               dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
+       }
+       if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
+               if (dst_get_tuner_info(state) < 0)
+                       dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
+       }
+       if (state->type_flags & DST_TYPE_HAS_TS204) {
+               dst_packsize(state, 204);
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
+               if (dst_fw_ver(state) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
+                       return 0;
+               }
+               if (dst_card_type(state) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
+                       return 0;
+               }
+               if (dst_get_vendor(state) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static int dst_command(struct dst_state *state, u8 *data, u8 len)
+{
+       u8 reply;
+
+       mutex_lock(&state->dst_mutex);
+       if ((dst_comm_init(state)) < 0) {
+               dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
+               goto error;
+       }
+       if (write_dst(state, data, len)) {
+               dprintk(verbose, DST_INFO, 1, "Trying to recover.. ");
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
+                       goto error;
+               }
+               goto error;
+       }
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
+               goto error;
+       }
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               mdelay(3);
+       if (read_dst(state, &reply, GET_ACK)) {
+               dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
+                       goto error;
+               }
+               goto error;
+       }
+       if (reply != ACK) {
+               dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
+               goto error;
+       }
+       if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
+               goto error;
+       if (state->type_flags & DST_TYPE_HAS_FW_1)
+               mdelay(3);
+       else
+               udelay(2000);
+       if (!dst_wait_dst_ready(state, NO_DELAY))
+               goto error;
+       if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
+               dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
+               if ((dst_error_recovery(state)) < 0) {
+                       dprintk(verbose, DST_INFO, 1, "Recovery failed.");
+                       goto error;
+               }
+               goto error;
+       }
+       if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
+               dprintk(verbose, DST_INFO, 1, "checksum failure");
+               goto error;
+       }
+       mutex_unlock(&state->dst_mutex);
+       return 0;
+
+error:
+       mutex_unlock(&state->dst_mutex);
+       return -EIO;
+
+}
+
+static int dst_get_signal(struct dst_state *state)
+{
+       int retval;
+       u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
+       //dprintk("%s: Getting Signal strength and other parameters\n", __func__);
+       if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
+               state->decode_lock = state->decode_strength = state->decode_snr = 0;
+               return 0;
+       }
+       if (0 == (state->diseq_flags & HAS_LOCK)) {
+               state->decode_lock = state->decode_strength = state->decode_snr = 0;
+               return 0;
+       }
+       if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
+               retval = dst_command(state, get_signal, 8);
+               if (retval < 0)
+                       return retval;
+               if (state->dst_type == DST_TYPE_IS_SAT) {
+                       state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
+                       state->decode_strength = state->rxbuffer[5] << 8;
+                       state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
+               } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
+                       state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
+                       state->decode_strength = state->rxbuffer[4] << 8;
+                       state->decode_snr = state->rxbuffer[3] << 8;
+               } else if (state->dst_type == DST_TYPE_IS_ATSC) {
+                       state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
+                       state->decode_strength = state->rxbuffer[4] << 8;
+                       state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
+               }
+               state->cur_jiff = jiffies;
+       }
+       return 0;
+}
+
+static int dst_tone_power_cmd(struct dst_state *state)
+{
+       u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
+
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return -EOPNOTSUPP;
+       paket[4] = state->tx_tuna[4];
+       paket[2] = state->tx_tuna[2];
+       paket[3] = state->tx_tuna[3];
+       paket[7] = dst_check_sum (paket, 7);
+       return dst_command(state, paket, 8);
+}
+
+static int dst_get_tuna(struct dst_state *state)
+{
+       int retval;
+
+       if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
+               return 0;
+       state->diseq_flags &= ~(HAS_LOCK);
+       if (!dst_wait_dst_ready(state, NO_DELAY))
+               return -EIO;
+       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
+               !(state->dst_type == DST_TYPE_IS_ATSC))
+
+               retval = read_dst(state, state->rx_tuna, 10);
+       else
+               retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
+       if (retval < 0) {
+               dprintk(verbose, DST_DEBUG, 1, "read not successful");
+               return retval;
+       }
+       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
+          !(state->dst_type == DST_TYPE_IS_ATSC)) {
+
+               if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
+                       dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
+                       return -EIO;
+               }
+       } else {
+               if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
+                       dprintk(verbose, DST_INFO, 1, "checksum failure? ");
+                       return -EIO;
+               }
+       }
+       if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
+               return 0;
+       if (state->dst_type == DST_TYPE_IS_SAT) {
+               state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
+       } else {
+               state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
+       }
+       state->decode_freq = state->decode_freq * 1000;
+       state->decode_lock = 1;
+       state->diseq_flags |= HAS_LOCK;
+
+       return 1;
+}
+
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
+
+static int dst_write_tuna(struct dvb_frontend *fe)
+{
+       struct dst_state *state = fe->demodulator_priv;
+       int retval;
+       u8 reply;
+
+       dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
+       state->decode_freq = 0;
+       state->decode_lock = state->decode_strength = state->decode_snr = 0;
+       if (state->dst_type == DST_TYPE_IS_SAT) {
+               if (!(state->diseq_flags & HAS_POWER))
+                       dst_set_voltage(fe, SEC_VOLTAGE_13);
+       }
+       state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
+       mutex_lock(&state->dst_mutex);
+       if ((dst_comm_init(state)) < 0) {
+               dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
+               goto error;
+       }
+//     if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
+       if ((state->type_flags & DST_TYPE_HAS_VLF) &&
+               (!(state->dst_type == DST_TYPE_IS_ATSC))) {
+
+               state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
+               retval = write_dst(state, &state->tx_tuna[0], 10);
+       } else {
+               state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
+               retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
+       }
+       if (retval < 0) {
+               dst_pio_disable(state);
+               dprintk(verbose, DST_DEBUG, 1, "write not successful");
+               goto werr;
+       }
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
+               goto error;
+       }
+       if ((read_dst(state, &reply, GET_ACK) < 0)) {
+               dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
+               goto error;
+       }
+       if (reply != ACK) {
+               dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
+               goto error;
+       }
+       state->diseq_flags |= ATTEMPT_TUNE;
+       retval = dst_get_tuna(state);
+werr:
+       mutex_unlock(&state->dst_mutex);
+       return retval;
+
+error:
+       mutex_unlock(&state->dst_mutex);
+       return -EIO;
+}
+
+/*
+ * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
+ * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
+ * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
+ * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
+ * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
+ * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+ * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
+ * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
+ * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
+ * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
+ * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
+ */
+
+static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+       struct dst_state *state = fe->demodulator_priv;
+       u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
+
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return -EOPNOTSUPP;
+       if (cmd->msg_len > 0 && cmd->msg_len < 5)
+               memcpy(&paket[3], cmd->msg, cmd->msg_len);
+       else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5)
+               memcpy(&paket[2], cmd->msg, cmd->msg_len);
+       else
+               return -EINVAL;
+       paket[7] = dst_check_sum(&paket[0], 7);
+       return dst_command(state, paket, 8);
+}
+
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       int need_cmd, retval = 0;
+       struct dst_state *state = fe->demodulator_priv;
+
+       state->voltage = voltage;
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return -EOPNOTSUPP;
+
+       need_cmd = 0;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+       case SEC_VOLTAGE_18:
+               if ((state->diseq_flags & HAS_POWER) == 0)
+                       need_cmd = 1;
+               state->diseq_flags |= HAS_POWER;
+               state->tx_tuna[4] = 0x01;
+               break;
+       case SEC_VOLTAGE_OFF:
+               need_cmd = 1;
+               state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
+               state->tx_tuna[4] = 0x00;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (need_cmd)
+               retval = dst_tone_power_cmd(state);
+
+       return retval;
+}
+
+static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       state->tone = tone;
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return -EOPNOTSUPP;
+
+       switch (tone) {
+       case SEC_TONE_OFF:
+               if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+                   state->tx_tuna[2] = 0x00;
+               else
+                   state->tx_tuna[2] = 0xff;
+               break;
+
+       case SEC_TONE_ON:
+               state->tx_tuna[2] = 0x02;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return dst_tone_power_cmd(state);
+}
+
+static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       if (state->dst_type != DST_TYPE_IS_SAT)
+               return -EOPNOTSUPP;
+       state->minicmd = minicmd;
+       switch (minicmd) {
+       case SEC_MINI_A:
+               state->tx_tuna[3] = 0x02;
+               break;
+       case SEC_MINI_B:
+               state->tx_tuna[3] = 0xff;
+               break;
+       }
+       return dst_tone_power_cmd(state);
+}
+
+
+static int dst_init(struct dvb_frontend *fe)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
+       static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
+       static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+       static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+       static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+       static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+       static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+
+       state->inversion = INVERSION_OFF;
+       state->voltage = SEC_VOLTAGE_13;
+       state->tone = SEC_TONE_OFF;
+       state->diseq_flags = 0;
+       state->k22 = 0x02;
+       state->bandwidth = 7000000;
+       state->cur_jiff = jiffies;
+       if (state->dst_type == DST_TYPE_IS_SAT)
+               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
+       else if (state->dst_type == DST_TYPE_IS_TERR)
+               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
+       else if (state->dst_type == DST_TYPE_IS_CABLE)
+               memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
+       else if (state->dst_type == DST_TYPE_IS_ATSC)
+               memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
+
+       return 0;
+}
+
+static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       *status = 0;
+       if (state->diseq_flags & HAS_LOCK) {
+//             dst_get_signal(state);  // don't require(?) to ask MCU
+               if (state->decode_lock)
+                       *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
+       }
+
+       return 0;
+}
+
+static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       int retval = dst_get_signal(state);
+       *strength = state->decode_strength;
+
+       return retval;
+}
+
+static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct dst_state *state = fe->demodulator_priv;
+
+       int retval = dst_get_signal(state);
+       *snr = state->decode_snr;
+
+       return retval;
+}
+
+static int dst_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       int retval = -EINVAL;
+       struct dst_state *state = fe->demodulator_priv;
+
+       if (p != NULL) {
+               retval = dst_set_freq(state, p->frequency);
+               if(retval != 0)
+                       return retval;
+               dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
+
+               if (state->dst_type == DST_TYPE_IS_SAT) {
+                       if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+                               dst_set_inversion(state, p->inversion);
+                       dst_set_fec(state, p->fec_inner);
+                       dst_set_symbolrate(state, p->symbol_rate);
+                       dst_set_polarization(state);
+                       dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
+
+               } else if (state->dst_type == DST_TYPE_IS_TERR)
+                       dst_set_bandwidth(state, p->bandwidth_hz);
+               else if (state->dst_type == DST_TYPE_IS_CABLE) {
+                       dst_set_fec(state, p->fec_inner);
+                       dst_set_symbolrate(state, p->symbol_rate);
+                       dst_set_modulation(state, p->modulation);
+               }
+               retval = dst_write_tuna(fe);
+       }
+
+       return retval;
+}
+
+static int dst_tune_frontend(struct dvb_frontend* fe,
+                           bool re_tune,
+                           unsigned int mode_flags,
+                           unsigned int *delay,
+                           fe_status_t *status)
+{
+       struct dst_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (re_tune) {
+               dst_set_freq(state, p->frequency);
+               dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
+
+               if (state->dst_type == DST_TYPE_IS_SAT) {
+                       if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+                               dst_set_inversion(state, p->inversion);
+                       dst_set_fec(state, p->fec_inner);
+                       dst_set_symbolrate(state, p->symbol_rate);
+                       dst_set_polarization(state);
+                       dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->symbol_rate);
+
+               } else if (state->dst_type == DST_TYPE_IS_TERR)
+                       dst_set_bandwidth(state, p->bandwidth_hz);
+               else if (state->dst_type == DST_TYPE_IS_CABLE) {
+                       dst_set_fec(state, p->fec_inner);
+                       dst_set_symbolrate(state, p->symbol_rate);
+                       dst_set_modulation(state, p->modulation);
+               }
+               dst_write_tuna(fe);
+       }
+
+       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+               dst_read_status(fe, status);
+
+       *delay = HZ/10;
+       return 0;
+}
+
+static int dst_get_tuning_algo(struct dvb_frontend *fe)
+{
+       return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
+}
+
+static int dst_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dst_state *state = fe->demodulator_priv;
+
+       p->frequency = state->decode_freq;
+       if (state->dst_type == DST_TYPE_IS_SAT) {
+               if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+                       p->inversion = state->inversion;
+               p->symbol_rate = state->symbol_rate;
+               p->fec_inner = dst_get_fec(state);
+       } else if (state->dst_type == DST_TYPE_IS_TERR) {
+               p->bandwidth_hz = state->bandwidth;
+       } else if (state->dst_type == DST_TYPE_IS_CABLE) {
+               p->symbol_rate = state->symbol_rate;
+               p->fec_inner = dst_get_fec(state);
+               p->modulation = dst_get_modulation(state);
+       }
+
+       return 0;
+}
+
+static void dst_release(struct dvb_frontend *fe)
+{
+       struct dst_state *state = fe->demodulator_priv;
+       if (state->dst_ca) {
+               dvb_unregister_device(state->dst_ca);
+#ifdef CONFIG_MEDIA_ATTACH
+               symbol_put(dst_ca_attach);
+#endif
+       }
+       kfree(state);
+}
+
+static struct dvb_frontend_ops dst_dvbt_ops;
+static struct dvb_frontend_ops dst_dvbs_ops;
+static struct dvb_frontend_ops dst_dvbc_ops;
+static struct dvb_frontend_ops dst_atsc_ops;
+
+struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
+{
+       /* check if the ASIC is there */
+       if (dst_probe(state) < 0) {
+               kfree(state);
+               return NULL;
+       }
+       /* determine settings based on type */
+       /* create dvb_frontend */
+       switch (state->dst_type) {
+       case DST_TYPE_IS_TERR:
+               memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       case DST_TYPE_IS_CABLE:
+               memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       case DST_TYPE_IS_SAT:
+               memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       case DST_TYPE_IS_ATSC:
+               memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       default:
+               dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
+               kfree(state);
+               return NULL;
+       }
+       state->frontend.demodulator_priv = state;
+
+       return state;                           /*      Manu (DST is a card not a frontend)     */
+}
+
+EXPORT_SYMBOL(dst_attach);
+
+static struct dvb_frontend_ops dst_dvbt_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "DST DVB-T",
+               .frequency_min = 137000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 166667,
+               .caps = FE_CAN_FEC_AUTO                 |
+                       FE_CAN_QAM_AUTO                 |
+                       FE_CAN_QAM_16                   |
+                       FE_CAN_QAM_32                   |
+                       FE_CAN_QAM_64                   |
+                       FE_CAN_QAM_128                  |
+                       FE_CAN_QAM_256                  |
+                       FE_CAN_TRANSMISSION_MODE_AUTO   |
+                       FE_CAN_GUARD_INTERVAL_AUTO
+       },
+
+       .release = dst_release,
+       .init = dst_init,
+       .tune = dst_tune_frontend,
+       .set_frontend = dst_set_frontend,
+       .get_frontend = dst_get_frontend,
+       .get_frontend_algo = dst_get_tuning_algo,
+       .read_status = dst_read_status,
+       .read_signal_strength = dst_read_signal_strength,
+       .read_snr = dst_read_snr,
+};
+
+static struct dvb_frontend_ops dst_dvbs_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name = "DST DVB-S",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1000,     /* kHz for QPSK frontends */
+               .frequency_tolerance = 29500,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+       /*     . symbol_rate_tolerance  =       ???,*/
+               .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
+       },
+
+       .release = dst_release,
+       .init = dst_init,
+       .tune = dst_tune_frontend,
+       .set_frontend = dst_set_frontend,
+       .get_frontend = dst_get_frontend,
+       .get_frontend_algo = dst_get_tuning_algo,
+       .read_status = dst_read_status,
+       .read_signal_strength = dst_read_signal_strength,
+       .read_snr = dst_read_snr,
+       .diseqc_send_burst = dst_send_burst,
+       .diseqc_send_master_cmd = dst_set_diseqc,
+       .set_voltage = dst_set_voltage,
+       .set_tone = dst_set_tone,
+};
+
+static struct dvb_frontend_ops dst_dvbc_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A },
+       .info = {
+               .name = "DST DVB-C",
+               .frequency_stepsize = 62500,
+               .frequency_min = 51000000,
+               .frequency_max = 858000000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_QAM_16   |
+                       FE_CAN_QAM_32   |
+                       FE_CAN_QAM_64   |
+                       FE_CAN_QAM_128  |
+                       FE_CAN_QAM_256
+       },
+
+       .release = dst_release,
+       .init = dst_init,
+       .tune = dst_tune_frontend,
+       .set_frontend = dst_set_frontend,
+       .get_frontend = dst_get_frontend,
+       .get_frontend_algo = dst_get_tuning_algo,
+       .read_status = dst_read_status,
+       .read_signal_strength = dst_read_signal_strength,
+       .read_snr = dst_read_snr,
+};
+
+static struct dvb_frontend_ops dst_atsc_ops = {
+       .delsys = { SYS_ATSC },
+       .info = {
+               .name = "DST ATSC",
+               .frequency_stepsize = 62500,
+               .frequency_min = 510000000,
+               .frequency_max = 858000000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .release = dst_release,
+       .init = dst_init,
+       .tune = dst_tune_frontend,
+       .set_frontend = dst_set_frontend,
+       .get_frontend = dst_get_frontend,
+       .get_frontend_algo = dst_get_tuning_algo,
+       .read_status = dst_read_status,
+       .read_signal_strength = dst_read_signal_strength,
+       .read_snr = dst_read_snr,
+};
+
+MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
+MODULE_AUTHOR("Jamie Honan, Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
new file mode 100644 (file)
index 0000000..ee3884f
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+       CA-driver for TwinHan DST Frontend/Card
+
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/dvb/ca.h>
+#include "dvbdev.h"
+#include "dvb_frontend.h"
+#include "dst_ca.h"
+#include "dst_common.h"
+
+#define DST_CA_ERROR           0
+#define DST_CA_NOTICE          1
+#define DST_CA_INFO            2
+#define DST_CA_DEBUG           3
+
+#define dprintk(x, y, z, format, arg...) do {                                          \
+       if (z) {                                                                        \
+               if      ((x > DST_CA_ERROR) && (x > y))                                 \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);  \
+               else if ((x > DST_CA_NOTICE) && (x > y))                                \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((x > DST_CA_INFO) && (x > y))                                  \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+               else if ((x > DST_CA_DEBUG) && (x > y))                                 \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (x > y)                                                              \
+                       printk(format, ## arg);                                         \
+       }                                                                               \
+} while(0)
+
+
+static DEFINE_MUTEX(dst_ca_mutex);
+static unsigned int verbose = 5;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+
+/*     Need some more work     */
+static int ca_set_slot_descr(void)
+{
+       /*      We could make this more graceful ?      */
+       return -EOPNOTSUPP;
+}
+
+/*     Need some more work     */
+static int ca_set_pid(void)
+{
+       /*      We could make this more graceful ?      */
+       return -EOPNOTSUPP;
+}
+
+static void put_command_and_length(u8 *data, int command, int length)
+{
+       data[0] = (command >> 16) & 0xff;
+       data[1] = (command >> 8) & 0xff;
+       data[2] = command & 0xff;
+       data[3] = length;
+}
+
+static void put_checksum(u8 *check_string, int length)
+{
+       dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
+       dprintk(verbose, DST_CA_DEBUG, 1, "  -> string length : 0x%02x", length);
+       check_string[length] = dst_check_sum (check_string, length);
+       dprintk(verbose, DST_CA_DEBUG, 1, "  -> checksum      : 0x%02x", check_string[length]);
+}
+
+static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
+{
+       u8 reply;
+
+       mutex_lock(&state->dst_mutex);
+       dst_comm_init(state);
+       msleep(65);
+
+       if (write_dst(state, data, len)) {
+               dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
+               dst_error_recovery(state);
+               goto error;
+       }
+       if ((dst_pio_disable(state)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
+               goto error;
+       }
+       if (read_dst(state, &reply, GET_ACK) < 0) {
+               dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
+               dst_error_recovery(state);
+               goto error;
+       }
+       if (read) {
+               if (! dst_wait_dst_ready(state, LONG_DELAY)) {
+                       dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
+                       goto error;
+               }
+               if (read_dst(state, ca_string, 128) < 0) {      /*      Try to make this dynamic        */
+                       dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
+                       dst_error_recovery(state);
+                       goto error;
+               }
+       }
+       mutex_unlock(&state->dst_mutex);
+       return 0;
+
+error:
+       mutex_unlock(&state->dst_mutex);
+       return -EIO;
+}
+
+
+static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read)
+{
+       u8 dst_ca_comm_err = 0;
+
+       while (dst_ca_comm_err < RETRIES) {
+               dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
+               if (dst_ci_command(state, data, ca_string, len, read)) {        // If error
+                       dst_error_recovery(state);
+                       dst_ca_comm_err++; // work required here.
+               } else {
+                       break;
+               }
+       }
+
+       if(dst_ca_comm_err == RETRIES)
+               return -1;
+
+       return 0;
+}
+
+
+
+static int ca_get_app_info(struct dst_state *state)
+{
+       int length, str_length;
+       static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff};
+
+       put_checksum(&command[0], command[0]);
+       if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
+               return -1;
+       }
+       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
+       dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
+       dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
+               state->messages[7], (state->messages[8] << 8) | state->messages[9],
+               (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12]));
+       dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
+
+       // Transform dst message to correct application_info message
+       length = state->messages[5];
+       str_length = length - 6;
+       if (str_length < 0) {
+               str_length = 0;
+               dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering.");
+       }
+
+       // First, the command and length fields
+       put_command_and_length(&state->messages[0], CA_APP_INFO, length);
+
+       // Copy application_type, application_manufacturer and manufacturer_code
+       memcpy(&state->messages[4], &state->messages[7], 5);
+
+       // Set string length and copy string
+       state->messages[9] = str_length;
+       memcpy(&state->messages[10], &state->messages[12], str_length);
+
+       return 0;
+}
+
+static int ca_get_ca_info(struct dst_state *state)
+{
+       int srcPtr, dstPtr, i, num_ids;
+       static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff};
+       const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7;
+
+       put_checksum(&slot_command[0], slot_command[0]);
+       if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
+               return -1;
+       }
+       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
+
+       // Print raw data
+       dprintk(verbose, DST_CA_INFO, 0, " DST data = [");
+       for (i = 0; i < state->messages[0] + 1; i++) {
+               dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]);
+       }
+       dprintk(verbose, DST_CA_INFO, 0, "]\n");
+
+       // Set the command and length of the output
+       num_ids = state->messages[in_num_ids_pos];
+       if (num_ids >= 100) {
+               num_ids = 100;
+               dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering.");
+       }
+       put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2);
+
+       dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = [");
+       srcPtr = in_system_id_pos;
+       dstPtr = out_system_id_pos;
+       for(i = 0; i < num_ids; i++) {
+               dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]);
+               // Append to output
+               state->messages[dstPtr + 0] = state->messages[srcPtr + 0];
+               state->messages[dstPtr + 1] = state->messages[srcPtr + 1];
+               srcPtr += 2;
+               dstPtr += 2;
+       }
+       dprintk(verbose, DST_CA_INFO, 0, "]\n");
+
+       return 0;
+}
+
+static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
+{
+       int i;
+       u8 slot_cap[256];
+       static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff};
+
+       put_checksum(&slot_command[0], slot_command[0]);
+       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
+               return -1;
+       }
+       dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
+
+       /*      Will implement the rest soon            */
+
+       dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
+       dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+       for (i = 0; i < slot_cap[0] + 1; i++)
+               dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
+       dprintk(verbose, DST_CA_INFO, 0, "\n");
+
+       p_ca_caps->slot_num = 1;
+       p_ca_caps->slot_type = 1;
+       p_ca_caps->descr_num = slot_cap[7];
+       p_ca_caps->descr_type = 1;
+
+       if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
+               return -EFAULT;
+
+       return 0;
+}
+
+/*     Need some more work     */
+static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
+{
+       return -EOPNOTSUPP;
+}
+
+
+static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
+{
+       int i;
+       static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
+
+       u8 *slot_info = state->messages;
+
+       put_checksum(&slot_command[0], 7);
+       if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
+               return -1;
+       }
+       dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
+
+       /*      Will implement the rest soon            */
+
+       dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
+       dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+       for (i = 0; i < 8; i++)
+               dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
+       dprintk(verbose, DST_CA_INFO, 0, "\n");
+
+       if (slot_info[4] & 0x80) {
+               p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
+               p_ca_slot_info->num = 1;
+               p_ca_slot_info->type = CA_CI;
+       } else if (slot_info[4] & 0x40) {
+               p_ca_slot_info->flags = CA_CI_MODULE_READY;
+               p_ca_slot_info->num = 1;
+               p_ca_slot_info->type = CA_CI;
+       } else
+               p_ca_slot_info->flags = 0;
+
+       if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
+               return -EFAULT;
+
+       return 0;
+}
+
+
+static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
+{
+       u8 i = 0;
+       u32 command = 0;
+
+       if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
+               return -EFAULT;
+
+       if (p_ca_message->msg) {
+               dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]",
+                       3, p_ca_message->msg);
+
+               for (i = 0; i < 3; i++) {
+                       command = command | p_ca_message->msg[i];
+                       if (i < 2)
+                               command = command << 8;
+               }
+               dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
+
+               switch (command) {
+               case CA_APP_INFO:
+                       memcpy(p_ca_message->msg, state->messages, 128);
+                       if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
+                               return -EFAULT;
+                       break;
+               case CA_INFO:
+                       memcpy(p_ca_message->msg, state->messages, 128);
+                       if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
+                               return -EFAULT;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
+{
+       if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
+               hw_buffer->msg[2] = p_ca_message->msg[1];       /*      MSB     */
+               hw_buffer->msg[3] = p_ca_message->msg[2];       /*      LSB     */
+       } else {
+               if (length > 247) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
+                       return -1;
+               }
+               hw_buffer->msg[0] = (length & 0xff) + 7;
+               hw_buffer->msg[1] = 0x40;
+               hw_buffer->msg[2] = 0x03;
+               hw_buffer->msg[3] = 0x00;
+               hw_buffer->msg[4] = 0x03;
+               hw_buffer->msg[5] = length & 0xff;
+               hw_buffer->msg[6] = 0x00;
+
+               /*
+                *      Need to compute length for EN50221 section 8.3.2, for the time being
+                *      assuming 8.3.2 is not applicable
+                */
+               memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
+       }
+
+       return 0;
+}
+
+static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
+{
+       if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
+               dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
+               dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
+               rdc_reset_state(state);
+               return -1;
+       }
+       dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success.");
+
+       return 0;
+}
+
+static u32 asn_1_decode(u8 *asn_1_array)
+{
+       u8 length_field = 0, word_count = 0, count = 0;
+       u32 length = 0;
+
+       length_field = asn_1_array[0];
+       dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
+       if (length_field < 0x80) {
+               length = length_field & 0x7f;
+               dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
+       } else {
+               word_count = length_field & 0x7f;
+               for (count = 0; count < word_count; count++) {
+                       length = length  << 8;
+                       length += asn_1_array[count + 1];
+                       dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
+               }
+       }
+       return length;
+}
+
+static int debug_string(u8 *msg, u32 length, u32 offset)
+{
+       u32 i;
+
+       dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
+       for (i = offset; i < length; i++)
+               dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
+       dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
+
+       return 0;
+}
+
+
+static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+{
+       u32 length = 0;
+       u8 tag_length = 8;
+
+       length = asn_1_decode(&p_ca_message->msg[3]);
+       dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
+       debug_string(&p_ca_message->msg[4], length, 0); /*      length is excluding tag & length        */
+
+       memset(hw_buffer->msg, '\0', length);
+       handle_dst_tag(state, p_ca_message, hw_buffer, length);
+       put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
+
+       debug_string(hw_buffer->msg, (length + tag_length), 0); /*      tags too        */
+       write_to_8820(state, hw_buffer, (length + tag_length), reply);
+
+       return 0;
+}
+
+
+/*     Board supports CA PMT reply ?           */
+static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
+{
+       int ca_pmt_reply_test = 0;
+
+       /*      Do test board                   */
+       /*      Not there yet but soon          */
+
+       /*      CA PMT Reply capable            */
+       if (ca_pmt_reply_test) {
+               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
+                       return -1;
+               }
+
+       /*      Process CA PMT Reply            */
+       /*      will implement soon             */
+               dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
+       }
+       /*      CA PMT Reply not capable        */
+       if (!ca_pmt_reply_test) {
+               if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
+                       return -1;
+               }
+               dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
+       /*      put a dummy message             */
+
+       }
+       return 0;
+}
+
+static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
+{
+       int i = 0;
+
+       u32 command = 0;
+       struct ca_msg *hw_buffer;
+       int result = 0;
+
+       if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
+               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
+               return -ENOMEM;
+       }
+       dprintk(verbose, DST_CA_DEBUG, 1, " ");
+
+       if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
+               result = -EFAULT;
+               goto free_mem_and_exit;
+       }
+
+
+       if (p_ca_message->msg) {
+               /*      EN50221 tag     */
+               command = 0;
+
+               for (i = 0; i < 3; i++) {
+                       command = command | p_ca_message->msg[i];
+                       if (i < 2)
+                               command = command << 8;
+               }
+               dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
+
+               switch (command) {
+               case CA_PMT:
+                       dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
+                       if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {   // code simplification started
+                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
+                               result = -1;
+                               goto free_mem_and_exit;
+                       }
+                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
+                       break;
+               case CA_PMT_REPLY:
+                       dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
+                       /*      Have to handle the 2 basic types of cards here  */
+                       if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
+                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
+                               result = -1;
+                               goto free_mem_and_exit;
+                       }
+                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
+                       break;
+               case CA_APP_INFO_ENQUIRY:               // only for debugging
+                       dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
+
+                       if ((ca_get_app_info(state)) < 0) {
+                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
+                               result = -1;
+                               goto free_mem_and_exit;
+                       }
+                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
+                       break;
+               case CA_INFO_ENQUIRY:
+                       dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information");
+
+                       if ((ca_get_ca_info(state)) < 0) {
+                               dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !");
+                               result = -1;
+                               goto free_mem_and_exit;
+                       }
+                       dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !");
+                       break;
+               }
+       }
+free_mem_and_exit:
+       kfree (hw_buffer);
+
+       return result;
+}
+
+static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+{
+       struct dvb_device *dvbdev;
+       struct dst_state *state;
+       struct ca_slot_info *p_ca_slot_info;
+       struct ca_caps *p_ca_caps;
+       struct ca_msg *p_ca_message;
+       void __user *arg = (void __user *)ioctl_arg;
+       int result = 0;
+
+       mutex_lock(&dst_ca_mutex);
+       dvbdev = file->private_data;
+       state = (struct dst_state *)dvbdev->priv;
+       p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
+       p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
+       p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
+       if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
+               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
+               result = -ENOMEM;
+               goto free_mem_and_exit;
+       }
+
+       /*      We have now only the standard ioctl's, the driver is upposed to handle internals.       */
+       switch (cmd) {
+       case CA_SEND_MSG:
+               dprintk(verbose, DST_CA_INFO, 1, " Sending message");
+               if ((ca_send_message(state, p_ca_message, arg)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               break;
+       case CA_GET_MSG:
+               dprintk(verbose, DST_CA_INFO, 1, " Getting message");
+               if ((ca_get_message(state, p_ca_message, arg)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
+               break;
+       case CA_RESET:
+               dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
+               dst_error_bailout(state);
+               msleep(4000);
+               break;
+       case CA_GET_SLOT_INFO:
+               dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
+               if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
+               break;
+       case CA_GET_CAP:
+               dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
+               if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
+               break;
+       case CA_GET_DESCR_INFO:
+               dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
+               if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
+               break;
+       case CA_SET_DESCR:
+               dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
+               if ((ca_set_slot_descr()) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
+               break;
+       case CA_SET_PID:
+               dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
+               if ((ca_set_pid()) < 0) {
+                       dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
+                       result = -1;
+                       goto free_mem_and_exit;
+               }
+               dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
+       default:
+               result = -EOPNOTSUPP;
+       };
+ free_mem_and_exit:
+       kfree (p_ca_message);
+       kfree (p_ca_slot_info);
+       kfree (p_ca_caps);
+
+       mutex_unlock(&dst_ca_mutex);
+       return result;
+}
+
+static int dst_ca_open(struct inode *inode, struct file *file)
+{
+       dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
+       try_module_get(THIS_MODULE);
+
+       return 0;
+}
+
+static int dst_ca_release(struct inode *inode, struct file *file)
+{
+       dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
+       module_put(THIS_MODULE);
+
+       return 0;
+}
+
+static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
+{
+       ssize_t bytes_read = 0;
+
+       dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
+
+       return bytes_read;
+}
+
+static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
+{
+       dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
+
+       return 0;
+}
+
+static const struct file_operations dst_ca_fops = {
+       .owner = THIS_MODULE,
+       .unlocked_ioctl = dst_ca_ioctl,
+       .open = dst_ca_open,
+       .release = dst_ca_release,
+       .read = dst_ca_read,
+       .write = dst_ca_write,
+       .llseek = noop_llseek,
+};
+
+static struct dvb_device dvbdev_ca = {
+       .priv = NULL,
+       .users = 1,
+       .readers = 1,
+       .writers = 1,
+       .fops = &dst_ca_fops
+};
+
+struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
+{
+       struct dvb_device *dvbdev;
+
+       dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
+       if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
+               dst->dst_ca = dvbdev;
+               return dst->dst_ca;
+       }
+
+       return NULL;
+}
+
+EXPORT_SYMBOL(dst_ca_attach);
+
+MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/dst_ca.h b/drivers/media/pci/bt8xx/dst_ca.h
new file mode 100644 (file)
index 0000000..59cd0dd
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+       CA-driver for TwinHan DST Frontend/Card
+
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 _DST_CA_H_
+#define _DST_CA_H_
+
+#define RETRIES                        5
+
+
+#define        CA_APP_INFO_ENQUIRY     0x9f8020
+#define        CA_APP_INFO             0x9f8021
+#define        CA_ENTER_MENU           0x9f8022
+#define CA_INFO_ENQUIRY                0x9f8030
+#define        CA_INFO                 0x9f8031
+#define CA_PMT                 0x9f8032
+#define CA_PMT_REPLY           0x9f8033
+
+#define CA_CLOSE_MMI           0x9f8800
+#define CA_DISPLAY_CONTROL     0x9f8801
+#define CA_DISPLAY_REPLY       0x9f8802
+#define CA_TEXT_LAST           0x9f8803
+#define CA_TEXT_MORE           0x9f8804
+#define CA_KEYPAD_CONTROL      0x9f8805
+#define CA_KEYPRESS            0x9f8806
+
+#define CA_ENQUIRY             0x9f8807
+#define CA_ANSWER              0x9f8808
+#define CA_MENU_LAST           0x9f8809
+#define CA_MENU_MORE           0x9f880a
+#define CA_MENU_ANSWER         0x9f880b
+#define CA_LIST_LAST           0x9f880c
+#define CA_LIST_MORE           0x9f880d
+
+
+struct dst_ca_private {
+       struct dst_state *dst;
+       struct dvb_device *dvbdev;
+};
+
+
+#endif
diff --git a/drivers/media/pci/bt8xx/dst_common.h b/drivers/media/pci/bt8xx/dst_common.h
new file mode 100644 (file)
index 0000000..d70d98f
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+       Frontend-driver for TwinHan DST Frontend
+
+       Copyright (C) 2003 Jamie Honan
+       Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 DST_COMMON_H
+#define DST_COMMON_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include "bt878.h"
+
+#include "dst_ca.h"
+
+
+#define NO_DELAY               0
+#define LONG_DELAY             1
+#define DEVICE_INIT            2
+
+#define DELAY                  1
+
+#define DST_TYPE_IS_SAT                0
+#define DST_TYPE_IS_TERR       1
+#define DST_TYPE_IS_CABLE      2
+#define DST_TYPE_IS_ATSC       3
+
+#define DST_TYPE_HAS_TS188     1
+#define DST_TYPE_HAS_TS204     2
+#define DST_TYPE_HAS_SYMDIV    4
+#define DST_TYPE_HAS_FW_1      8
+#define DST_TYPE_HAS_FW_2      16
+#define DST_TYPE_HAS_FW_3      32
+#define DST_TYPE_HAS_FW_BUILD  64
+#define DST_TYPE_HAS_OBS_REGS  128
+#define DST_TYPE_HAS_INC_COUNT 256
+#define DST_TYPE_HAS_MULTI_FE  512
+#define DST_TYPE_HAS_NEWTUNE_2 1024
+#define DST_TYPE_HAS_DBOARD    2048
+#define DST_TYPE_HAS_VLF       4096
+
+/*     Card capability list    */
+
+#define DST_TYPE_HAS_MAC       1
+#define DST_TYPE_HAS_DISEQC3   2
+#define DST_TYPE_HAS_DISEQC4   4
+#define DST_TYPE_HAS_DISEQC5   8
+#define DST_TYPE_HAS_MOTO      16
+#define DST_TYPE_HAS_CA                32
+#define        DST_TYPE_HAS_ANALOG     64      /*      Analog inputs   */
+#define DST_TYPE_HAS_SESSION   128
+
+#define TUNER_TYPE_MULTI       1
+#define TUNER_TYPE_UNKNOWN     2
+/*     DVB-S           */
+#define TUNER_TYPE_L64724      4
+#define TUNER_TYPE_STV0299     8
+#define TUNER_TYPE_MB86A15     16
+
+/*     DVB-T           */
+#define TUNER_TYPE_TDA10046    32
+
+/*     ATSC            */
+#define TUNER_TYPE_NXT200x     64
+
+
+#define RDC_8820_PIO_0_DISABLE 0
+#define RDC_8820_PIO_0_ENABLE  1
+#define RDC_8820_INT           2
+#define RDC_8820_RESET         4
+
+/*     DST Communication       */
+#define GET_REPLY              1
+#define NO_REPLY               0
+
+#define GET_ACK                        1
+#define FIXED_COMM             8
+
+#define ACK                    0xff
+
+struct dst_state {
+
+       struct i2c_adapter* i2c;
+
+       struct bt878* bt;
+
+       /* configuration settings */
+       const struct dst_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* private ASIC data */
+       u8 tx_tuna[10];
+       u8 rx_tuna[10];
+       u8 rxbuffer[10];
+       u8 diseq_flags;
+       u8 dst_type;
+       u32 type_flags;
+       u32 frequency;          /* intermediate frequency in kHz for QPSK */
+       fe_spectral_inversion_t inversion;
+       u32 symbol_rate;        /* symbol rate in Symbols per second */
+       fe_code_rate_t fec;
+       fe_sec_voltage_t voltage;
+       fe_sec_tone_mode_t tone;
+       u32 decode_freq;
+       u8 decode_lock;
+       u16 decode_strength;
+       u16 decode_snr;
+       unsigned long cur_jiff;
+       u8 k22;
+       u32 bandwidth;
+       u32 dst_hw_cap;
+       u8 dst_fw_version;
+       fe_sec_mini_cmd_t minicmd;
+       fe_modulation_t modulation;
+       u8 messages[256];
+       u8 mac_address[8];
+       u8 fw_version[8];
+       u8 card_info[8];
+       u8 vendor[8];
+       u8 board_info[8];
+       u32 tuner_type;
+       char *tuner_name;
+       struct mutex dst_mutex;
+       u8 fw_name[8];
+       struct dvb_device *dst_ca;
+};
+
+struct tuner_types {
+       u32 tuner_type;
+       char *tuner_name;
+       char *board_name;
+       char *fw_name;
+};
+
+struct dst_types {
+       char *device_id;
+       int offset;
+       u8 dst_type;
+       u32 type_flags;
+       u32 dst_feature;
+       u32 tuner_type;
+};
+
+struct dst_config
+{
+       /* the ASIC i2c address */
+       u8 demod_address;
+};
+
+int rdc_reset_state(struct dst_state *state);
+
+int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode);
+int dst_pio_disable(struct dst_state *state);
+int dst_error_recovery(struct dst_state* state);
+int dst_error_bailout(struct dst_state *state);
+int dst_comm_init(struct dst_state* state);
+
+int write_dst(struct dst_state *state, u8 * data, u8 len);
+int read_dst(struct dst_state *state, u8 * ret, u8 len);
+u8 dst_check_sum(u8 * buf, u32 len);
+struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
+struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
+
+
+#endif // DST_COMMON_H
diff --git a/drivers/media/pci/bt8xx/dst_priv.h b/drivers/media/pci/bt8xx/dst_priv.h
new file mode 100644 (file)
index 0000000..3974a4c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
+ *
+ * Copyright (C) 2003 Jamie Honan
+ */
+
+struct dst_gpio_enable {
+       u32     mask;
+       u32     enable;
+};
+
+struct dst_gpio_output {
+       u32     mask;
+       u32     highvals;
+};
+
+struct dst_gpio_read {
+       unsigned long value;
+};
+
+union dst_gpio_packet {
+       struct dst_gpio_enable enb;
+       struct dst_gpio_output outp;
+       struct dst_gpio_read rd;
+       int    psize;
+};
+
+#define DST_IG_ENABLE  0
+#define DST_IG_WRITE   1
+#define DST_IG_READ    2
+#define DST_IG_TS       3
+
+struct bt878;
+
+int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
new file mode 100644 (file)
index 0000000..81fab9a
--- /dev/null
@@ -0,0 +1,975 @@
+/*
+ * Bt8xx based DVB adapter driver
+ *
+ * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) "dvb_bt8xx: " fmt
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb-bt8xx.h"
+#include "bt878.h"
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define dprintk( args... ) \
+       do { \
+               if (debug) printk(KERN_DEBUG args); \
+       } while (0)
+
+#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
+
+static void dvb_bt8xx_task(unsigned long data)
+{
+       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
+
+       //printk("%d ", card->bt->finished_block);
+
+       while (card->bt->last_block != card->bt->finished_block) {
+               (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
+                       (&card->demux,
+                        &card->bt->buf_cpu[card->bt->last_block *
+                                           card->bt->block_bytes],
+                        card->bt->block_bytes);
+               card->bt->last_block = (card->bt->last_block + 1) %
+                                       card->bt->block_count;
+       }
+}
+
+static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
+       struct dvb_bt8xx_card *card = dvbdmx->priv;
+       int rc;
+
+       dprintk("dvb_bt8xx: start_feed\n");
+
+       if (!dvbdmx->dmx.frontend)
+               return -EINVAL;
+
+       mutex_lock(&card->lock);
+       card->nfeeds++;
+       rc = card->nfeeds;
+       if (card->nfeeds == 1)
+               bt878_start(card->bt, card->gpio_mode,
+                           card->op_sync_orin, card->irq_err_ignore);
+       mutex_unlock(&card->lock);
+       return rc;
+}
+
+static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct dvb_bt8xx_card *card = dvbdmx->priv;
+
+       dprintk("dvb_bt8xx: stop_feed\n");
+
+       if (!dvbdmx->dmx.frontend)
+               return -EINVAL;
+
+       mutex_lock(&card->lock);
+       card->nfeeds--;
+       if (card->nfeeds == 0)
+               bt878_stop(card->bt);
+       mutex_unlock(&card->lock);
+
+       return 0;
+}
+
+static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
+{
+       if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
+               (adev->subsystem_device == bdev->subsystem_device) &&
+               (adev->bus->number == bdev->bus->number) &&
+               (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
+               return 1;
+       return 0;
+}
+
+static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
+{
+       unsigned int card_nr;
+
+       /* Hmm, n squared. Hope n is small */
+       for (card_nr = 0; card_nr < bt878_num; card_nr++)
+               if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
+                       return &bt878[card_nr];
+       return NULL;
+}
+
+static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
+{
+       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
+       static u8 mt352_reset [] = { 0x50, 0x80 };
+       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
+       static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
+       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+       mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+       mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
+       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+       return 0;
+}
+
+static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend *fe, u8* pllbuf, int buf_len)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 div;
+       unsigned char bs = 0;
+       unsigned char cp = 0;
+
+       if (buf_len < 5)
+               return -EINVAL;
+
+       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+       if (c->frequency < 542000000)
+               cp = 0xb4;
+       else if (c->frequency < 771000000)
+               cp = 0xbc;
+       else
+               cp = 0xf4;
+
+       if (c->frequency == 0)
+               bs = 0x03;
+       else if (c->frequency < 443250000)
+               bs = 0x02;
+       else
+               bs = 0x08;
+
+       pllbuf[0] = 0x60;
+       pllbuf[1] = div >> 8;
+       pllbuf[2] = div & 0xff;
+       pllbuf[3] = cp;
+       pllbuf[4] = bs;
+
+       return 5;
+}
+
+static struct mt352_config thomson_dtt7579_config = {
+       .demod_address = 0x0f,
+       .demod_init = thomson_dtt7579_demod_init,
+};
+
+static struct zl10353_config thomson_dtt7579_zl10353_config = {
+       .demod_address = 0x0f,
+};
+
+static int cx24108_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 freq = c->frequency;
+       int i, a, n, pump;
+       u32 band, pll;
+       u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
+               1576000,1718000,1856000,2036000,2150000};
+       u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
+               0x00102000,0x00104000,0x00108000,0x00110000,
+               0x00120000,0x00140000};
+
+       #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
+       dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n", freq);
+
+       /* This is really the bit driving the tuner chip cx24108 */
+
+       if (freq<950000)
+               freq = 950000; /* kHz */
+       else if (freq>2150000)
+               freq = 2150000; /* satellite IF is 950..2150MHz */
+
+       /* decide which VCO to use for the input frequency */
+       for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
+       dprintk("cx24108 debug: select vco #%d (f=%d)\n", i, freq);
+       band=bandsel[i];
+       /* the gain values must be set by SetSymbolrate */
+       /* compute the pll divider needed, from Conexant data sheet,
+          resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
+          depending on the divider bit. It is set to /4 on the 2 lowest
+          bands  */
+       n=((i<=2?2:1)*freq*10L)/(XTAL/100);
+       a=n%32; n/=32; if(a==0) n--;
+       pump=(freq<(osci[i-1]+osci[i])/2);
+       pll=0xf8000000|
+           ((pump?1:2)<<(14+11))|
+           ((n&0x1ff)<<(5+11))|
+           ((a&0x1f)<<11);
+       /* everything is shifted left 11 bits to left-align the bits in the
+          32bit word. Output to the tuner goes MSB-aligned, after all */
+       dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n", pump, n, a);
+       cx24110_pll_write(fe,band);
+       /* set vga and vca to their widest-band settings, as a precaution.
+          SetSymbolrate might not be called to set this up */
+       cx24110_pll_write(fe,0x500c0000);
+       cx24110_pll_write(fe,0x83f1f800);
+       cx24110_pll_write(fe,pll);
+       //writereg(client,0x56,0x7f);
+
+       return 0;
+}
+
+static int pinnsat_tuner_init(struct dvb_frontend* fe)
+{
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_gpio_enable(card->bttv_nr, 1, 1);  /* output */
+       bttv_write_gpio(card->bttv_nr, 1, 1);   /* relay on */
+
+       return 0;
+}
+
+static int pinnsat_tuner_sleep(struct dvb_frontend* fe)
+{
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_write_gpio(card->bttv_nr, 1, 0);   /* relay off */
+
+       return 0;
+}
+
+static struct cx24110_config pctvsat_config = {
+       .demod_address = 0x55,
+};
+
+static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
+       u8 cfg, cpump, band_select;
+       u8 data[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (36000000 + c->frequency + 83333) / 166666;
+       cfg = 0x88;
+
+       if (c->frequency < 175000000)
+               cpump = 2;
+       else if (c->frequency < 390000000)
+               cpump = 1;
+       else if (c->frequency < 470000000)
+               cpump = 2;
+       else if (c->frequency < 750000000)
+               cpump = 2;
+       else
+               cpump = 3;
+
+       if (c->frequency < 175000000)
+               band_select = 0x0e;
+       else if (c->frequency < 470000000)
+               band_select = 0x05;
+       else
+               band_select = 0x03;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = ((div >> 10) & 0x60) | cfg;
+       data[3] = (cpump << 6) | band_select;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       i2c_transfer(card->i2c_adapter, &msg, 1);
+       return (div * 166666 - 36000000);
+}
+
+static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+       struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
+
+       return request_firmware(fw, name, &bt->bt->dev->dev);
+}
+
+static struct sp887x_config microtune_mt7202dtf_config = {
+       .demod_address = 0x70,
+       .request_firmware = microtune_mt7202dtf_request_firmware,
+};
+
+static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
+{
+       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+       static u8 mt352_reset [] = { 0x50, 0x80 };
+       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
+                                      0x00, 0xFF, 0x00, 0x40, 0x40 };
+       static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
+       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+
+       mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
+       udelay(2000);
+       mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
+       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+       return 0;
+}
+
+static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend *fe, u8 *pllbuf, int buf_len)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 div;
+       unsigned char bs = 0;
+       unsigned char cp = 0;
+
+       if (buf_len < 5) return -EINVAL;
+
+       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+       if (c->frequency < 150000000)
+               cp = 0xB4;
+       else if (c->frequency < 173000000)
+               cp = 0xBC;
+       else if (c->frequency < 250000000)
+               cp = 0xB4;
+       else if (c->frequency < 400000000)
+               cp = 0xBC;
+       else if (c->frequency < 420000000)
+               cp = 0xF4;
+       else if (c->frequency < 470000000)
+               cp = 0xFC;
+       else if (c->frequency < 600000000)
+               cp = 0xBC;
+       else if (c->frequency < 730000000)
+               cp = 0xF4;
+       else
+               cp = 0xFC;
+
+       if (c->frequency < 150000000)
+               bs = 0x01;
+       else if (c->frequency < 173000000)
+               bs = 0x01;
+       else if (c->frequency < 250000000)
+               bs = 0x02;
+       else if (c->frequency < 400000000)
+               bs = 0x02;
+       else if (c->frequency < 420000000)
+               bs = 0x02;
+       else if (c->frequency < 470000000)
+               bs = 0x02;
+       else if (c->frequency < 600000000)
+               bs = 0x08;
+       else if (c->frequency < 730000000)
+               bs = 0x08;
+       else
+               bs = 0x08;
+
+       pllbuf[0] = 0x61;
+       pllbuf[1] = div >> 8;
+       pllbuf[2] = div & 0xff;
+       pllbuf[3] = cp;
+       pllbuf[4] = bs;
+
+       return 5;
+}
+
+static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
+       .demod_address = 0x0f,
+       .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
+};
+
+static struct dst_config dst_config = {
+       .demod_address = 0x55,
+};
+
+static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+       struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
+
+       return request_firmware(fw, name, &bt->bt->dev->dev);
+}
+
+static void or51211_setmode(struct dvb_frontend * fe, int mode)
+{
+       struct dvb_bt8xx_card *bt = fe->dvb->priv;
+       bttv_write_gpio(bt->bttv_nr, 0x0002, mode);   /* Reset */
+       msleep(20);
+}
+
+static void or51211_reset(struct dvb_frontend * fe)
+{
+       struct dvb_bt8xx_card *bt = fe->dvb->priv;
+
+       /* RESET DEVICE
+        * reset is controlled by GPIO-0
+        * when set to 0 causes reset and when to 1 for normal op
+        * must remain reset for 128 clock cycles on a 50Mhz clock
+        * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4
+        * We assume that the reset has be held low long enough or we
+        * have been reset by a power on.  When the driver is unloaded
+        * reset set to 0 so if reloaded we have been reset.
+        */
+       /* reset & PRM1,2&4 are outputs */
+       int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
+       if (ret != 0)
+               printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
+       bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000);   /* Reset */
+       msleep(20);
+       /* Now set for normal operation */
+       bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
+       /* wait for operation to begin */
+       msleep(500);
+}
+
+static void or51211_sleep(struct dvb_frontend * fe)
+{
+       struct dvb_bt8xx_card *bt = fe->dvb->priv;
+       bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
+}
+
+static struct or51211_config or51211_config = {
+       .demod_address = 0x15,
+       .request_firmware = or51211_request_firmware,
+       .setmode = or51211_setmode,
+       .reset = or51211_reset,
+       .sleep = or51211_sleep,
+};
+
+static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
+
+       div = (c->frequency + 36166667) / 166667;
+
+       buf[0] = (div >> 8) & 0x7F;
+       buf[1] = div & 0xFF;
+       buf[2] = 0x85;
+       if ((c->frequency >= 47000000) && (c->frequency < 153000000))
+               buf[3] = 0x01;
+       else if ((c->frequency >= 153000000) && (c->frequency < 430000000))
+               buf[3] = 0x02;
+       else if ((c->frequency >= 430000000) && (c->frequency < 824000000))
+               buf[3] = 0x0C;
+       else if ((c->frequency >= 824000000) && (c->frequency < 863000000))
+               buf[3] = 0x8C;
+       else
+               return -EINVAL;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       i2c_transfer(card->i2c_adapter, &msg, 1);
+       return 0;
+}
+
+static struct nxt6000_config vp3021_alps_tded4_config = {
+       .demod_address = 0x0a,
+       .clock_inversion = 1,
+};
+
+static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
+{
+       static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+       static u8 mt352_reset [] = { 0x50, 0x80 };
+       static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
+       static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+       mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
+       mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+       return 0;
+}
+
+static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend *fe,  u8 *pllbuf, int buf_len)
+{
+       u32 div;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       if (buf_len < 5)
+               return -EINVAL;
+
+       div = (((c->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+       pllbuf[0] = 0x61;
+       pllbuf[1] = (div >> 8) & 0x7F;
+       pllbuf[2] = div & 0xFF;
+       pllbuf[3] = 0x85;
+
+       dprintk("frequency %u, div %u\n", c->frequency, div);
+
+       if (c->frequency < 470000000)
+               pllbuf[4] = 0x02;
+       else if (c->frequency > 823000000)
+               pllbuf[4] = 0x88;
+       else
+               pllbuf[4] = 0x08;
+
+       if (c->bandwidth_hz == 8000000)
+               pllbuf[4] |= 0x04;
+
+       return 5;
+}
+
+static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
+{
+       /*
+        * Reset the frontend, must be called before trying
+        * to initialise the MT352 or mt352_attach
+        * will fail. Same goes for the nxt6000 frontend.
+        *
+        */
+
+       int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
+       if (ret != 0)
+               printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
+
+       /* Pulse the reset line */
+       bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+       bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low  */
+       msleep(100);
+
+       bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+}
+
+static struct mt352_config digitv_alps_tded4_config = {
+       .demod_address = 0x0a,
+       .demod_init = digitv_alps_tded4_demod_init,
+};
+
+static struct lgdt330x_config tdvs_tua6034_config = {
+       .demod_address    = 0x0e,
+       .demod_chip       = LGDT3303,
+       .serial_mpeg      = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
+};
+
+static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
+{
+       /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
+
+       /* Pulse the reset line */
+       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
+       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low  */
+       msleep(100);
+
+       bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
+       msleep(100);
+}
+
+static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
+{
+       struct dst_state* state = NULL;
+
+       switch(type) {
+       case BTTV_BOARD_DVICO_DVBT_LITE:
+               card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
+
+               if (card->fe == NULL)
+                       card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
+                                                 card->i2c_adapter);
+
+               if (card->fe != NULL) {
+                       card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs;
+                       card->fe->ops.info.frequency_min = 174000000;
+                       card->fe->ops.info.frequency_max = 862000000;
+               }
+               break;
+
+       case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
+               lgdt330x_reset(card);
+               card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
+               if (card->fe != NULL) {
+                       dvb_attach(simple_tuner_attach, card->fe,
+                                  card->i2c_adapter, 0x61,
+                                  TUNER_LG_TDVS_H06XF);
+                       dprintk ("dvb_bt8xx: lgdt330x detected\n");
+               }
+               break;
+
+       case BTTV_BOARD_NEBULA_DIGITV:
+               /*
+                * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
+                * this would be a cleaner solution than trying each frontend in turn.
+                */
+
+               /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
+               digitv_alps_tded4_reset(card);
+               card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
+               if (card->fe != NULL) {
+                       card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
+                       dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
+                       break;
+               }
+
+               /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
+               digitv_alps_tded4_reset(card);
+               card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
+
+               if (card->fe != NULL) {
+                       card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
+                       dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
+               }
+               break;
+
+       case BTTV_BOARD_AVDVBT_761:
+               card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
+               if (card->fe) {
+                       card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
+               }
+               break;
+
+       case BTTV_BOARD_AVDVBT_771:
+               card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
+               if (card->fe != NULL) {
+                       card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
+                       card->fe->ops.info.frequency_min = 174000000;
+                       card->fe->ops.info.frequency_max = 862000000;
+               }
+               break;
+
+       case BTTV_BOARD_TWINHAN_DST:
+               /*      DST is not a frontend driver !!!                */
+               state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
+               if (!state) {
+                       pr_err("No memory\n");
+                       break;
+               }
+               /*      Setup the Card                                  */
+               state->config = &dst_config;
+               state->i2c = card->i2c_adapter;
+               state->bt = card->bt;
+               state->dst_ca = NULL;
+               /*      DST is not a frontend, attaching the ASIC       */
+               if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
+                       pr_err("%s: Could not find a Twinhan DST\n", __func__);
+                       break;
+               }
+               /*      Attach other DST peripherals if any             */
+               /*      Conditional Access device                       */
+               card->fe = &state->frontend;
+               if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+                       dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
+               break;
+
+       case BTTV_BOARD_PINNACLESAT:
+               card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
+               if (card->fe) {
+                       card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
+                       card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
+                       card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params;
+               }
+               break;
+
+       case BTTV_BOARD_PC_HDTV:
+               card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
+               if (card->fe != NULL)
+                       dvb_attach(simple_tuner_attach, card->fe,
+                                  card->i2c_adapter, 0x61,
+                                  TUNER_PHILIPS_FCV1236D);
+               break;
+       }
+
+       if (card->fe == NULL)
+               pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      card->bt->dev->vendor,
+                      card->bt->dev->device,
+                      card->bt->dev->subsystem_vendor,
+                      card->bt->dev->subsystem_device);
+       else
+               if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
+                       pr_err("Frontend registration failed!\n");
+                       dvb_frontend_detach(card->fe);
+                       card->fe = NULL;
+               }
+}
+
+static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
+{
+       int result;
+
+       result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
+                                     THIS_MODULE, &card->bt->dev->dev,
+                                     adapter_nr);
+       if (result < 0) {
+               pr_err("dvb_register_adapter failed (errno = %d)\n", result);
+               return result;
+       }
+       card->dvb_adapter.priv = card;
+
+       card->bt->adapter = card->i2c_adapter;
+
+       memset(&card->demux, 0, sizeof(struct dvb_demux));
+
+       card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
+
+       card->demux.priv = card;
+       card->demux.filternum = 256;
+       card->demux.feednum = 256;
+       card->demux.start_feed = dvb_bt8xx_start_feed;
+       card->demux.stop_feed = dvb_bt8xx_stop_feed;
+       card->demux.write_to_decoder = NULL;
+
+       result = dvb_dmx_init(&card->demux);
+       if (result < 0) {
+               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
+               goto err_unregister_adaptor;
+       }
+
+       card->dmxdev.filternum = 256;
+       card->dmxdev.demux = &card->demux.dmx;
+       card->dmxdev.capabilities = 0;
+
+       result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter);
+       if (result < 0) {
+               pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
+               goto err_dmx_release;
+       }
+
+       card->fe_hw.source = DMX_FRONTEND_0;
+
+       result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw);
+       if (result < 0) {
+               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
+               goto err_dmxdev_release;
+       }
+
+       card->fe_mem.source = DMX_MEMORY_FE;
+
+       result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem);
+       if (result < 0) {
+               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
+               goto err_remove_hw_frontend;
+       }
+
+       result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw);
+       if (result < 0) {
+               pr_err("dvb_dmx_init failed (errno = %d)\n", result);
+               goto err_remove_mem_frontend;
+       }
+
+       result = dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
+       if (result < 0) {
+               pr_err("dvb_net_init failed (errno = %d)\n", result);
+               goto err_disconnect_frontend;
+       }
+
+       tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
+
+       frontend_init(card, type);
+
+       return 0;
+
+err_disconnect_frontend:
+       card->demux.dmx.disconnect_frontend(&card->demux.dmx);
+err_remove_mem_frontend:
+       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
+err_remove_hw_frontend:
+       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
+err_dmxdev_release:
+       dvb_dmxdev_release(&card->dmxdev);
+err_dmx_release:
+       dvb_dmx_release(&card->demux);
+err_unregister_adaptor:
+       dvb_unregister_adapter(&card->dvb_adapter);
+       return result;
+}
+
+static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
+{
+       struct dvb_bt8xx_card *card;
+       struct pci_dev* bttv_pci_dev;
+       int ret;
+
+       if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
+               return -ENOMEM;
+
+       mutex_init(&card->lock);
+       card->bttv_nr = sub->core->nr;
+       strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
+       card->i2c_adapter = &sub->core->i2c_adap;
+
+       switch(sub->core->type) {
+       case BTTV_BOARD_PINNACLESAT:
+               card->gpio_mode = 0x0400c060;
+               /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
+                             BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               break;
+
+       case BTTV_BOARD_DVICO_DVBT_LITE:
+               card->gpio_mode = 0x0400C060;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               /* 26, 15, 14, 6, 5
+                * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA
+                * DA_APP(parallel) */
+               break;
+
+       case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
+               card->gpio_mode = 0x0400c060;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               break;
+
+       case BTTV_BOARD_NEBULA_DIGITV:
+       case BTTV_BOARD_AVDVBT_761:
+               card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               /* A_PWRDN DA_SBR DA_APP (high speed serial) */
+               break;
+
+       case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
+               card->gpio_mode = 0x0400402B;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               /* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
+               break;
+
+       case BTTV_BOARD_TWINHAN_DST:
+               card->gpio_mode = 0x2204f2c;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
+                                      BT878_APPERR | BT878_AFBUS;
+               /* 25,21,14,11,10,9,8,3,2 then
+                * 0x33 = 5,4,1,0
+                * A_SEL=SML, DA_MLB, DA_SBR,
+                * DA_SDR=f, fifo trigger = 32 DWORDS
+                * IOM = 0 == audio A/D
+                * DPM = 0 == digital audio mode
+                * == async data parallel port
+                * then 0x33 (13 is set by start_capture)
+                * DA_APP = async data parallel port,
+                * ACAP_EN = 1,
+                * RISC+FIFO ENABLE */
+               break;
+
+       case BTTV_BOARD_PC_HDTV:
+               card->gpio_mode = 0x0100EC7B;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
+               break;
+
+       default:
+               pr_err("Unknown bttv card type: %d\n", sub->core->type);
+               kfree(card);
+               return -ENODEV;
+       }
+
+       dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
+
+       if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
+               pr_err("no pci device for card %d\n", card->bttv_nr);
+               kfree(card);
+               return -ENODEV;
+       }
+
+       if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
+               pr_err("unable to determine DMA core of card %d,\n", card->bttv_nr);
+               pr_err("if you have the ALSA bt87x audio driver installed, try removing it.\n");
+
+               kfree(card);
+               return -ENODEV;
+       }
+
+       mutex_init(&card->bt->gpio_lock);
+       card->bt->bttv_nr = sub->core->nr;
+
+       if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
+               kfree(card);
+               return ret;
+       }
+
+       dev_set_drvdata(&sub->dev, card);
+       return 0;
+}
+
+static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
+{
+       struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev);
+
+       dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
+
+       bt878_stop(card->bt);
+       tasklet_kill(&card->bt->tasklet);
+       dvb_net_release(&card->dvbnet);
+       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
+       card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
+       dvb_dmxdev_release(&card->dmxdev);
+       dvb_dmx_release(&card->demux);
+       if (card->fe) {
+               dvb_unregister_frontend(card->fe);
+               dvb_frontend_detach(card->fe);
+       }
+       dvb_unregister_adapter(&card->dvb_adapter);
+
+       kfree(card);
+}
+
+static struct bttv_sub_driver driver = {
+       .drv = {
+               .name           = "dvb-bt8xx",
+       },
+       .probe          = dvb_bt8xx_probe,
+       .remove         = dvb_bt8xx_remove,
+       /* FIXME:
+        * .shutdown    = dvb_bt8xx_shutdown,
+        * .suspend     = dvb_bt8xx_suspend,
+        * .resume      = dvb_bt8xx_resume,
+        */
+};
+
+static int __init dvb_bt8xx_init(void)
+{
+       return bttv_sub_register(&driver, "dvb");
+}
+
+static void __exit dvb_bt8xx_exit(void)
+{
+       bttv_sub_unregister(&driver);
+}
+
+module_init(dvb_bt8xx_init);
+module_exit(dvb_bt8xx_exit);
+
+MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
+MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.h b/drivers/media/pci/bt8xx/dvb-bt8xx.h
new file mode 100644 (file)
index 0000000..4499ed2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Bt8xx based DVB adapter driver
+ *
+ * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
+ * Copyright (C) 1999-2001 Ralph  Metzler & Marcus Metzler for convergence integrated media GmbH
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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 DVB_BT8XX_H
+#define DVB_BT8XX_H
+
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include "dvbdev.h"
+#include "dvb_net.h"
+#include "bttv.h"
+#include "mt352.h"
+#include "sp887x.h"
+#include "dst_common.h"
+#include "nxt6000.h"
+#include "cx24110.h"
+#include "or51211.h"
+#include "lgdt330x.h"
+#include "zl10353.h"
+#include "tuner-simple.h"
+
+struct dvb_bt8xx_card {
+       struct mutex lock;
+       int nfeeds;
+       char card_name[32];
+       struct dvb_adapter dvb_adapter;
+       struct bt878 *bt;
+       unsigned int bttv_nr;
+       struct dvb_demux demux;
+       struct dmxdev dmxdev;
+       struct dmx_frontend fe_hw;
+       struct dmx_frontend fe_mem;
+       u32 gpio_mode;
+       u32 op_sync_orin;
+       u32 irq_err_ignore;
+       struct i2c_adapter *i2c_adapter;
+       struct dvb_net dvbnet;
+
+       struct dvb_frontend* fe;
+};
+
+#endif /* DVB_BT8XX_H */
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig
new file mode 100644 (file)
index 0000000..d099e1a
--- /dev/null
@@ -0,0 +1,18 @@
+config DVB_DDBRIDGE
+       tristate "Digital Devices bridge support"
+       depends on DVB_CORE && PCI && I2C
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110x if !DVB_FE_CUSTOMISE
+       select DVB_STV090x if !DVB_FE_CUSTOMISE
+       select DVB_DRXK if !DVB_FE_CUSTOMISE
+       select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
+       ---help---
+         Support for cards with the Digital Devices PCI express bridge:
+         - Octopus PCIe Bridge
+         - Octopus mini PCIe Bridge
+         - Octopus LE
+         - DuoFlex S2 Octopus
+         - DuoFlex CT Octopus
+         - cineS2(v6)
+
+         Say Y if you own such a card and want to use it.
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
new file mode 100644 (file)
index 0000000..9d083c9
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the ddbridge device driver
+#
+
+ddbridge-objs := ddbridge-core.o
+
+obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/common/tuners/
+
+# For the staging CI driver cxd2099
+ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
new file mode 100644 (file)
index 0000000..ebf3f05
--- /dev/null
@@ -0,0 +1,1723 @@
+/*
+ * ddbridge.c: Digital Devices PCIe bridge driver
+ *
+ * Copyright (C) 2010-2011 Digital Devices GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/timer.h>
+#include <linux/i2c.h>
+#include <linux/swab.h>
+#include <linux/vmalloc.h>
+#include "ddbridge.h"
+
+#include "ddbridge-regs.h"
+
+#include "tda18271c2dd.h"
+#include "stv6110x.h"
+#include "stv090x.h"
+#include "lnbh24.h"
+#include "drxk.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* MSI had problems with lost interrupts, fixed but needs testing */
+#undef CONFIG_PCI_MSI
+
+/******************************************************************************/
+
+static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
+{
+       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
+                                  .buf  = val,  .len   = 1 } };
+       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
+}
+
+static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
+{
+       struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0,
+                                  .buf  = &reg, .len   = 1 },
+                                 {.addr = adr,  .flags = I2C_M_RD,
+                                  .buf  = val,  .len   = 1 } };
+       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
+}
+
+static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
+                         u16 reg, u8 *val)
+{
+       u8 msg[2] = {reg>>8, reg&0xff};
+       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
+                                  .buf  = msg, .len   = 2},
+                                 {.addr = adr, .flags = I2C_M_RD,
+                                  .buf  = val, .len   = 1} };
+       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
+}
+
+static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
+{
+       struct ddb *dev = i2c->dev;
+       int stat;
+       u32 val;
+
+       i2c->done = 0;
+       ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND);
+       stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ);
+       if (stat <= 0) {
+               printk(KERN_ERR "I2C timeout\n");
+               { /* MSI debugging*/
+                       u32 istat = ddbreadl(INTERRUPT_STATUS);
+                       printk(KERN_ERR "IRS %08x\n", istat);
+                       ddbwritel(istat, INTERRUPT_ACK);
+               }
+               return -EIO;
+       }
+       val = ddbreadl(i2c->regs+I2C_COMMAND);
+       if (val & 0x70000)
+               return -EIO;
+       return 0;
+}
+
+static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
+                              struct i2c_msg msg[], int num)
+{
+       struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter);
+       struct ddb *dev = i2c->dev;
+       u8 addr = 0;
+
+       if (num)
+               addr = msg[0].addr;
+
+       if (num == 2 && msg[1].flags & I2C_M_RD &&
+           !(msg[0].flags & I2C_M_RD)) {
+               memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf,
+                           msg[0].buf, msg[0].len);
+               ddbwritel(msg[0].len|(msg[1].len << 16),
+                         i2c->regs+I2C_TASKLENGTH);
+               if (!ddb_i2c_cmd(i2c, addr, 1)) {
+                       memcpy_fromio(msg[1].buf,
+                                     dev->regs + I2C_TASKMEM_BASE + i2c->rbuf,
+                                     msg[1].len);
+                       return num;
+               }
+       }
+
+       if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
+               ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len);
+               ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH);
+               if (!ddb_i2c_cmd(i2c, addr, 2))
+                       return num;
+       }
+       if (num == 1 && (msg[0].flags & I2C_M_RD)) {
+               ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
+               if (!ddb_i2c_cmd(i2c, addr, 3)) {
+                       ddbcpyfrom(msg[0].buf,
+                                  I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len);
+                       return num;
+               }
+       }
+       return -EIO;
+}
+
+
+static u32 ddb_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_SMBUS_EMUL;
+}
+
+struct i2c_algorithm ddb_i2c_algo = {
+       .master_xfer   = ddb_i2c_master_xfer,
+       .functionality = ddb_i2c_functionality,
+};
+
+static void ddb_i2c_release(struct ddb *dev)
+{
+       int i;
+       struct ddb_i2c *i2c;
+       struct i2c_adapter *adap;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               i2c = &dev->i2c[i];
+               adap = &i2c->adap;
+               i2c_del_adapter(adap);
+       }
+}
+
+static int ddb_i2c_init(struct ddb *dev)
+{
+       int i, j, stat = 0;
+       struct ddb_i2c *i2c;
+       struct i2c_adapter *adap;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               i2c = &dev->i2c[i];
+               i2c->dev = dev;
+               i2c->nr = i;
+               i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4);
+               i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8);
+               i2c->regs = 0x80 + i * 0x20;
+               ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING);
+               ddbwritel((i2c->rbuf << 16) | i2c->wbuf,
+                         i2c->regs + I2C_TASKADDRESS);
+               init_waitqueue_head(&i2c->wq);
+
+               adap = &i2c->adap;
+               i2c_set_adapdata(adap, i2c);
+#ifdef I2C_ADAP_CLASS_TV_DIGITAL
+               adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
+#else
+#ifdef I2C_CLASS_TV_ANALOG
+               adap->class = I2C_CLASS_TV_ANALOG;
+#endif
+#endif
+               strcpy(adap->name, "ddbridge");
+               adap->algo = &ddb_i2c_algo;
+               adap->algo_data = (void *)i2c;
+               adap->dev.parent = &dev->pdev->dev;
+               stat = i2c_add_adapter(adap);
+               if (stat)
+                       break;
+       }
+       if (stat)
+               for (j = 0; j < i; j++) {
+                       i2c = &dev->i2c[j];
+                       adap = &i2c->adap;
+                       i2c_del_adapter(adap);
+               }
+       return stat;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+#if 0
+static void set_table(struct ddb *dev, u32 off,
+                     dma_addr_t *pbuf, u32 num)
+{
+       u32 i, base;
+       u64 mem;
+
+       base = DMA_BASE_ADDRESS_TABLE + off;
+       for (i = 0; i < num; i++) {
+               mem = pbuf[i];
+               ddbwritel(mem & 0xffffffff, base + i * 8);
+               ddbwritel(mem >> 32, base + i * 8 + 4);
+       }
+}
+#endif
+
+static void ddb_address_table(struct ddb *dev)
+{
+       u32 i, j, base;
+       u64 mem;
+       dma_addr_t *pbuf;
+
+       for (i = 0; i < dev->info->port_num * 2; i++) {
+               base = DMA_BASE_ADDRESS_TABLE + i * 0x100;
+               pbuf = dev->input[i].pbuf;
+               for (j = 0; j < dev->input[i].dma_buf_num; j++) {
+                       mem = pbuf[j];
+                       ddbwritel(mem & 0xffffffff, base + j * 8);
+                       ddbwritel(mem >> 32, base + j * 8 + 4);
+               }
+       }
+       for (i = 0; i < dev->info->port_num; i++) {
+               base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100;
+               pbuf = dev->output[i].pbuf;
+               for (j = 0; j < dev->output[i].dma_buf_num; j++) {
+                       mem = pbuf[j];
+                       ddbwritel(mem & 0xffffffff, base + j * 8);
+                       ddbwritel(mem >> 32, base + j * 8 + 4);
+               }
+       }
+}
+
+static void io_free(struct pci_dev *pdev, u8 **vbuf,
+                   dma_addr_t *pbuf, u32 size, int num)
+{
+       int i;
+
+       for (i = 0; i < num; i++) {
+               if (vbuf[i]) {
+                       pci_free_consistent(pdev, size, vbuf[i], pbuf[i]);
+                       vbuf[i] = 0;
+               }
+       }
+}
+
+static int io_alloc(struct pci_dev *pdev, u8 **vbuf,
+                   dma_addr_t *pbuf, u32 size, int num)
+{
+       int i;
+
+       for (i = 0; i < num; i++) {
+               vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]);
+               if (!vbuf[i])
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+static int ddb_buffers_alloc(struct ddb *dev)
+{
+       int i;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               switch (port->class) {
+               case DDB_PORT_TUNER:
+                       if (io_alloc(dev->pdev, port->input[0]->vbuf,
+                                    port->input[0]->pbuf,
+                                    port->input[0]->dma_buf_size,
+                                    port->input[0]->dma_buf_num) < 0)
+                               return -1;
+                       if (io_alloc(dev->pdev, port->input[1]->vbuf,
+                                    port->input[1]->pbuf,
+                                    port->input[1]->dma_buf_size,
+                                    port->input[1]->dma_buf_num) < 0)
+                               return -1;
+                       break;
+               case DDB_PORT_CI:
+                       if (io_alloc(dev->pdev, port->input[0]->vbuf,
+                                    port->input[0]->pbuf,
+                                    port->input[0]->dma_buf_size,
+                                    port->input[0]->dma_buf_num) < 0)
+                               return -1;
+                       if (io_alloc(dev->pdev, port->output->vbuf,
+                                    port->output->pbuf,
+                                    port->output->dma_buf_size,
+                                    port->output->dma_buf_num) < 0)
+                               return -1;
+                       break;
+               default:
+                       break;
+               }
+       }
+       ddb_address_table(dev);
+       return 0;
+}
+
+static void ddb_buffers_free(struct ddb *dev)
+{
+       int i;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               io_free(dev->pdev, port->input[0]->vbuf,
+                       port->input[0]->pbuf,
+                       port->input[0]->dma_buf_size,
+                       port->input[0]->dma_buf_num);
+               io_free(dev->pdev, port->input[1]->vbuf,
+                       port->input[1]->pbuf,
+                       port->input[1]->dma_buf_size,
+                       port->input[1]->dma_buf_num);
+               io_free(dev->pdev, port->output->vbuf,
+                       port->output->pbuf,
+                       port->output->dma_buf_size,
+                       port->output->dma_buf_num);
+       }
+}
+
+static void ddb_input_start(struct ddb_input *input)
+{
+       struct ddb *dev = input->port->dev;
+
+       spin_lock_irq(&input->lock);
+       input->cbuf = 0;
+       input->coff = 0;
+
+       /* reset */
+       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
+       ddbwritel(2, TS_INPUT_CONTROL(input->nr));
+       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
+
+       ddbwritel((1 << 16) |
+                 (input->dma_buf_num << 11) |
+                 (input->dma_buf_size >> 7),
+                 DMA_BUFFER_SIZE(input->nr));
+       ddbwritel(0, DMA_BUFFER_ACK(input->nr));
+
+       ddbwritel(1, DMA_BASE_WRITE);
+       ddbwritel(3, DMA_BUFFER_CONTROL(input->nr));
+       ddbwritel(9, TS_INPUT_CONTROL(input->nr));
+       input->running = 1;
+       spin_unlock_irq(&input->lock);
+}
+
+static void ddb_input_stop(struct ddb_input *input)
+{
+       struct ddb *dev = input->port->dev;
+
+       spin_lock_irq(&input->lock);
+       ddbwritel(0, TS_INPUT_CONTROL(input->nr));
+       ddbwritel(0, DMA_BUFFER_CONTROL(input->nr));
+       input->running = 0;
+       spin_unlock_irq(&input->lock);
+}
+
+static void ddb_output_start(struct ddb_output *output)
+{
+       struct ddb *dev = output->port->dev;
+
+       spin_lock_irq(&output->lock);
+       output->cbuf = 0;
+       output->coff = 0;
+       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
+       ddbwritel(2, TS_OUTPUT_CONTROL(output->nr));
+       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
+       ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr));
+       ddbwritel((1 << 16) |
+                 (output->dma_buf_num << 11) |
+                 (output->dma_buf_size >> 7),
+                 DMA_BUFFER_SIZE(output->nr + 8));
+       ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8));
+
+       ddbwritel(1, DMA_BASE_READ);
+       ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8));
+       /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */
+       ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr));
+       output->running = 1;
+       spin_unlock_irq(&output->lock);
+}
+
+static void ddb_output_stop(struct ddb_output *output)
+{
+       struct ddb *dev = output->port->dev;
+
+       spin_lock_irq(&output->lock);
+       ddbwritel(0, TS_OUTPUT_CONTROL(output->nr));
+       ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8));
+       output->running = 0;
+       spin_unlock_irq(&output->lock);
+}
+
+static u32 ddb_output_free(struct ddb_output *output)
+{
+       u32 idx, off, stat = output->stat;
+       s32 diff;
+
+       idx = (stat >> 11) & 0x1f;
+       off = (stat & 0x7ff) << 7;
+
+       if (output->cbuf != idx) {
+               if ((((output->cbuf + 1) % output->dma_buf_num) == idx) &&
+                   (output->dma_buf_size - output->coff <= 188))
+                       return 0;
+               return 188;
+       }
+       diff = off - output->coff;
+       if (diff <= 0 || diff > 188)
+               return 188;
+       return 0;
+}
+
+static ssize_t ddb_output_write(struct ddb_output *output,
+                               const u8 *buf, size_t count)
+{
+       struct ddb *dev = output->port->dev;
+       u32 idx, off, stat = output->stat;
+       u32 left = count, len;
+
+       idx = (stat >> 11) & 0x1f;
+       off = (stat & 0x7ff) << 7;
+
+       while (left) {
+               len = output->dma_buf_size - output->coff;
+               if ((((output->cbuf + 1) % output->dma_buf_num) == idx) &&
+                   (off == 0)) {
+                       if (len <= 188)
+                               break;
+                       len -= 188;
+               }
+               if (output->cbuf == idx) {
+                       if (off > output->coff) {
+#if 1
+                               len = off - output->coff;
+                               len -= (len % 188);
+                               if (len <= 188)
+
+#endif
+                                       break;
+                               len -= 188;
+                       }
+               }
+               if (len > left)
+                       len = left;
+               if (copy_from_user(output->vbuf[output->cbuf] + output->coff,
+                                  buf, len))
+                       return -EIO;
+               left -= len;
+               buf += len;
+               output->coff += len;
+               if (output->coff == output->dma_buf_size) {
+                       output->coff = 0;
+                       output->cbuf = ((output->cbuf + 1) % output->dma_buf_num);
+               }
+               ddbwritel((output->cbuf << 11) | (output->coff >> 7),
+                         DMA_BUFFER_ACK(output->nr + 8));
+       }
+       return count - left;
+}
+
+static u32 ddb_input_avail(struct ddb_input *input)
+{
+       struct ddb *dev = input->port->dev;
+       u32 idx, off, stat = input->stat;
+       u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr));
+
+       idx = (stat >> 11) & 0x1f;
+       off = (stat & 0x7ff) << 7;
+
+       if (ctrl & 4) {
+               printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl);
+               ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr));
+               return 0;
+       }
+       if (input->cbuf != idx)
+               return 188;
+       return 0;
+}
+
+static ssize_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count)
+{
+       struct ddb *dev = input->port->dev;
+       u32 left = count;
+       u32 idx, free, stat = input->stat;
+       int ret;
+
+       idx = (stat >> 11) & 0x1f;
+
+       while (left) {
+               if (input->cbuf == idx)
+                       return count - left;
+               free = input->dma_buf_size - input->coff;
+               if (free > left)
+                       free = left;
+               ret = copy_to_user(buf, input->vbuf[input->cbuf] +
+                                  input->coff, free);
+               if (ret)
+                       return -EFAULT;
+               input->coff += free;
+               if (input->coff == input->dma_buf_size) {
+                       input->coff = 0;
+                       input->cbuf = (input->cbuf+1) % input->dma_buf_num;
+               }
+               left -= free;
+               ddbwritel((input->cbuf << 11) | (input->coff >> 7),
+                         DMA_BUFFER_ACK(input->nr));
+       }
+       return count;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+#if 0
+static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe)
+{
+       int i;
+
+       for (i = 0; i < dev->info->port_num * 2; i++) {
+               if (dev->input[i].fe == fe)
+                       return &dev->input[i];
+       }
+       return NULL;
+}
+#endif
+
+static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct ddb_input *input = fe->sec_priv;
+       struct ddb_port *port = input->port;
+       int status;
+
+       if (enable) {
+               mutex_lock(&port->i2c_gate_lock);
+               status = input->gate_ctrl(fe, 1);
+       } else {
+               status = input->gate_ctrl(fe, 0);
+               mutex_unlock(&port->i2c_gate_lock);
+       }
+       return status;
+}
+
+static int demod_attach_drxk(struct ddb_input *input)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct dvb_frontend *fe;
+       struct drxk_config config;
+
+       memset(&config, 0, sizeof(config));
+       config.microcode_name = "drxk_a3.mc";
+       config.qam_demod_parameter_count = 4;
+       config.adr = 0x29 + (input->nr & 1);
+
+       fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
+       if (!input->fe) {
+               printk(KERN_ERR "No DRXK found!\n");
+               return -ENODEV;
+       }
+       fe->sec_priv = input;
+       input->gate_ctrl = fe->ops.i2c_gate_ctrl;
+       fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+       return 0;
+}
+
+static int tuner_attach_tda18271(struct ddb_input *input)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct dvb_frontend *fe;
+
+       if (input->fe->ops.i2c_gate_ctrl)
+               input->fe->ops.i2c_gate_ctrl(input->fe, 1);
+       fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60);
+       if (!fe) {
+               printk(KERN_ERR "No TDA18271 found!\n");
+               return -ENODEV;
+       }
+       if (input->fe->ops.i2c_gate_ctrl)
+               input->fe->ops.i2c_gate_ctrl(input->fe, 0);
+       return 0;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+static struct stv090x_config stv0900 = {
+       .device         = STV0900,
+       .demod_mode     = STV090x_DUAL,
+       .clk_mode       = STV090x_CLK_EXT,
+
+       .xtal           = 27000000,
+       .address        = 0x69,
+
+       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+
+       .repeater_level = STV090x_RPTLEVEL_16,
+
+       .adc1_range     = STV090x_ADC_1Vpp,
+       .adc2_range     = STV090x_ADC_1Vpp,
+
+       .diseqc_envelope_mode = true,
+};
+
+static struct stv090x_config stv0900_aa = {
+       .device         = STV0900,
+       .demod_mode     = STV090x_DUAL,
+       .clk_mode       = STV090x_CLK_EXT,
+
+       .xtal           = 27000000,
+       .address        = 0x68,
+
+       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+
+       .repeater_level = STV090x_RPTLEVEL_16,
+
+       .adc1_range     = STV090x_ADC_1Vpp,
+       .adc2_range     = STV090x_ADC_1Vpp,
+
+       .diseqc_envelope_mode = true,
+};
+
+static struct stv6110x_config stv6110a = {
+       .addr    = 0x60,
+       .refclk  = 27000000,
+       .clk_div = 1,
+};
+
+static struct stv6110x_config stv6110b = {
+       .addr    = 0x63,
+       .refclk  = 27000000,
+       .clk_div = 1,
+};
+
+static int demod_attach_stv0900(struct ddb_input *input, int type)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
+
+       input->fe = dvb_attach(stv090x_attach, feconf, i2c,
+                              (input->nr & 1) ? STV090x_DEMODULATOR_1
+                              : STV090x_DEMODULATOR_0);
+       if (!input->fe) {
+               printk(KERN_ERR "No STV0900 found!\n");
+               return -ENODEV;
+       }
+       if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0,
+                       0, (input->nr & 1) ?
+                       (0x09 - type) : (0x0b - type))) {
+               printk(KERN_ERR "No LNBH24 found!\n");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static int tuner_attach_stv6110(struct ddb_input *input, int type)
+{
+       struct i2c_adapter *i2c = &input->port->i2c->adap;
+       struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
+       struct stv6110x_config *tunerconf = (input->nr & 1) ?
+               &stv6110b : &stv6110a;
+       struct stv6110x_devctl *ctl;
+
+       ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c);
+       if (!ctl) {
+               printk(KERN_ERR "No STV6110X found!\n");
+               return -ENODEV;
+       }
+       printk(KERN_INFO "attach tuner input %d adr %02x\n",
+                        input->nr, tunerconf->addr);
+
+       feconf->tuner_init          = ctl->tuner_init;
+       feconf->tuner_sleep         = ctl->tuner_sleep;
+       feconf->tuner_set_mode      = ctl->tuner_set_mode;
+       feconf->tuner_set_frequency = ctl->tuner_set_frequency;
+       feconf->tuner_get_frequency = ctl->tuner_get_frequency;
+       feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+       feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+       feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
+       feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
+       feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
+       feconf->tuner_get_status    = ctl->tuner_get_status;
+
+       return 0;
+}
+
+static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
+                           int (*start_feed)(struct dvb_demux_feed *),
+                           int (*stop_feed)(struct dvb_demux_feed *),
+                           void *priv)
+{
+       dvbdemux->priv = priv;
+
+       dvbdemux->filternum = 256;
+       dvbdemux->feednum = 256;
+       dvbdemux->start_feed = start_feed;
+       dvbdemux->stop_feed = stop_feed;
+       dvbdemux->write_to_decoder = NULL;
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+                                     DMX_SECTION_FILTERING |
+                                     DMX_MEMORY_BASED_FILTERING);
+       return dvb_dmx_init(dvbdemux);
+}
+
+static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
+                              struct dvb_demux *dvbdemux,
+                              struct dmx_frontend *hw_frontend,
+                              struct dmx_frontend *mem_frontend,
+                              struct dvb_adapter *dvb_adapter)
+{
+       int ret;
+
+       dmxdev->filternum = 256;
+       dmxdev->demux = &dvbdemux->dmx;
+       dmxdev->capabilities = 0;
+       ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
+       if (ret < 0)
+               return ret;
+
+       hw_frontend->source = DMX_FRONTEND_0;
+       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
+       mem_frontend->source = DMX_MEMORY_FE;
+       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
+       return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
+}
+
+static int start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct ddb_input *input = dvbdmx->priv;
+
+       if (!input->users)
+               ddb_input_start(input);
+
+       return ++input->users;
+}
+
+static int stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct ddb_input *input = dvbdmx->priv;
+
+       if (--input->users)
+               return input->users;
+
+       ddb_input_stop(input);
+       return 0;
+}
+
+
+static void dvb_input_detach(struct ddb_input *input)
+{
+       struct dvb_adapter *adap = &input->adap;
+       struct dvb_demux *dvbdemux = &input->demux;
+
+       switch (input->attached) {
+       case 5:
+               if (input->fe2)
+                       dvb_unregister_frontend(input->fe2);
+               if (input->fe) {
+                       dvb_unregister_frontend(input->fe);
+                       dvb_frontend_detach(input->fe);
+                       input->fe = NULL;
+               }
+       case 4:
+               dvb_net_release(&input->dvbnet);
+
+       case 3:
+               dvbdemux->dmx.close(&dvbdemux->dmx);
+               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+                                             &input->hw_frontend);
+               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+                                             &input->mem_frontend);
+               dvb_dmxdev_release(&input->dmxdev);
+
+       case 2:
+               dvb_dmx_release(&input->demux);
+
+       case 1:
+               dvb_unregister_adapter(adap);
+       }
+       input->attached = 0;
+}
+
+static int dvb_input_attach(struct ddb_input *input)
+{
+       int ret;
+       struct ddb_port *port = input->port;
+       struct dvb_adapter *adap = &input->adap;
+       struct dvb_demux *dvbdemux = &input->demux;
+
+       ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE,
+                                  &input->port->dev->pdev->dev,
+                                  adapter_nr);
+       if (ret < 0) {
+               printk(KERN_ERR "ddbridge: Could not register adapter."
+                      "Check if you enabled enough adapters in dvb-core!\n");
+               return ret;
+       }
+       input->attached = 1;
+
+       ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
+                                     start_feed,
+                                     stop_feed, input);
+       if (ret < 0)
+               return ret;
+       input->attached = 2;
+
+       ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux,
+                                        &input->hw_frontend,
+                                        &input->mem_frontend, adap);
+       if (ret < 0)
+               return ret;
+       input->attached = 3;
+
+       ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux);
+       if (ret < 0)
+               return ret;
+       input->attached = 4;
+
+       input->fe = 0;
+       switch (port->type) {
+       case DDB_TUNER_DVBS_ST:
+               if (demod_attach_stv0900(input, 0) < 0)
+                       return -ENODEV;
+               if (tuner_attach_stv6110(input, 0) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               break;
+       case DDB_TUNER_DVBS_ST_AA:
+               if (demod_attach_stv0900(input, 1) < 0)
+                       return -ENODEV;
+               if (tuner_attach_stv6110(input, 1) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               break;
+       case DDB_TUNER_DVBCT_TR:
+               if (demod_attach_drxk(input) < 0)
+                       return -ENODEV;
+               if (tuner_attach_tda18271(input) < 0)
+                       return -ENODEV;
+               if (input->fe) {
+                       if (dvb_register_frontend(adap, input->fe) < 0)
+                               return -ENODEV;
+               }
+               if (input->fe2) {
+                       if (dvb_register_frontend(adap, input->fe2) < 0)
+                               return -ENODEV;
+                       input->fe2->tuner_priv = input->fe->tuner_priv;
+                       memcpy(&input->fe2->ops.tuner_ops,
+                              &input->fe->ops.tuner_ops,
+                              sizeof(struct dvb_tuner_ops));
+               }
+               break;
+       }
+       input->attached = 5;
+       return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+
+static ssize_t ts_write(struct file *file, const char *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct ddb_output *output = dvbdev->priv;
+       size_t left = count;
+       int stat;
+
+       while (left) {
+               if (ddb_output_free(output) < 188) {
+                       if (file->f_flags & O_NONBLOCK)
+                               break;
+                       if (wait_event_interruptible(
+                                   output->wq, ddb_output_free(output) >= 188) < 0)
+                               break;
+               }
+               stat = ddb_output_write(output, buf, left);
+               if (stat < 0)
+                       break;
+               buf += stat;
+               left -= stat;
+       }
+       return (left == count) ? -EAGAIN : (count - left);
+}
+
+static ssize_t ts_read(struct file *file, char *buf,
+                      size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct ddb_output *output = dvbdev->priv;
+       struct ddb_input *input = output->port->input[0];
+       int left, read;
+
+       count -= count % 188;
+       left = count;
+       while (left) {
+               if (ddb_input_avail(input) < 188) {
+                       if (file->f_flags & O_NONBLOCK)
+                               break;
+                       if (wait_event_interruptible(
+                                   input->wq, ddb_input_avail(input) >= 188) < 0)
+                               break;
+               }
+               read = ddb_input_read(input, buf, left);
+               if (read < 0)
+                       return read;
+               left -= read;
+               buf += read;
+       }
+       return (left == count) ? -EAGAIN : (count - left);
+}
+
+static unsigned int ts_poll(struct file *file, poll_table *wait)
+{
+       /*
+       struct dvb_device *dvbdev = file->private_data;
+       struct ddb_output *output = dvbdev->priv;
+       struct ddb_input *input = output->port->input[0];
+       */
+       unsigned int mask = 0;
+
+#if 0
+       if (data_avail_to_read)
+               mask |= POLLIN | POLLRDNORM;
+       if (data_avail_to_write)
+               mask |= POLLOUT | POLLWRNORM;
+
+       poll_wait(file, &read_queue, wait);
+       poll_wait(file, &write_queue, wait);
+#endif
+       return mask;
+}
+
+static const struct file_operations ci_fops = {
+       .owner   = THIS_MODULE,
+       .read    = ts_read,
+       .write   = ts_write,
+       .open    = dvb_generic_open,
+       .release = dvb_generic_release,
+       .poll    = ts_poll,
+       .mmap    = 0,
+};
+
+static struct dvb_device dvbdev_ci = {
+       .priv    = 0,
+       .readers = -1,
+       .writers = -1,
+       .users   = -1,
+       .fops    = &ci_fops,
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static void input_tasklet(unsigned long data)
+{
+       struct ddb_input *input = (struct ddb_input *) data;
+       struct ddb *dev = input->port->dev;
+
+       spin_lock(&input->lock);
+       if (!input->running) {
+               spin_unlock(&input->lock);
+               return;
+       }
+       input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr));
+
+       if (input->port->class == DDB_PORT_TUNER) {
+               if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))
+                       printk(KERN_ERR "Overflow input %d\n", input->nr);
+               while (input->cbuf != ((input->stat >> 11) & 0x1f)
+                      || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) {
+                       dvb_dmx_swfilter_packets(&input->demux,
+                                                input->vbuf[input->cbuf],
+                                                input->dma_buf_size / 188);
+
+                       input->cbuf = (input->cbuf + 1) % input->dma_buf_num;
+                       ddbwritel((input->cbuf << 11),
+                                 DMA_BUFFER_ACK(input->nr));
+                       input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr));
+                      }
+       }
+       if (input->port->class == DDB_PORT_CI)
+               wake_up(&input->wq);
+       spin_unlock(&input->lock);
+}
+
+static void output_tasklet(unsigned long data)
+{
+       struct ddb_output *output = (struct ddb_output *) data;
+       struct ddb *dev = output->port->dev;
+
+       spin_lock(&output->lock);
+       if (!output->running) {
+               spin_unlock(&output->lock);
+               return;
+       }
+       output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8));
+       wake_up(&output->wq);
+       spin_unlock(&output->lock);
+}
+
+
+struct cxd2099_cfg cxd_cfg = {
+       .bitrate =  62000,
+       .adr     =  0x40,
+       .polarity = 1,
+       .clock_mode = 1,
+};
+
+static int ddb_ci_attach(struct ddb_port *port)
+{
+       int ret;
+
+       ret = dvb_register_adapter(&port->output->adap,
+                                  "DDBridge",
+                                  THIS_MODULE,
+                                  &port->dev->pdev->dev,
+                                  adapter_nr);
+       if (ret < 0)
+               return ret;
+       port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
+       if (!port->en) {
+               dvb_unregister_adapter(&port->output->adap);
+               return -ENODEV;
+       }
+       ddb_input_start(port->input[0]);
+       ddb_output_start(port->output);
+       dvb_ca_en50221_init(&port->output->adap,
+                           port->en, 0, 1);
+       ret = dvb_register_device(&port->output->adap, &port->output->dev,
+                                 &dvbdev_ci, (void *) port->output,
+                                 DVB_DEVICE_SEC);
+       return ret;
+}
+
+static int ddb_port_attach(struct ddb_port *port)
+{
+       int ret = 0;
+
+       switch (port->class) {
+       case DDB_PORT_TUNER:
+               ret = dvb_input_attach(port->input[0]);
+               if (ret < 0)
+                       break;
+               ret = dvb_input_attach(port->input[1]);
+               break;
+       case DDB_PORT_CI:
+               ret = ddb_ci_attach(port);
+               break;
+       default:
+               break;
+       }
+       if (ret < 0)
+               printk(KERN_ERR "port_attach on port %d failed\n", port->nr);
+       return ret;
+}
+
+static int ddb_ports_attach(struct ddb *dev)
+{
+       int i, ret = 0;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               ret = ddb_port_attach(port);
+               if (ret < 0)
+                       break;
+       }
+       return ret;
+}
+
+static void ddb_ports_detach(struct ddb *dev)
+{
+       int i;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               switch (port->class) {
+               case DDB_PORT_TUNER:
+                       dvb_input_detach(port->input[0]);
+                       dvb_input_detach(port->input[1]);
+                       break;
+               case DDB_PORT_CI:
+                       if (port->output->dev)
+                               dvb_unregister_device(port->output->dev);
+                       if (port->en) {
+                               ddb_input_stop(port->input[0]);
+                               ddb_output_stop(port->output);
+                               dvb_ca_en50221_release(port->en);
+                               kfree(port->en);
+                               port->en = 0;
+                               dvb_unregister_adapter(&port->output->adap);
+                       }
+                       break;
+               }
+       }
+}
+
+/****************************************************************************/
+/****************************************************************************/
+
+static int port_has_ci(struct ddb_port *port)
+{
+       u8 val;
+       return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1;
+}
+
+static int port_has_stv0900(struct ddb_port *port)
+{
+       u8 val;
+       if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0)
+               return 0;
+       return 1;
+}
+
+static int port_has_stv0900_aa(struct ddb_port *port)
+{
+       u8 val;
+       if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0)
+               return 0;
+       return 1;
+}
+
+static int port_has_drxks(struct ddb_port *port)
+{
+       u8 val;
+       if (i2c_read(&port->i2c->adap, 0x29, &val) < 0)
+               return 0;
+       if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0)
+               return 0;
+       return 1;
+}
+
+static void ddb_port_probe(struct ddb_port *port)
+{
+       struct ddb *dev = port->dev;
+       char *modname = "NO MODULE";
+
+       port->class = DDB_PORT_NONE;
+
+       if (port_has_ci(port)) {
+               modname = "CI";
+               port->class = DDB_PORT_CI;
+               ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+       } else if (port_has_stv0900(port)) {
+               modname = "DUAL DVB-S2";
+               port->class = DDB_PORT_TUNER;
+               port->type = DDB_TUNER_DVBS_ST;
+               ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
+       } else if (port_has_stv0900_aa(port)) {
+               modname = "DUAL DVB-S2";
+               port->class = DDB_PORT_TUNER;
+               port->type = DDB_TUNER_DVBS_ST_AA;
+               ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
+       } else if (port_has_drxks(port)) {
+               modname = "DUAL DVB-C/T";
+               port->class = DDB_PORT_TUNER;
+               port->type = DDB_TUNER_DVBCT_TR;
+               ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+       }
+       printk(KERN_INFO "Port %d (TAB %d): %s\n",
+                        port->nr, port->nr+1, modname);
+}
+
+static void ddb_input_init(struct ddb_port *port, int nr)
+{
+       struct ddb *dev = port->dev;
+       struct ddb_input *input = &dev->input[nr];
+
+       input->nr = nr;
+       input->port = port;
+       input->dma_buf_num = INPUT_DMA_BUFS;
+       input->dma_buf_size = INPUT_DMA_SIZE;
+       ddbwritel(0, TS_INPUT_CONTROL(nr));
+       ddbwritel(2, TS_INPUT_CONTROL(nr));
+       ddbwritel(0, TS_INPUT_CONTROL(nr));
+       ddbwritel(0, DMA_BUFFER_ACK(nr));
+       tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input);
+       spin_lock_init(&input->lock);
+       init_waitqueue_head(&input->wq);
+}
+
+static void ddb_output_init(struct ddb_port *port, int nr)
+{
+       struct ddb *dev = port->dev;
+       struct ddb_output *output = &dev->output[nr];
+       output->nr = nr;
+       output->port = port;
+       output->dma_buf_num = OUTPUT_DMA_BUFS;
+       output->dma_buf_size = OUTPUT_DMA_SIZE;
+
+       ddbwritel(0, TS_OUTPUT_CONTROL(nr));
+       ddbwritel(2, TS_OUTPUT_CONTROL(nr));
+       ddbwritel(0, TS_OUTPUT_CONTROL(nr));
+       tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output);
+       init_waitqueue_head(&output->wq);
+}
+
+static void ddb_ports_init(struct ddb *dev)
+{
+       int i;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               port->dev = dev;
+               port->nr = i;
+               port->i2c = &dev->i2c[i];
+               port->input[0] = &dev->input[2 * i];
+               port->input[1] = &dev->input[2 * i + 1];
+               port->output = &dev->output[i];
+
+               mutex_init(&port->i2c_gate_lock);
+               ddb_port_probe(port);
+               ddb_input_init(port, 2 * i);
+               ddb_input_init(port, 2 * i + 1);
+               ddb_output_init(port, i);
+       }
+}
+
+static void ddb_ports_release(struct ddb *dev)
+{
+       int i;
+       struct ddb_port *port;
+
+       for (i = 0; i < dev->info->port_num; i++) {
+               port = &dev->port[i];
+               port->dev = dev;
+               tasklet_kill(&port->input[0]->tasklet);
+               tasklet_kill(&port->input[1]->tasklet);
+               tasklet_kill(&port->output->tasklet);
+       }
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static void irq_handle_i2c(struct ddb *dev, int n)
+{
+       struct ddb_i2c *i2c = &dev->i2c[n];
+
+       i2c->done = 1;
+       wake_up(&i2c->wq);
+}
+
+static irqreturn_t irq_handler(int irq, void *dev_id)
+{
+       struct ddb *dev = (struct ddb *) dev_id;
+       u32 s = ddbreadl(INTERRUPT_STATUS);
+
+       if (!s)
+               return IRQ_NONE;
+
+       do {
+               ddbwritel(s, INTERRUPT_ACK);
+
+               if (s & 0x00000001)
+                       irq_handle_i2c(dev, 0);
+               if (s & 0x00000002)
+                       irq_handle_i2c(dev, 1);
+               if (s & 0x00000004)
+                       irq_handle_i2c(dev, 2);
+               if (s & 0x00000008)
+                       irq_handle_i2c(dev, 3);
+
+               if (s & 0x00000100)
+                       tasklet_schedule(&dev->input[0].tasklet);
+               if (s & 0x00000200)
+                       tasklet_schedule(&dev->input[1].tasklet);
+               if (s & 0x00000400)
+                       tasklet_schedule(&dev->input[2].tasklet);
+               if (s & 0x00000800)
+                       tasklet_schedule(&dev->input[3].tasklet);
+               if (s & 0x00001000)
+                       tasklet_schedule(&dev->input[4].tasklet);
+               if (s & 0x00002000)
+                       tasklet_schedule(&dev->input[5].tasklet);
+               if (s & 0x00004000)
+                       tasklet_schedule(&dev->input[6].tasklet);
+               if (s & 0x00008000)
+                       tasklet_schedule(&dev->input[7].tasklet);
+
+               if (s & 0x00010000)
+                       tasklet_schedule(&dev->output[0].tasklet);
+               if (s & 0x00020000)
+                       tasklet_schedule(&dev->output[1].tasklet);
+               if (s & 0x00040000)
+                       tasklet_schedule(&dev->output[2].tasklet);
+               if (s & 0x00080000)
+                       tasklet_schedule(&dev->output[3].tasklet);
+
+               /* if (s & 0x000f0000)  printk(KERN_DEBUG "%08x\n", istat); */
+       } while ((s = ddbreadl(INTERRUPT_STATUS)));
+
+       return IRQ_HANDLED;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
+{
+       u32 data, shift;
+
+       if (wlen > 4)
+               ddbwritel(1, SPI_CONTROL);
+       while (wlen > 4) {
+               /* FIXME: check for big-endian */
+               data = swab32(*(u32 *)wbuf);
+               wbuf += 4;
+               wlen -= 4;
+               ddbwritel(data, SPI_DATA);
+               while (ddbreadl(SPI_CONTROL) & 0x0004)
+                       ;
+       }
+
+       if (rlen)
+               ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL);
+       else
+               ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL);
+
+       data = 0;
+       shift = ((4 - wlen) * 8);
+       while (wlen) {
+               data <<= 8;
+               data |= *wbuf;
+               wlen--;
+               wbuf++;
+       }
+       if (shift)
+               data <<= shift;
+       ddbwritel(data, SPI_DATA);
+       while (ddbreadl(SPI_CONTROL) & 0x0004)
+               ;
+
+       if (!rlen) {
+               ddbwritel(0, SPI_CONTROL);
+               return 0;
+       }
+       if (rlen > 4)
+               ddbwritel(1, SPI_CONTROL);
+
+       while (rlen > 4) {
+               ddbwritel(0xffffffff, SPI_DATA);
+               while (ddbreadl(SPI_CONTROL) & 0x0004)
+                       ;
+               data = ddbreadl(SPI_DATA);
+               *(u32 *) rbuf = swab32(data);
+               rbuf += 4;
+               rlen -= 4;
+       }
+       ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL);
+       ddbwritel(0xffffffff, SPI_DATA);
+       while (ddbreadl(SPI_CONTROL) & 0x0004)
+               ;
+
+       data = ddbreadl(SPI_DATA);
+       ddbwritel(0, SPI_CONTROL);
+
+       if (rlen < 4)
+               data <<= ((4 - rlen) * 8);
+
+       while (rlen > 0) {
+               *rbuf = ((data >> 24) & 0xff);
+               data <<= 8;
+               rbuf++;
+               rlen--;
+       }
+       return 0;
+}
+
+#define DDB_MAGIC 'd'
+
+struct ddb_flashio {
+       __u8 *write_buf;
+       __u32 write_len;
+       __u8 *read_buf;
+       __u32 read_len;
+};
+
+#define IOCTL_DDB_FLASHIO  _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
+
+#define DDB_NAME "ddbridge"
+
+static u32 ddb_num;
+static struct ddb *ddbs[32];
+static struct class *ddb_class;
+static int ddb_major;
+
+static int ddb_open(struct inode *inode, struct file *file)
+{
+       struct ddb *dev = ddbs[iminor(inode)];
+
+       file->private_data = dev;
+       return 0;
+}
+
+static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct ddb *dev = file->private_data;
+       void *parg = (void *)arg;
+       int res;
+
+       switch (cmd) {
+       case IOCTL_DDB_FLASHIO:
+       {
+               struct ddb_flashio fio;
+               u8 *rbuf, *wbuf;
+
+               if (copy_from_user(&fio, parg, sizeof(fio)))
+                       return -EFAULT;
+
+               if (fio.write_len > 1028 || fio.read_len > 1028)
+                       return -EINVAL;
+               if (fio.write_len + fio.read_len > 1028)
+                       return -EINVAL;
+
+               wbuf = &dev->iobuf[0];
+               rbuf = wbuf + fio.write_len;
+
+               if (copy_from_user(wbuf, fio.write_buf, fio.write_len))
+                       return -EFAULT;
+               res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len);
+               if (res)
+                       return res;
+               if (copy_to_user(fio.read_buf, rbuf, fio.read_len))
+                       return -EFAULT;
+               break;
+       }
+       default:
+               return -ENOTTY;
+       }
+       return 0;
+}
+
+static const struct file_operations ddb_fops = {
+       .unlocked_ioctl = ddb_ioctl,
+       .open           = ddb_open,
+};
+
+static char *ddb_devnode(struct device *device, umode_t *mode)
+{
+       struct ddb *dev = dev_get_drvdata(device);
+
+       return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr);
+}
+
+static int ddb_class_create(void)
+{
+       ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops);
+       if (ddb_major < 0)
+               return ddb_major;
+
+       ddb_class = class_create(THIS_MODULE, DDB_NAME);
+       if (IS_ERR(ddb_class)) {
+               unregister_chrdev(ddb_major, DDB_NAME);
+               return -1;
+       }
+       ddb_class->devnode = ddb_devnode;
+       return 0;
+}
+
+static void ddb_class_destroy(void)
+{
+       class_destroy(ddb_class);
+       unregister_chrdev(ddb_major, DDB_NAME);
+}
+
+static int ddb_device_create(struct ddb *dev)
+{
+       dev->nr = ddb_num++;
+       dev->ddb_dev = device_create(ddb_class, NULL,
+                                    MKDEV(ddb_major, dev->nr),
+                                    dev, "ddbridge%d", dev->nr);
+       ddbs[dev->nr] = dev;
+       if (IS_ERR(dev->ddb_dev))
+               return -1;
+       return 0;
+}
+
+static void ddb_device_destroy(struct ddb *dev)
+{
+       ddb_num--;
+       if (IS_ERR(dev->ddb_dev))
+               return;
+       device_destroy(ddb_class, MKDEV(ddb_major, 0));
+}
+
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static void ddb_unmap(struct ddb *dev)
+{
+       if (dev->regs)
+               iounmap(dev->regs);
+       vfree(dev);
+}
+
+
+static void __devexit ddb_remove(struct pci_dev *pdev)
+{
+       struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
+
+       ddb_ports_detach(dev);
+       ddb_i2c_release(dev);
+
+       ddbwritel(0, INTERRUPT_ENABLE);
+       free_irq(dev->pdev->irq, dev);
+#ifdef CONFIG_PCI_MSI
+       if (dev->msi)
+               pci_disable_msi(dev->pdev);
+#endif
+       ddb_ports_release(dev);
+       ddb_buffers_free(dev);
+       ddb_device_destroy(dev);
+
+       ddb_unmap(dev);
+       pci_set_drvdata(pdev, 0);
+       pci_disable_device(pdev);
+}
+
+
+static int __devinit ddb_probe(struct pci_dev *pdev,
+                              const struct pci_device_id *id)
+{
+       struct ddb *dev;
+       int stat = 0;
+       int irq_flag = IRQF_SHARED;
+
+       if (pci_enable_device(pdev) < 0)
+               return -ENODEV;
+
+       dev = vmalloc(sizeof(struct ddb));
+       if (dev == NULL)
+               return -ENOMEM;
+       memset(dev, 0, sizeof(struct ddb));
+
+       dev->pdev = pdev;
+       pci_set_drvdata(pdev, dev);
+       dev->info = (struct ddb_info *) id->driver_data;
+       printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name);
+
+       dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
+                           pci_resource_len(dev->pdev, 0));
+       if (!dev->regs) {
+               stat = -ENOMEM;
+               goto fail;
+       }
+       printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4));
+
+#ifdef CONFIG_PCI_MSI
+       if (pci_msi_enabled())
+               stat = pci_enable_msi(dev->pdev);
+       if (stat) {
+               printk(KERN_INFO ": MSI not available.\n");
+       } else {
+               irq_flag = 0;
+               dev->msi = 1;
+       }
+#endif
+       stat = request_irq(dev->pdev->irq, irq_handler,
+                          irq_flag, "DDBridge", (void *) dev);
+       if (stat < 0)
+               goto fail1;
+       ddbwritel(0, DMA_BASE_WRITE);
+       ddbwritel(0, DMA_BASE_READ);
+       ddbwritel(0xffffffff, INTERRUPT_ACK);
+       ddbwritel(0xfff0f, INTERRUPT_ENABLE);
+       ddbwritel(0, MSI1_ENABLE);
+
+       if (ddb_i2c_init(dev) < 0)
+               goto fail1;
+       ddb_ports_init(dev);
+       if (ddb_buffers_alloc(dev) < 0) {
+               printk(KERN_INFO ": Could not allocate buffer memory\n");
+               goto fail2;
+       }
+       if (ddb_ports_attach(dev) < 0)
+               goto fail3;
+       ddb_device_create(dev);
+       return 0;
+
+fail3:
+       ddb_ports_detach(dev);
+       printk(KERN_ERR "fail3\n");
+       ddb_ports_release(dev);
+fail2:
+       printk(KERN_ERR "fail2\n");
+       ddb_buffers_free(dev);
+fail1:
+       printk(KERN_ERR "fail1\n");
+       if (dev->msi)
+               pci_disable_msi(dev->pdev);
+       free_irq(dev->pdev->irq, dev);
+fail:
+       printk(KERN_ERR "fail\n");
+       ddb_unmap(dev);
+       pci_set_drvdata(pdev, 0);
+       pci_disable_device(pdev);
+       return -1;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+static struct ddb_info ddb_none = {
+       .type     = DDB_NONE,
+       .name     = "Digital Devices PCIe bridge",
+};
+
+static struct ddb_info ddb_octopus = {
+       .type     = DDB_OCTOPUS,
+       .name     = "Digital Devices Octopus DVB adapter",
+       .port_num = 4,
+};
+
+static struct ddb_info ddb_octopus_le = {
+       .type     = DDB_OCTOPUS,
+       .name     = "Digital Devices Octopus LE DVB adapter",
+       .port_num = 2,
+};
+
+static struct ddb_info ddb_v6 = {
+       .type     = DDB_OCTOPUS,
+       .name     = "Digital Devices Cine S2 V6 DVB adapter",
+       .port_num = 3,
+};
+
+#define DDVID 0xdd01 /* Digital Devices Vendor ID */
+
+#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) {  \
+       .vendor      = _vend,    .device    = _dev, \
+       .subvendor   = _subvend, .subdevice = _subdev, \
+       .driver_data = (unsigned long)&_driverdata }
+
+static const struct pci_device_id ddb_id_tbl[] __devinitdata = {
+       DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
+       DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
+       DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
+       DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus),
+       DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
+       /* in case sub-ids got deleted in flash */
+       DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
+       {0}
+};
+MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
+
+
+static struct pci_driver ddb_pci_driver = {
+       .name        = "DDBridge",
+       .id_table    = ddb_id_tbl,
+       .probe       = ddb_probe,
+       .remove      = __devexit_p(ddb_remove),
+};
+
+static __init int module_init_ddbridge(void)
+{
+       printk(KERN_INFO "Digital Devices PCIE bridge driver, "
+              "Copyright (C) 2010-11 Digital Devices GmbH\n");
+       if (ddb_class_create())
+               return -1;
+       return pci_register_driver(&ddb_pci_driver);
+}
+
+static __exit void module_exit_ddbridge(void)
+{
+       pci_unregister_driver(&ddb_pci_driver);
+       ddb_class_destroy();
+}
+
+module_init(module_init_ddbridge);
+module_exit(module_exit_ddbridge);
+
+MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
+MODULE_AUTHOR("Ralph Metzler");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.5");
diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h
new file mode 100644 (file)
index 0000000..a3ccb31
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * ddbridge-regs.h: Digital Devices PCIe bridge driver
+ *
+ * Copyright (C) 2010-2011 Digital Devices GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */
+
+/* Register Definitions */
+
+#define CUR_REGISTERMAP_VERSION 0x10000
+
+#define HARDWARE_VERSION       0x00
+#define REGISTERMAP_VERSION    0x04
+
+/* ------------------------------------------------------------------------- */
+/* SPI Controller */
+
+#define SPI_CONTROL     0x10
+#define SPI_DATA        0x14
+
+/* ------------------------------------------------------------------------- */
+
+/* Interrupt controller                                     */
+/* How many MSI's are available depends on HW (Min 2 max 8) */
+/* How many are usable also depends on Host platform        */
+
+#define INTERRUPT_BASE   (0x40)
+
+#define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00)
+#define MSI0_ENABLE      (INTERRUPT_BASE + 0x00)
+#define MSI1_ENABLE      (INTERRUPT_BASE + 0x04)
+#define MSI2_ENABLE      (INTERRUPT_BASE + 0x08)
+#define MSI3_ENABLE      (INTERRUPT_BASE + 0x0C)
+#define MSI4_ENABLE      (INTERRUPT_BASE + 0x10)
+#define MSI5_ENABLE      (INTERRUPT_BASE + 0x14)
+#define MSI6_ENABLE      (INTERRUPT_BASE + 0x18)
+#define MSI7_ENABLE      (INTERRUPT_BASE + 0x1C)
+
+#define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20)
+#define INTERRUPT_ACK    (INTERRUPT_BASE + 0x20)
+
+#define INTMASK_I2C1        (0x00000001)
+#define INTMASK_I2C2        (0x00000002)
+#define INTMASK_I2C3        (0x00000004)
+#define INTMASK_I2C4        (0x00000008)
+
+#define INTMASK_CIRQ1       (0x00000010)
+#define INTMASK_CIRQ2       (0x00000020)
+#define INTMASK_CIRQ3       (0x00000040)
+#define INTMASK_CIRQ4       (0x00000080)
+
+#define INTMASK_TSINPUT1    (0x00000100)
+#define INTMASK_TSINPUT2    (0x00000200)
+#define INTMASK_TSINPUT3    (0x00000400)
+#define INTMASK_TSINPUT4    (0x00000800)
+#define INTMASK_TSINPUT5    (0x00001000)
+#define INTMASK_TSINPUT6    (0x00002000)
+#define INTMASK_TSINPUT7    (0x00004000)
+#define INTMASK_TSINPUT8    (0x00008000)
+
+#define INTMASK_TSOUTPUT1   (0x00010000)
+#define INTMASK_TSOUTPUT2   (0x00020000)
+#define INTMASK_TSOUTPUT3   (0x00040000)
+#define INTMASK_TSOUTPUT4   (0x00080000)
+
+/* ------------------------------------------------------------------------- */
+/* I2C Master Controller */
+
+#define I2C_BASE        (0x80)  /* Byte offset */
+
+#define I2C_COMMAND     (0x00)
+#define I2C_TIMING      (0x04)
+#define I2C_TASKLENGTH  (0x08)     /* High read, low write */
+#define I2C_TASKADDRESS (0x0C)     /* High read, low write */
+
+#define I2C_MONITOR     (0x1C)
+
+#define I2C_BASE_1      (I2C_BASE + 0x00)
+#define I2C_BASE_2      (I2C_BASE + 0x20)
+#define I2C_BASE_3      (I2C_BASE + 0x40)
+#define I2C_BASE_4      (I2C_BASE + 0x60)
+
+#define I2C_BASE_N(i)   (I2C_BASE + (i) * 0x20)
+
+#define I2C_TASKMEM_BASE    (0x1000)    /* Byte offset */
+#define I2C_TASKMEM_SIZE    (0x1000)
+
+#define I2C_SPEED_400   (0x04030404)
+#define I2C_SPEED_200   (0x09080909)
+#define I2C_SPEED_154   (0x0C0B0C0C)
+#define I2C_SPEED_100   (0x13121313)
+#define I2C_SPEED_77    (0x19181919)
+#define I2C_SPEED_50    (0x27262727)
+
+
+/* ------------------------------------------------------------------------- */
+/* DMA  Controller */
+
+#define DMA_BASE_WRITE        (0x100)
+#define DMA_BASE_READ         (0x140)
+
+#define DMA_CONTROL     (0x00)                  /* 64 */
+#define DMA_ERROR       (0x04)                  /* 65 ( only read instance ) */
+
+#define DMA_DIAG_CONTROL                (0x1C)  /* 71 */
+#define DMA_DIAG_PACKETCOUNTER_LOW      (0x20)  /* 72 */
+#define DMA_DIAG_PACKETCOUNTER_HIGH     (0x24)  /* 73 */
+#define DMA_DIAG_TIMECOUNTER_LOW        (0x28)  /* 74 */
+#define DMA_DIAG_TIMECOUNTER_HIGH       (0x2C)  /* 75 */
+#define DMA_DIAG_RECHECKCOUNTER         (0x30)  /* 76  ( Split completions on read ) */
+#define DMA_DIAG_WAITTIMEOUTINIT        (0x34)  /* 77 */
+#define DMA_DIAG_WAITOVERFLOWCOUNTER    (0x38)  /* 78 */
+#define DMA_DIAG_WAITCOUNTER            (0x3C)  /* 79 */
+
+/* ------------------------------------------------------------------------- */
+/* DMA  Buffer */
+
+#define TS_INPUT_BASE       (0x200)
+#define TS_INPUT_CONTROL(i)         (TS_INPUT_BASE + (i) * 16 + 0x00)
+
+#define TS_OUTPUT_BASE       (0x280)
+#define TS_OUTPUT_CONTROL(i)         (TS_OUTPUT_BASE + (i) * 16 + 0x00)
+
+#define DMA_BUFFER_BASE     (0x300)
+
+#define DMA_BUFFER_CONTROL(i)       (DMA_BUFFER_BASE + (i) * 16 + 0x00)
+#define DMA_BUFFER_ACK(i)           (DMA_BUFFER_BASE + (i) * 16 + 0x04)
+#define DMA_BUFFER_CURRENT(i)       (DMA_BUFFER_BASE + (i) * 16 + 0x08)
+#define DMA_BUFFER_SIZE(i)          (DMA_BUFFER_BASE + (i) * 16 + 0x0c)
+
+#define DMA_BASE_ADDRESS_TABLE  (0x2000)
+#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512)
+
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
new file mode 100644 (file)
index 0000000..8b1b41d
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * ddbridge.h: Digital Devices PCIe bridge driver
+ *
+ * Copyright (C) 2010-2011 Digital Devices GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _DDBRIDGE_H_
+#define _DDBRIDGE_H_
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <asm/dma.h>
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/ca.h>
+#include <linux/socket.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_ringbuffer.h"
+#include "dvb_ca_en50221.h"
+#include "dvb_net.h"
+#include "cxd2099.h"
+
+#define DDB_MAX_I2C     4
+#define DDB_MAX_PORT    4
+#define DDB_MAX_INPUT   8
+#define DDB_MAX_OUTPUT  4
+
+struct ddb_info {
+       int   type;
+#define DDB_NONE         0
+#define DDB_OCTOPUS      1
+       char *name;
+       int   port_num;
+       u32   port_type[DDB_MAX_PORT];
+};
+
+/* DMA_SIZE MUST be divisible by 188 and 128 !!! */
+
+#define INPUT_DMA_MAX_BUFS 32      /* hardware table limit */
+#define INPUT_DMA_BUFS 8
+#define INPUT_DMA_SIZE (128*47*21)
+
+#define OUTPUT_DMA_MAX_BUFS 32
+#define OUTPUT_DMA_BUFS 8
+#define OUTPUT_DMA_SIZE (128*47*21)
+
+struct ddb;
+struct ddb_port;
+
+struct ddb_input {
+       struct ddb_port       *port;
+       u32                    nr;
+       int                    attached;
+
+       dma_addr_t             pbuf[INPUT_DMA_MAX_BUFS];
+       u8                    *vbuf[INPUT_DMA_MAX_BUFS];
+       u32                    dma_buf_num;
+       u32                    dma_buf_size;
+
+       struct tasklet_struct  tasklet;
+       spinlock_t             lock;
+       wait_queue_head_t      wq;
+       int                    running;
+       u32                    stat;
+       u32                    cbuf;
+       u32                    coff;
+
+       struct dvb_adapter     adap;
+       struct dvb_device     *dev;
+       struct dvb_frontend   *fe;
+       struct dvb_frontend   *fe2;
+       struct dmxdev          dmxdev;
+       struct dvb_demux       demux;
+       struct dvb_net         dvbnet;
+       struct dmx_frontend    hw_frontend;
+       struct dmx_frontend    mem_frontend;
+       int                    users;
+       int (*gate_ctrl)(struct dvb_frontend *, int);
+};
+
+struct ddb_output {
+       struct ddb_port       *port;
+       u32                    nr;
+       dma_addr_t             pbuf[OUTPUT_DMA_MAX_BUFS];
+       u8                    *vbuf[OUTPUT_DMA_MAX_BUFS];
+       u32                    dma_buf_num;
+       u32                    dma_buf_size;
+       struct tasklet_struct  tasklet;
+       spinlock_t             lock;
+       wait_queue_head_t      wq;
+       int                    running;
+       u32                    stat;
+       u32                    cbuf;
+       u32                    coff;
+
+       struct dvb_adapter     adap;
+       struct dvb_device     *dev;
+};
+
+struct ddb_i2c {
+       struct ddb            *dev;
+       u32                    nr;
+       struct i2c_adapter     adap;
+       struct i2c_adapter     adap2;
+       u32                    regs;
+       u32                    rbuf;
+       u32                    wbuf;
+       int                    done;
+       wait_queue_head_t      wq;
+};
+
+struct ddb_port {
+       struct ddb            *dev;
+       u32                    nr;
+       struct ddb_i2c        *i2c;
+       struct mutex           i2c_gate_lock;
+       u32                    class;
+#define DDB_PORT_NONE           0
+#define DDB_PORT_CI             1
+#define DDB_PORT_TUNER          2
+       u32                    type;
+#define DDB_TUNER_NONE          0
+#define DDB_TUNER_DVBS_ST       1
+#define DDB_TUNER_DVBS_ST_AA    2
+#define DDB_TUNER_DVBCT_TR     16
+#define DDB_TUNER_DVBCT_ST     17
+       u32                    adr;
+
+       struct ddb_input      *input[2];
+       struct ddb_output     *output;
+       struct dvb_ca_en50221 *en;
+};
+
+struct ddb {
+       struct pci_dev        *pdev;
+       unsigned char         *regs;
+       struct ddb_port        port[DDB_MAX_PORT];
+       struct ddb_i2c         i2c[DDB_MAX_I2C];
+       struct ddb_input       input[DDB_MAX_INPUT];
+       struct ddb_output      output[DDB_MAX_OUTPUT];
+
+       struct device         *ddb_dev;
+       int                    nr;
+       u8                     iobuf[1028];
+
+       struct ddb_info       *info;
+       int                    msi;
+};
+
+/****************************************************************************/
+
+#define ddbwritel(_val, _adr)        writel((_val), \
+                                    (char *) (dev->regs+(_adr)))
+#define ddbreadl(_adr)               readl((char *) (dev->regs+(_adr)))
+#define ddbcpyto(_adr, _src, _count) memcpy_toio((char *)      \
+                                    (dev->regs+(_adr)), (_src), (_count))
+#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), (char *) \
+                                      (dev->regs+(_adr)), (_count))
+
+/****************************************************************************/
+
+#endif
diff --git a/drivers/media/pci/dm1105/Kconfig b/drivers/media/pci/dm1105/Kconfig
new file mode 100644 (file)
index 0000000..f3de0a4
--- /dev/null
@@ -0,0 +1,20 @@
+config DVB_DM1105
+       tristate "SDMC DM1105 based PCI cards"
+       depends on DVB_CORE && PCI && I2C
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_STV0288 if !DVB_FE_CUSTOMISE
+       select DVB_STB6000 if !DVB_FE_CUSTOMISE
+       select DVB_CX24116 if !DVB_FE_CUSTOMISE
+       select DVB_SI21XX if !DVB_FE_CUSTOMISE
+       select DVB_DS3000 if !DVB_FE_CUSTOMISE
+       depends on RC_CORE
+       help
+         Support for cards based on the SDMC DM1105 PCI chip like
+         DvbWorld 2002
+
+         Since these cards have no MPEG decoder onboard, they transmit
+         only compressed MPEG data over the PCI bus, so you need
+         an external software decoder to watch TV on your computer.
+
+         Say Y or M if you own such a device and want to use it.
diff --git a/drivers/media/pci/dm1105/Makefile b/drivers/media/pci/dm1105/Makefile
new file mode 100644 (file)
index 0000000..3275851
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_DM1105) += dm1105.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
new file mode 100644 (file)
index 0000000..a609b3a
--- /dev/null
@@ -0,0 +1,1248 @@
+/*
+ * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip
+ *
+ * Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
+ *
+ * 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/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <media/rc-core.h>
+
+#include "demux.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include "dvbdev.h"
+#include "dvb-pll.h"
+
+#include "stv0299.h"
+#include "stv0288.h"
+#include "stb6000.h"
+#include "si21xx.h"
+#include "cx24116.h"
+#include "z0194a.h"
+#include "ds3000.h"
+
+#define MODULE_NAME "dm1105"
+
+#define UNSET (-1U)
+
+#define DM1105_BOARD_NOAUTO                    UNSET
+#define DM1105_BOARD_UNKNOWN                   0
+#define DM1105_BOARD_DVBWORLD_2002             1
+#define DM1105_BOARD_DVBWORLD_2004             2
+#define DM1105_BOARD_AXESS_DM05                        3
+#define DM1105_BOARD_UNBRANDED_I2C_ON_GPIO     4
+
+/* ----------------------------------------------- */
+/*
+ * PCI ID's
+ */
+#ifndef PCI_VENDOR_ID_TRIGEM
+#define PCI_VENDOR_ID_TRIGEM   0x109f
+#endif
+#ifndef PCI_VENDOR_ID_AXESS
+#define PCI_VENDOR_ID_AXESS    0x195d
+#endif
+#ifndef PCI_DEVICE_ID_DM1105
+#define PCI_DEVICE_ID_DM1105   0x036f
+#endif
+#ifndef PCI_DEVICE_ID_DW2002
+#define PCI_DEVICE_ID_DW2002   0x2002
+#endif
+#ifndef PCI_DEVICE_ID_DW2004
+#define PCI_DEVICE_ID_DW2004   0x2004
+#endif
+#ifndef PCI_DEVICE_ID_DM05
+#define PCI_DEVICE_ID_DM05     0x1105
+#endif
+/* ----------------------------------------------- */
+/* sdmc dm1105 registers */
+
+/* TS Control */
+#define DM1105_TSCTR                           0x00
+#define DM1105_DTALENTH                                0x04
+
+/* GPIO Interface */
+#define DM1105_GPIOVAL                         0x08
+#define DM1105_GPIOCTR                         0x0c
+
+/* PID serial number */
+#define DM1105_PIDN                            0x10
+
+/* Odd-even secret key select */
+#define DM1105_CWSEL                           0x14
+
+/* Host Command Interface */
+#define DM1105_HOST_CTR                                0x18
+#define DM1105_HOST_AD                         0x1c
+
+/* PCI Interface */
+#define DM1105_CR                              0x30
+#define DM1105_RST                             0x34
+#define DM1105_STADR                           0x38
+#define DM1105_RLEN                            0x3c
+#define DM1105_WRP                             0x40
+#define DM1105_INTCNT                          0x44
+#define DM1105_INTMAK                          0x48
+#define DM1105_INTSTS                          0x4c
+
+/* CW Value */
+#define DM1105_ODD                             0x50
+#define DM1105_EVEN                            0x58
+
+/* PID Value */
+#define DM1105_PID                             0x60
+
+/* IR Control */
+#define DM1105_IRCTR                           0x64
+#define DM1105_IRMODE                          0x68
+#define DM1105_SYSTEMCODE                      0x6c
+#define DM1105_IRCODE                          0x70
+
+/* Unknown Values */
+#define DM1105_ENCRYPT                         0x74
+#define DM1105_VER                             0x7c
+
+/* I2C Interface */
+#define DM1105_I2CCTR                          0x80
+#define DM1105_I2CSTS                          0x81
+#define DM1105_I2CDAT                          0x82
+#define DM1105_I2C_RA                          0x83
+/* ----------------------------------------------- */
+/* Interrupt Mask Bits */
+
+#define INTMAK_TSIRQM                          0x01
+#define INTMAK_HIRQM                           0x04
+#define INTMAK_IRM                             0x08
+#define INTMAK_ALLMASK                         (INTMAK_TSIRQM | \
+                                               INTMAK_HIRQM | \
+                                               INTMAK_IRM)
+#define INTMAK_NONEMASK                                0x00
+
+/* Interrupt Status Bits */
+#define INTSTS_TSIRQ                           0x01
+#define INTSTS_HIRQ                            0x04
+#define INTSTS_IR                              0x08
+
+/* IR Control Bits */
+#define DM1105_IR_EN                           0x01
+#define DM1105_SYS_CHK                         0x02
+#define DM1105_REP_FLG                         0x08
+
+/* EEPROM addr */
+#define IIC_24C01_addr                         0xa0
+/* Max board count */
+#define DM1105_MAX                             0x04
+
+#define DRIVER_NAME                            "dm1105"
+#define DM1105_I2C_GPIO_NAME                   "dm1105-gpio"
+
+#define DM1105_DMA_PACKETS                     47
+#define DM1105_DMA_PACKET_LENGTH               (128*4)
+#define DM1105_DMA_BYTES                       (128 * 4 * DM1105_DMA_PACKETS)
+
+/*  */
+#define GPIO08                                 (1 << 8)
+#define GPIO13                                 (1 << 13)
+#define GPIO14                                 (1 << 14)
+#define GPIO15                                 (1 << 15)
+#define GPIO16                                 (1 << 16)
+#define GPIO17                                 (1 << 17)
+#define GPIO_ALL                               0x03ffff
+
+/* GPIO's for LNB power control */
+#define DM1105_LNB_MASK                                (GPIO_ALL & ~(GPIO14 | GPIO13))
+#define DM1105_LNB_OFF                         GPIO17
+#define DM1105_LNB_13V                         (GPIO16 | GPIO08)
+#define DM1105_LNB_18V                         GPIO08
+
+/* GPIO's for LNB power control for Axess DM05 */
+#define DM05_LNB_MASK                          (GPIO_ALL & ~(GPIO14 | GPIO13))
+#define DM05_LNB_OFF                           GPIO17/* actually 13v */
+#define DM05_LNB_13V                           GPIO17
+#define DM05_LNB_18V                           (GPIO17 | GPIO16)
+
+/* GPIO's for LNB power control for unbranded with I2C on GPIO */
+#define UNBR_LNB_MASK                          (GPIO17 | GPIO16)
+#define UNBR_LNB_OFF                           0
+#define UNBR_LNB_13V                           GPIO17
+#define UNBR_LNB_18V                           (GPIO17 | GPIO16)
+
+static unsigned int card[]  = {[0 ... 3] = UNSET };
+module_param_array(card,  int, NULL, 0444);
+MODULE_PARM_DESC(card, "card type");
+
+static int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
+
+static unsigned int dm1105_devcount;
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct dm1105_board {
+       char    *name;
+       struct  {
+               u32     mask, off, v13, v18;
+       } lnb;
+       u32     gpio_scl, gpio_sda;
+};
+
+struct dm1105_subid {
+       u16     subvendor;
+       u16     subdevice;
+       u32     card;
+};
+
+static const struct dm1105_board dm1105_boards[] = {
+       [DM1105_BOARD_UNKNOWN] = {
+               .name           = "UNKNOWN/GENERIC",
+               .lnb = {
+                       .mask = DM1105_LNB_MASK,
+                       .off = DM1105_LNB_OFF,
+                       .v13 = DM1105_LNB_13V,
+                       .v18 = DM1105_LNB_18V,
+               },
+       },
+       [DM1105_BOARD_DVBWORLD_2002] = {
+               .name           = "DVBWorld PCI 2002",
+               .lnb = {
+                       .mask = DM1105_LNB_MASK,
+                       .off = DM1105_LNB_OFF,
+                       .v13 = DM1105_LNB_13V,
+                       .v18 = DM1105_LNB_18V,
+               },
+       },
+       [DM1105_BOARD_DVBWORLD_2004] = {
+               .name           = "DVBWorld PCI 2004",
+               .lnb = {
+                       .mask = DM1105_LNB_MASK,
+                       .off = DM1105_LNB_OFF,
+                       .v13 = DM1105_LNB_13V,
+                       .v18 = DM1105_LNB_18V,
+               },
+       },
+       [DM1105_BOARD_AXESS_DM05] = {
+               .name           = "Axess/EasyTv DM05",
+               .lnb = {
+                       .mask = DM05_LNB_MASK,
+                       .off = DM05_LNB_OFF,
+                       .v13 = DM05_LNB_13V,
+                       .v18 = DM05_LNB_18V,
+               },
+       },
+       [DM1105_BOARD_UNBRANDED_I2C_ON_GPIO] = {
+               .name           = "Unbranded DM1105 with i2c on GPIOs",
+               .lnb = {
+                       .mask = UNBR_LNB_MASK,
+                       .off = UNBR_LNB_OFF,
+                       .v13 = UNBR_LNB_13V,
+                       .v18 = UNBR_LNB_18V,
+               },
+               .gpio_scl       = GPIO14,
+               .gpio_sda       = GPIO13,
+       },
+};
+
+static const struct dm1105_subid dm1105_subids[] = {
+       {
+               .subvendor = 0x0000,
+               .subdevice = 0x2002,
+               .card      = DM1105_BOARD_DVBWORLD_2002,
+       }, {
+               .subvendor = 0x0001,
+               .subdevice = 0x2002,
+               .card      = DM1105_BOARD_DVBWORLD_2002,
+       }, {
+               .subvendor = 0x0000,
+               .subdevice = 0x2004,
+               .card      = DM1105_BOARD_DVBWORLD_2004,
+       }, {
+               .subvendor = 0x0001,
+               .subdevice = 0x2004,
+               .card      = DM1105_BOARD_DVBWORLD_2004,
+       }, {
+               .subvendor = 0x195d,
+               .subdevice = 0x1105,
+               .card      = DM1105_BOARD_AXESS_DM05,
+       },
+};
+
+static void dm1105_card_list(struct pci_dev *pci)
+{
+       int i;
+
+       if (0 == pci->subsystem_vendor &&
+                       0 == pci->subsystem_device) {
+               printk(KERN_ERR
+                       "dm1105: Your board has no valid PCI Subsystem ID\n"
+                       "dm1105: and thus can't be autodetected\n"
+                       "dm1105: Please pass card=<n> insmod option to\n"
+                       "dm1105: workaround that.  Redirect complaints to\n"
+                       "dm1105: the vendor of the TV card.  Best regards,\n"
+                       "dm1105: -- tux\n");
+       } else {
+               printk(KERN_ERR
+                       "dm1105: Your board isn't known (yet) to the driver.\n"
+                       "dm1105: You can try to pick one of the existing\n"
+                       "dm1105: card configs via card=<n> insmod option.\n"
+                       "dm1105: Updating to the latest version might help\n"
+                       "dm1105: as well.\n");
+       }
+       printk(KERN_ERR "Here is a list of valid choices for the card=<n> "
+                  "insmod option:\n");
+       for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)
+               printk(KERN_ERR "dm1105:    card=%d -> %s\n",
+                               i, dm1105_boards[i].name);
+}
+
+/* infrared remote control */
+struct infrared {
+       struct rc_dev           *dev;
+       char                    input_phys[32];
+       struct work_struct      work;
+       u32                     ir_command;
+};
+
+struct dm1105_dev {
+       /* pci */
+       struct pci_dev *pdev;
+       u8 __iomem *io_mem;
+
+       /* ir */
+       struct infrared ir;
+
+       /* dvb */
+       struct dmx_frontend hw_frontend;
+       struct dmx_frontend mem_frontend;
+       struct dmxdev dmxdev;
+       struct dvb_adapter dvb_adapter;
+       struct dvb_demux demux;
+       struct dvb_frontend *fe;
+       struct dvb_net dvbnet;
+       unsigned int full_ts_users;
+       unsigned int boardnr;
+       int nr;
+
+       /* i2c */
+       struct i2c_adapter i2c_adap;
+       struct i2c_adapter i2c_bb_adap;
+       struct i2c_algo_bit_data i2c_bit;
+
+       /* irq */
+       struct work_struct work;
+       struct workqueue_struct *wq;
+       char wqn[16];
+
+       /* dma */
+       dma_addr_t dma_addr;
+       unsigned char *ts_buf;
+       u32 wrp;
+       u32 nextwrp;
+       u32 buffer_size;
+       unsigned int    PacketErrorCount;
+       unsigned int dmarst;
+       spinlock_t lock;
+};
+
+#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
+
+#define dm_readb(reg)          inb(dm_io_mem(reg))
+#define dm_writeb(reg, value)  outb((value), (dm_io_mem(reg)))
+
+#define dm_readw(reg)          inw(dm_io_mem(reg))
+#define dm_writew(reg, value)  outw((value), (dm_io_mem(reg)))
+
+#define dm_readl(reg)          inl(dm_io_mem(reg))
+#define dm_writel(reg, value)  outl((value), (dm_io_mem(reg)))
+
+#define dm_andorl(reg, mask, value) \
+       outl((inl(dm_io_mem(reg)) & ~(mask)) |\
+               ((value) & (mask)), (dm_io_mem(reg)))
+
+#define dm_setl(reg, bit)      dm_andorl((reg), (bit), (bit))
+#define dm_clearl(reg, bit)    dm_andorl((reg), (bit), 0)
+
+/* The chip has 18 GPIOs. In HOST mode GPIO's used as 15 bit address lines,
+ so we can use only 3 GPIO's from GPIO15 to GPIO17.
+ Here I don't check whether HOST is enebled as it is not implemented yet.
+ */
+static void dm1105_gpio_set(struct dm1105_dev *dev, u32 mask)
+{
+       if (mask & 0xfffc0000)
+               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+       if (mask & 0x0003ffff)
+               dm_setl(DM1105_GPIOVAL, mask & 0x0003ffff);
+
+}
+
+static void dm1105_gpio_clear(struct dm1105_dev *dev, u32 mask)
+{
+       if (mask & 0xfffc0000)
+               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+       if (mask & 0x0003ffff)
+               dm_clearl(DM1105_GPIOVAL, mask & 0x0003ffff);
+
+}
+
+static void dm1105_gpio_andor(struct dm1105_dev *dev, u32 mask, u32 val)
+{
+       if (mask & 0xfffc0000)
+               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+       if (mask & 0x0003ffff)
+               dm_andorl(DM1105_GPIOVAL, mask & 0x0003ffff, val);
+
+}
+
+static u32 dm1105_gpio_get(struct dm1105_dev *dev, u32 mask)
+{
+       if (mask & 0xfffc0000)
+               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+       if (mask & 0x0003ffff)
+               return dm_readl(DM1105_GPIOVAL) & mask & 0x0003ffff;
+
+       return 0;
+}
+
+static void dm1105_gpio_enable(struct dm1105_dev *dev, u32 mask, int asoutput)
+{
+       if (mask & 0xfffc0000)
+               printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+       if ((mask & 0x0003ffff) && asoutput)
+               dm_clearl(DM1105_GPIOCTR, mask & 0x0003ffff);
+       else if ((mask & 0x0003ffff) && !asoutput)
+               dm_setl(DM1105_GPIOCTR, mask & 0x0003ffff);
+
+}
+
+static void dm1105_setline(struct dm1105_dev *dev, u32 line, int state)
+{
+       if (state)
+               dm1105_gpio_enable(dev, line, 0);
+       else {
+               dm1105_gpio_enable(dev, line, 1);
+               dm1105_gpio_clear(dev, line);
+       }
+}
+
+static void dm1105_setsda(void *data, int state)
+{
+       struct dm1105_dev *dev = data;
+
+       dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_sda, state);
+}
+
+static void dm1105_setscl(void *data, int state)
+{
+       struct dm1105_dev *dev = data;
+
+       dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_scl, state);
+}
+
+static int dm1105_getsda(void *data)
+{
+       struct dm1105_dev *dev = data;
+
+       return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_sda)
+                                                                       ? 1 : 0;
+}
+
+static int dm1105_getscl(void *data)
+{
+       struct dm1105_dev *dev = data;
+
+       return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_scl)
+                                                                       ? 1 : 0;
+}
+
+static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
+                           struct i2c_msg *msgs, int num)
+{
+       struct dm1105_dev *dev ;
+
+       int addr, rc, i, j, k, len, byte, data;
+       u8 status;
+
+       dev = i2c_adap->algo_data;
+       for (i = 0; i < num; i++) {
+               dm_writeb(DM1105_I2CCTR, 0x00);
+               if (msgs[i].flags & I2C_M_RD) {
+                       /* read bytes */
+                       addr  = msgs[i].addr << 1;
+                       addr |= 1;
+                       dm_writeb(DM1105_I2CDAT, addr);
+                       for (byte = 0; byte < msgs[i].len; byte++)
+                               dm_writeb(DM1105_I2CDAT + byte + 1, 0);
+
+                       dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
+                       for (j = 0; j < 55; j++) {
+                               mdelay(10);
+                               status = dm_readb(DM1105_I2CSTS);
+                               if ((status & 0xc0) == 0x40)
+                                       break;
+                       }
+                       if (j >= 55)
+                               return -1;
+
+                       for (byte = 0; byte < msgs[i].len; byte++) {
+                               rc = dm_readb(DM1105_I2CDAT + byte + 1);
+                               if (rc < 0)
+                                       goto err;
+                               msgs[i].buf[byte] = rc;
+                       }
+               } else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
+                       /* prepaired for cx24116 firmware */
+                       /* Write in small blocks */
+                       len = msgs[i].len - 1;
+                       k = 1;
+                       do {
+                               dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
+                               dm_writeb(DM1105_I2CDAT + 1, 0xf7);
+                               for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
+                                       data = msgs[i].buf[k + byte];
+                                       dm_writeb(DM1105_I2CDAT + byte + 2, data);
+                               }
+                               dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len));
+                               for (j = 0; j < 25; j++) {
+                                       mdelay(10);
+                                       status = dm_readb(DM1105_I2CSTS);
+                                       if ((status & 0xc0) == 0x40)
+                                               break;
+                               }
+
+                               if (j >= 25)
+                                       return -1;
+
+                               k += 48;
+                               len -= 48;
+                       } while (len > 0);
+               } else {
+                       /* write bytes */
+                       dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
+                       for (byte = 0; byte < msgs[i].len; byte++) {
+                               data = msgs[i].buf[byte];
+                               dm_writeb(DM1105_I2CDAT + byte + 1, data);
+                       }
+                       dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
+                       for (j = 0; j < 25; j++) {
+                               mdelay(10);
+                               status = dm_readb(DM1105_I2CSTS);
+                               if ((status & 0xc0) == 0x40)
+                                       break;
+                       }
+
+                       if (j >= 25)
+                               return -1;
+               }
+       }
+       return num;
+ err:
+       return rc;
+}
+
+static u32 functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dm1105_algo = {
+       .master_xfer   = dm1105_i2c_xfer,
+       .functionality = functionality,
+};
+
+static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed)
+{
+       return container_of(feed->demux, struct dm1105_dev, demux);
+}
+
+static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe)
+{
+       return container_of(fe->dvb, struct dm1105_dev, dvb_adapter);
+}
+
+static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);
+
+       dm1105_gpio_enable(dev, dm1105_boards[dev->boardnr].lnb.mask, 1);
+       if (voltage == SEC_VOLTAGE_18)
+               dm1105_gpio_andor(dev,
+                               dm1105_boards[dev->boardnr].lnb.mask,
+                               dm1105_boards[dev->boardnr].lnb.v18);
+       else if (voltage == SEC_VOLTAGE_13)
+               dm1105_gpio_andor(dev,
+                               dm1105_boards[dev->boardnr].lnb.mask,
+                               dm1105_boards[dev->boardnr].lnb.v13);
+       else
+               dm1105_gpio_andor(dev,
+                               dm1105_boards[dev->boardnr].lnb.mask,
+                               dm1105_boards[dev->boardnr].lnb.off);
+
+       return 0;
+}
+
+static void dm1105_set_dma_addr(struct dm1105_dev *dev)
+{
+       dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));
+}
+
+static int __devinit dm1105_dma_map(struct dm1105_dev *dev)
+{
+       dev->ts_buf = pci_alloc_consistent(dev->pdev,
+                                       6 * DM1105_DMA_BYTES,
+                                       &dev->dma_addr);
+
+       return !dev->ts_buf;
+}
+
+static void dm1105_dma_unmap(struct dm1105_dev *dev)
+{
+       pci_free_consistent(dev->pdev,
+                       6 * DM1105_DMA_BYTES,
+                       dev->ts_buf,
+                       dev->dma_addr);
+}
+
+static void dm1105_enable_irqs(struct dm1105_dev *dev)
+{
+       dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK);
+       dm_writeb(DM1105_CR, 1);
+}
+
+static void dm1105_disable_irqs(struct dm1105_dev *dev)
+{
+       dm_writeb(DM1105_INTMAK, INTMAK_IRM);
+       dm_writeb(DM1105_CR, 0);
+}
+
+static int dm1105_start_feed(struct dvb_demux_feed *f)
+{
+       struct dm1105_dev *dev = feed_to_dm1105_dev(f);
+
+       if (dev->full_ts_users++ == 0)
+               dm1105_enable_irqs(dev);
+
+       return 0;
+}
+
+static int dm1105_stop_feed(struct dvb_demux_feed *f)
+{
+       struct dm1105_dev *dev = feed_to_dm1105_dev(f);
+
+       if (--dev->full_ts_users == 0)
+               dm1105_disable_irqs(dev);
+
+       return 0;
+}
+
+/* ir work handler */
+static void dm1105_emit_key(struct work_struct *work)
+{
+       struct infrared *ir = container_of(work, struct infrared, work);
+       u32 ircom = ir->ir_command;
+       u8 data;
+
+       if (ir_debug)
+               printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
+
+       data = (ircom >> 8) & 0x7f;
+
+       rc_keydown(ir->dev, data, 0);
+}
+
+/* work handler */
+static void dm1105_dmx_buffer(struct work_struct *work)
+{
+       struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work);
+       unsigned int nbpackets;
+       u32 oldwrp = dev->wrp;
+       u32 nextwrp = dev->nextwrp;
+
+       if (!((dev->ts_buf[oldwrp] == 0x47) &&
+                       (dev->ts_buf[oldwrp + 188] == 0x47) &&
+                       (dev->ts_buf[oldwrp + 188 * 2] == 0x47))) {
+               dev->PacketErrorCount++;
+               /* bad packet found */
+               if ((dev->PacketErrorCount >= 2) &&
+                               (dev->dmarst == 0)) {
+                       dm_writeb(DM1105_RST, 1);
+                       dev->wrp = 0;
+                       dev->PacketErrorCount = 0;
+                       dev->dmarst = 0;
+                       return;
+               }
+       }
+
+       if (nextwrp < oldwrp) {
+               memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp);
+               nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188;
+       } else
+               nbpackets = (nextwrp - oldwrp) / 188;
+
+       dev->wrp = nextwrp;
+       dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets);
+}
+
+static irqreturn_t dm1105_irq(int irq, void *dev_id)
+{
+       struct dm1105_dev *dev = dev_id;
+
+       /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
+       unsigned int intsts = dm_readb(DM1105_INTSTS);
+       dm_writeb(DM1105_INTSTS, intsts);
+
+       switch (intsts) {
+       case INTSTS_TSIRQ:
+       case (INTSTS_TSIRQ | INTSTS_IR):
+               dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR);
+               queue_work(dev->wq, &dev->work);
+               break;
+       case INTSTS_IR:
+               dev->ir.ir_command = dm_readl(DM1105_IRCODE);
+               schedule_work(&dev->ir.work);
+               break;
+       }
+
+       return IRQ_HANDLED;
+}
+
+int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
+{
+       struct rc_dev *dev;
+       int err = -ENOMEM;
+
+       dev = rc_allocate_device();
+       if (!dev)
+               return -ENOMEM;
+
+       snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
+               "pci-%s/ir0", pci_name(dm1105->pdev));
+
+       dev->driver_name = MODULE_NAME;
+       dev->map_name = RC_MAP_DM1105_NEC;
+       dev->driver_type = RC_DRIVER_SCANCODE;
+       dev->input_name = "DVB on-card IR receiver";
+       dev->input_phys = dm1105->ir.input_phys;
+       dev->input_id.bustype = BUS_PCI;
+       dev->input_id.version = 1;
+       if (dm1105->pdev->subsystem_vendor) {
+               dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
+               dev->input_id.product = dm1105->pdev->subsystem_device;
+       } else {
+               dev->input_id.vendor = dm1105->pdev->vendor;
+               dev->input_id.product = dm1105->pdev->device;
+       }
+       dev->dev.parent = &dm1105->pdev->dev;
+
+       INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
+
+       err = rc_register_device(dev);
+       if (err < 0) {
+               rc_free_device(dev);
+               return err;
+       }
+
+       dm1105->ir.dev = dev;
+       return 0;
+}
+
+void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
+{
+       rc_unregister_device(dm1105->ir.dev);
+}
+
+static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
+{
+       dm1105_disable_irqs(dev);
+
+       dm_writeb(DM1105_HOST_CTR, 0);
+
+       /*DATALEN 188,*/
+       dm_writeb(DM1105_DTALENTH, 188);
+       /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/
+       dm_writew(DM1105_TSCTR, 0xc10a);
+
+       /* map DMA and set address */
+       dm1105_dma_map(dev);
+       dm1105_set_dma_addr(dev);
+       /* big buffer */
+       dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES);
+       dm_writeb(DM1105_INTCNT, 47);
+
+       /* IR NEC mode enable */
+       dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK));
+       dm_writeb(DM1105_IRMODE, 0);
+       dm_writew(DM1105_SYSTEMCODE, 0);
+
+       return 0;
+}
+
+static void dm1105_hw_exit(struct dm1105_dev *dev)
+{
+       dm1105_disable_irqs(dev);
+
+       /* IR disable */
+       dm_writeb(DM1105_IRCTR, 0);
+       dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK);
+
+       dm1105_dma_unmap(dev);
+}
+
+static struct stv0299_config sharp_z0194a_config = {
+       .demod_address = 0x68,
+       .inittab = sharp_z0194a_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
+static struct stv0288_config earda_config = {
+       .demod_address = 0x68,
+       .min_delay_ms = 100,
+};
+
+static struct si21xx_config serit_config = {
+       .demod_address = 0x68,
+       .min_delay_ms = 100,
+
+};
+
+static struct cx24116_config serit_sp2633_config = {
+       .demod_address = 0x55,
+};
+
+static struct ds3000_config dvbworld_ds3000_config = {
+       .demod_address = 0x68,
+};
+
+static int __devinit frontend_init(struct dm1105_dev *dev)
+{
+       int ret;
+
+       switch (dev->boardnr) {
+       case DM1105_BOARD_UNBRANDED_I2C_ON_GPIO:
+               dm1105_gpio_enable(dev, GPIO15, 1);
+               dm1105_gpio_clear(dev, GPIO15);
+               msleep(100);
+               dm1105_gpio_set(dev, GPIO15);
+               msleep(200);
+               dev->fe = dvb_attach(
+                       stv0299_attach, &sharp_z0194a_config,
+                       &dev->i2c_bb_adap);
+               if (dev->fe) {
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+                       dvb_attach(dvb_pll_attach, dev->fe, 0x60,
+                                       &dev->i2c_bb_adap, DVB_PLL_OPERA1);
+                       break;
+               }
+
+               dev->fe = dvb_attach(
+                       stv0288_attach, &earda_config,
+                       &dev->i2c_bb_adap);
+               if (dev->fe) {
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+                       dvb_attach(stb6000_attach, dev->fe, 0x61,
+                                       &dev->i2c_bb_adap);
+                       break;
+               }
+
+               dev->fe = dvb_attach(
+                       si21xx_attach, &serit_config,
+                       &dev->i2c_bb_adap);
+               if (dev->fe)
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+               break;
+       case DM1105_BOARD_DVBWORLD_2004:
+               dev->fe = dvb_attach(
+                       cx24116_attach, &serit_sp2633_config,
+                       &dev->i2c_adap);
+               if (dev->fe) {
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+                       break;
+               }
+
+               dev->fe = dvb_attach(
+                       ds3000_attach, &dvbworld_ds3000_config,
+                       &dev->i2c_adap);
+               if (dev->fe)
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+
+               break;
+       case DM1105_BOARD_DVBWORLD_2002:
+       case DM1105_BOARD_AXESS_DM05:
+       default:
+               dev->fe = dvb_attach(
+                       stv0299_attach, &sharp_z0194a_config,
+                       &dev->i2c_adap);
+               if (dev->fe) {
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+                       dvb_attach(dvb_pll_attach, dev->fe, 0x60,
+                                       &dev->i2c_adap, DVB_PLL_OPERA1);
+                       break;
+               }
+
+               dev->fe = dvb_attach(
+                       stv0288_attach, &earda_config,
+                       &dev->i2c_adap);
+               if (dev->fe) {
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+                       dvb_attach(stb6000_attach, dev->fe, 0x61,
+                                       &dev->i2c_adap);
+                       break;
+               }
+
+               dev->fe = dvb_attach(
+                       si21xx_attach, &serit_config,
+                       &dev->i2c_adap);
+               if (dev->fe)
+                       dev->fe->ops.set_voltage = dm1105_set_voltage;
+
+       }
+
+       if (!dev->fe) {
+               dev_err(&dev->pdev->dev, "could not attach frontend\n");
+               return -ENODEV;
+       }
+
+       ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe);
+       if (ret < 0) {
+               if (dev->fe->ops.release)
+                       dev->fe->ops.release(dev->fe);
+               dev->fe = NULL;
+               return ret;
+       }
+
+       return 0;
+}
+
+static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac)
+{
+       static u8 command[1] = { 0x28 };
+
+       struct i2c_msg msg[] = {
+               {
+                       .addr = IIC_24C01_addr >> 1,
+                       .flags = 0,
+                       .buf = command,
+                       .len = 1
+               }, {
+                       .addr = IIC_24C01_addr >> 1,
+                       .flags = I2C_M_RD,
+                       .buf = mac,
+                       .len = 6
+               },
+       };
+
+       dm1105_i2c_xfer(&dev->i2c_adap, msg , 2);
+       dev_info(&dev->pdev->dev, "MAC %pM\n", mac);
+}
+
+static int __devinit dm1105_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+       struct dm1105_dev *dev;
+       struct dvb_adapter *dvb_adapter;
+       struct dvb_demux *dvbdemux;
+       struct dmx_demux *dmx;
+       int ret = -ENOMEM;
+       int i;
+
+       dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       /* board config */
+       dev->nr = dm1105_devcount;
+       dev->boardnr = UNSET;
+       if (card[dev->nr] < ARRAY_SIZE(dm1105_boards))
+               dev->boardnr = card[dev->nr];
+       for (i = 0; UNSET == dev->boardnr &&
+                               i < ARRAY_SIZE(dm1105_subids); i++)
+               if (pdev->subsystem_vendor ==
+                       dm1105_subids[i].subvendor &&
+                               pdev->subsystem_device ==
+                                       dm1105_subids[i].subdevice)
+                       dev->boardnr = dm1105_subids[i].card;
+
+       if (UNSET == dev->boardnr) {
+               dev->boardnr = DM1105_BOARD_UNKNOWN;
+               dm1105_card_list(pdev);
+       }
+
+       dm1105_devcount++;
+       dev->pdev = pdev;
+       dev->buffer_size = 5 * DM1105_DMA_BYTES;
+       dev->PacketErrorCount = 0;
+       dev->dmarst = 0;
+
+       ret = pci_enable_device(pdev);
+       if (ret < 0)
+               goto err_kfree;
+
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       pci_set_master(pdev);
+
+       ret = pci_request_regions(pdev, DRIVER_NAME);
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
+       if (!dev->io_mem) {
+               ret = -EIO;
+               goto err_pci_release_regions;
+       }
+
+       spin_lock_init(&dev->lock);
+       pci_set_drvdata(pdev, dev);
+
+       ret = dm1105_hw_init(dev);
+       if (ret < 0)
+               goto err_pci_iounmap;
+
+       /* i2c */
+       i2c_set_adapdata(&dev->i2c_adap, dev);
+       strcpy(dev->i2c_adap.name, DRIVER_NAME);
+       dev->i2c_adap.owner = THIS_MODULE;
+       dev->i2c_adap.dev.parent = &pdev->dev;
+       dev->i2c_adap.algo = &dm1105_algo;
+       dev->i2c_adap.algo_data = dev;
+       ret = i2c_add_adapter(&dev->i2c_adap);
+
+       if (ret < 0)
+               goto err_dm1105_hw_exit;
+
+       i2c_set_adapdata(&dev->i2c_bb_adap, dev);
+       strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME);
+       dev->i2c_bb_adap.owner = THIS_MODULE;
+       dev->i2c_bb_adap.dev.parent = &pdev->dev;
+       dev->i2c_bb_adap.algo_data = &dev->i2c_bit;
+       dev->i2c_bit.data = dev;
+       dev->i2c_bit.setsda = dm1105_setsda;
+       dev->i2c_bit.setscl = dm1105_setscl;
+       dev->i2c_bit.getsda = dm1105_getsda;
+       dev->i2c_bit.getscl = dm1105_getscl;
+       dev->i2c_bit.udelay = 10;
+       dev->i2c_bit.timeout = 10;
+
+       /* Raise SCL and SDA */
+       dm1105_setsda(dev, 1);
+       dm1105_setscl(dev, 1);
+
+       ret = i2c_bit_add_bus(&dev->i2c_bb_adap);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       /* dvb */
+       ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,
+                                       THIS_MODULE, &pdev->dev, adapter_nr);
+       if (ret < 0)
+               goto err_i2c_del_adapters;
+
+       dvb_adapter = &dev->dvb_adapter;
+
+       dm1105_read_mac(dev, dvb_adapter->proposed_mac);
+
+       dvbdemux = &dev->demux;
+       dvbdemux->filternum = 256;
+       dvbdemux->feednum = 256;
+       dvbdemux->start_feed = dm1105_start_feed;
+       dvbdemux->stop_feed = dm1105_stop_feed;
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+                       DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+       ret = dvb_dmx_init(dvbdemux);
+       if (ret < 0)
+               goto err_dvb_unregister_adapter;
+
+       dmx = &dvbdemux->dmx;
+       dev->dmxdev.filternum = 256;
+       dev->dmxdev.demux = dmx;
+       dev->dmxdev.capabilities = 0;
+
+       ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter);
+       if (ret < 0)
+               goto err_dvb_dmx_release;
+
+       dev->hw_frontend.source = DMX_FRONTEND_0;
+
+       ret = dmx->add_frontend(dmx, &dev->hw_frontend);
+       if (ret < 0)
+               goto err_dvb_dmxdev_release;
+
+       dev->mem_frontend.source = DMX_MEMORY_FE;
+
+       ret = dmx->add_frontend(dmx, &dev->mem_frontend);
+       if (ret < 0)
+               goto err_remove_hw_frontend;
+
+       ret = dmx->connect_frontend(dmx, &dev->hw_frontend);
+       if (ret < 0)
+               goto err_remove_mem_frontend;
+
+       ret = dvb_net_init(dvb_adapter, &dev->dvbnet, dmx);
+       if (ret < 0)
+               goto err_disconnect_frontend;
+
+       ret = frontend_init(dev);
+       if (ret < 0)
+               goto err_dvb_net;
+
+       dm1105_ir_init(dev);
+
+       INIT_WORK(&dev->work, dm1105_dmx_buffer);
+       sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
+       dev->wq = create_singlethread_workqueue(dev->wqn);
+       if (!dev->wq)
+               goto err_dvb_net;
+
+       ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,
+                                               DRIVER_NAME, dev);
+       if (ret < 0)
+               goto err_workqueue;
+
+       return 0;
+
+err_workqueue:
+       destroy_workqueue(dev->wq);
+err_dvb_net:
+       dvb_net_release(&dev->dvbnet);
+err_disconnect_frontend:
+       dmx->disconnect_frontend(dmx);
+err_remove_mem_frontend:
+       dmx->remove_frontend(dmx, &dev->mem_frontend);
+err_remove_hw_frontend:
+       dmx->remove_frontend(dmx, &dev->hw_frontend);
+err_dvb_dmxdev_release:
+       dvb_dmxdev_release(&dev->dmxdev);
+err_dvb_dmx_release:
+       dvb_dmx_release(dvbdemux);
+err_dvb_unregister_adapter:
+       dvb_unregister_adapter(dvb_adapter);
+err_i2c_del_adapters:
+       i2c_del_adapter(&dev->i2c_bb_adap);
+err_i2c_del_adapter:
+       i2c_del_adapter(&dev->i2c_adap);
+err_dm1105_hw_exit:
+       dm1105_hw_exit(dev);
+err_pci_iounmap:
+       pci_iounmap(pdev, dev->io_mem);
+err_pci_release_regions:
+       pci_release_regions(pdev);
+err_pci_disable_device:
+       pci_disable_device(pdev);
+err_kfree:
+       pci_set_drvdata(pdev, NULL);
+       kfree(dev);
+       return ret;
+}
+
+static void __devexit dm1105_remove(struct pci_dev *pdev)
+{
+       struct dm1105_dev *dev = pci_get_drvdata(pdev);
+       struct dvb_adapter *dvb_adapter = &dev->dvb_adapter;
+       struct dvb_demux *dvbdemux = &dev->demux;
+       struct dmx_demux *dmx = &dvbdemux->dmx;
+
+       dm1105_ir_exit(dev);
+       dmx->close(dmx);
+       dvb_net_release(&dev->dvbnet);
+       if (dev->fe)
+               dvb_unregister_frontend(dev->fe);
+
+       dmx->disconnect_frontend(dmx);
+       dmx->remove_frontend(dmx, &dev->mem_frontend);
+       dmx->remove_frontend(dmx, &dev->hw_frontend);
+       dvb_dmxdev_release(&dev->dmxdev);
+       dvb_dmx_release(dvbdemux);
+       dvb_unregister_adapter(dvb_adapter);
+       if (&dev->i2c_adap)
+               i2c_del_adapter(&dev->i2c_adap);
+
+       dm1105_hw_exit(dev);
+       synchronize_irq(pdev->irq);
+       free_irq(pdev->irq, dev);
+       pci_iounmap(pdev, dev->io_mem);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+       dm1105_devcount--;
+       kfree(dev);
+}
+
+static struct pci_device_id dm1105_id_table[] __devinitdata = {
+       {
+               .vendor = PCI_VENDOR_ID_TRIGEM,
+               .device = PCI_DEVICE_ID_DM1105,
+               .subvendor = PCI_ANY_ID,
+               .subdevice = PCI_ANY_ID,
+       }, {
+               .vendor = PCI_VENDOR_ID_AXESS,
+               .device = PCI_DEVICE_ID_DM05,
+               .subvendor = PCI_ANY_ID,
+               .subdevice = PCI_ANY_ID,
+       }, {
+               /* empty */
+       },
+};
+
+MODULE_DEVICE_TABLE(pci, dm1105_id_table);
+
+static struct pci_driver dm1105_driver = {
+       .name = DRIVER_NAME,
+       .id_table = dm1105_id_table,
+       .probe = dm1105_probe,
+       .remove = __devexit_p(dm1105_remove),
+};
+
+static int __init dm1105_init(void)
+{
+       return pci_register_driver(&dm1105_driver);
+}
+
+static void __exit dm1105_exit(void)
+{
+       pci_unregister_driver(&dm1105_driver);
+}
+
+module_init(dm1105_init);
+module_exit(dm1105_exit);
+
+MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
+MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/mantis/Kconfig b/drivers/media/pci/mantis/Kconfig
new file mode 100644 (file)
index 0000000..a13a505
--- /dev/null
@@ -0,0 +1,38 @@
+config MANTIS_CORE
+       tristate "Mantis/Hopper PCI bridge based devices"
+       depends on PCI && I2C && INPUT && RC_CORE
+
+       help
+         Support for PCI cards based on the Mantis and Hopper PCi bridge.
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_MANTIS
+       tristate "MANTIS based cards"
+       depends on MANTIS_CORE && DVB_CORE && PCI && I2C
+       select DVB_MB86A16 if !DVB_FE_CUSTOMISE
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_STB0899 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       select DVB_TDA665x if !DVB_FE_CUSTOMISE
+       select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+       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.
+
+config DVB_HOPPER
+       tristate "HOPPER based cards"
+       depends on MANTIS_CORE && DVB_CORE && PCI && I2C
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select DVB_PLL
+       help
+         Support for PCI cards based on the Hopper  PCI bridge.
+         Say Y when you have a Hopper based DVB card and want to use it.
+
+         If unsure say N
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile
new file mode 100644 (file)
index 0000000..f715051
--- /dev/null
@@ -0,0 +1,28 @@
+mantis_core-objs :=    mantis_ioc.o    \
+                       mantis_uart.o   \
+                       mantis_dma.o    \
+                       mantis_pci.o    \
+                       mantis_i2c.o    \
+                       mantis_dvb.o    \
+                       mantis_evm.o    \
+                       mantis_hif.o    \
+                       mantis_ca.o     \
+                       mantis_pcmcia.o \
+                       mantis_input.o
+
+mantis-objs    :=      mantis_cards.o  \
+                       mantis_vp1033.o \
+                       mantis_vp1034.o \
+                       mantis_vp1041.o \
+                       mantis_vp2033.o \
+                       mantis_vp2040.o \
+                       mantis_vp3030.o
+
+hopper-objs    :=      hopper_cards.o  \
+                       hopper_vp3028.o
+
+obj-$(CONFIG_MANTIS_CORE)      += mantis_core.o
+obj-$(CONFIG_DVB_MANTIS)       += mantis.o
+obj-$(CONFIG_DVB_HOPPER)       += hopper.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
new file mode 100644 (file)
index 0000000..cc0251e
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+       Hopper PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "hopper_vp3028.h"
+#include "mantis_dma.h"
+#include "mantis_dvb.h"
+#include "mantis_uart.h"
+#include "mantis_ioc.h"
+#include "mantis_pci.h"
+#include "mantis_i2c.h"
+#include "mantis_reg.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
+
+#define DRIVER_NAME    "Hopper"
+
+static char *label[10] = {
+       "DMA",
+       "IRQ-0",
+       "IRQ-1",
+       "OCERR",
+       "PABRT",
+       "RIPRR",
+       "PPERR",
+       "FTRGT",
+       "RISCI",
+       "RACK"
+};
+
+static int devs;
+
+static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
+{
+       u32 stat = 0, mask = 0;
+       u32 rst_stat = 0, rst_mask = 0;
+
+       struct mantis_pci *mantis;
+       struct mantis_ca *ca;
+
+       mantis = (struct mantis_pci *) dev_id;
+       if (unlikely(mantis == NULL)) {
+               dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
+               return IRQ_NONE;
+       }
+       ca = mantis->mantis_ca;
+
+       stat = mmread(MANTIS_INT_STAT);
+       mask = mmread(MANTIS_INT_MASK);
+       if (!(stat & mask))
+               return IRQ_NONE;
+
+       rst_mask  = MANTIS_GPIF_WRACK  |
+                   MANTIS_GPIF_OTHERR |
+                   MANTIS_SBUF_WSTO   |
+                   MANTIS_GPIF_EXTIRQ;
+
+       rst_stat  = mmread(MANTIS_GPIF_STATUS);
+       rst_stat &= rst_mask;
+       mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
+       mantis->mantis_int_stat = stat;
+       mantis->mantis_int_mask = mask;
+       dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
+       if (stat & MANTIS_INT_RISCEN) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
+       }
+       if (stat & MANTIS_INT_IRQ0) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
+               mantis->gpif_status = rst_stat;
+               wake_up(&ca->hif_write_wq);
+               schedule_work(&ca->hif_evm_work);
+       }
+       if (stat & MANTIS_INT_IRQ1) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
+               schedule_work(&mantis->uart_work);
+       }
+       if (stat & MANTIS_INT_OCERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
+       }
+       if (stat & MANTIS_INT_PABORT) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
+       }
+       if (stat & MANTIS_INT_RIPERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
+       }
+       if (stat & MANTIS_INT_PPERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
+       }
+       if (stat & MANTIS_INT_FTRGT) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
+       }
+       if (stat & MANTIS_INT_RISCI) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
+               mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+               tasklet_schedule(&mantis->tasklet);
+       }
+       if (stat & MANTIS_INT_I2CDONE) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+               wake_up(&mantis->i2c_wq);
+       }
+       mmwrite(stat, MANTIS_INT_STAT);
+       stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
+                 MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
+                 MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
+                 MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
+                 MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
+                 MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1    |
+                 MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
+                 MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
+                 MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
+                 MANTIS_INT_RISCI);
+
+       if (stat)
+               dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
+
+       dprintk(MANTIS_DEBUG, 0, "\n");
+       return IRQ_HANDLED;
+}
+
+static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+       struct mantis_pci *mantis;
+       struct mantis_hwconfig *config;
+       int err = 0;
+
+       mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
+       if (mantis == NULL) {
+               printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+               err = -ENOMEM;
+               goto fail0;
+       }
+
+       mantis->num             = devs;
+       mantis->verbose         = verbose;
+       mantis->pdev            = pdev;
+       config                  = (struct mantis_hwconfig *) pci_id->driver_data;
+       config->irq_handler     = &hopper_irq_handler;
+       mantis->hwconfig        = config;
+
+       err = mantis_pci_init(mantis);
+       if (err) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
+               goto fail1;
+       }
+
+       err = mantis_stream_control(mantis, STREAM_TO_HIF);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
+               goto fail1;
+       }
+
+       err = mantis_i2c_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
+               goto fail2;
+       }
+
+       err = mantis_get_mac(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
+               goto fail2;
+       }
+
+       err = mantis_dma_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
+               goto fail3;
+       }
+
+       err = mantis_dvb_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
+               goto fail4;
+       }
+       devs++;
+
+       return err;
+
+fail4:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
+       mantis_dma_exit(mantis);
+
+fail3:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
+       mantis_i2c_exit(mantis);
+
+fail2:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
+       mantis_pci_exit(mantis);
+
+fail1:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
+       kfree(mantis);
+
+fail0:
+       return err;
+}
+
+static void __devexit hopper_pci_remove(struct pci_dev *pdev)
+{
+       struct mantis_pci *mantis = pci_get_drvdata(pdev);
+
+       if (mantis) {
+               mantis_dvb_exit(mantis);
+               mantis_dma_exit(mantis);
+               mantis_i2c_exit(mantis);
+               mantis_pci_exit(mantis);
+               kfree(mantis);
+       }
+       return;
+
+}
+
+static struct pci_device_id hopper_pci_table[] = {
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, hopper_pci_table);
+
+static struct pci_driver hopper_pci_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = hopper_pci_table,
+       .probe          = hopper_pci_probe,
+       .remove         = hopper_pci_remove,
+};
+
+static int __devinit hopper_init(void)
+{
+       return pci_register_driver(&hopper_pci_driver);
+}
+
+static void __devexit hopper_exit(void)
+{
+       return pci_unregister_driver(&hopper_pci_driver);
+}
+
+module_init(hopper_init);
+module_exit(hopper_exit);
+
+MODULE_DESCRIPTION("HOPPER driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c
new file mode 100644 (file)
index 0000000..68a29f8
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+       Hopper VP-3028 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "zl10353.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "hopper_vp3028.h"
+
+struct zl10353_config hopper_vp3028_config = {
+       .demod_address  = 0x0f,
+};
+
+#define MANTIS_MODEL_NAME      "VP-3028"
+#define MANTIS_DEV_TYPE                "DVB-T"
+
+static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter     = &mantis->adapter;
+       struct mantis_hwconfig *config  = mantis->hwconfig;
+       int err = 0;
+
+       mantis_gpio_set_bits(mantis, config->reset, 0);
+       msleep(100);
+       err = mantis_frontend_power(mantis, POWER_ON);
+       msleep(100);
+       mantis_gpio_set_bits(mantis, config->reset, 1);
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               msleep(250);
+               dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
+               fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter);
+
+               if (!fe)
+                       return -1;
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+       dprintk(MANTIS_ERROR, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp3028_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_188,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp3028_frontend_init,
+       .power          = GPIF_A00,
+       .reset          = GPIF_A03,
+};
diff --git a/drivers/media/pci/mantis/hopper_vp3028.h b/drivers/media/pci/mantis/hopper_vp3028.h
new file mode 100644 (file)
index 0000000..5723949
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Hopper VP-3028 driver
+
+       Copyright (C) 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_VP3028_H
+#define __MANTIS_VP3028_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_3028_DVB_T   0x0028
+
+extern struct mantis_hwconfig vp3028_config;
+
+#endif /* __MANTIS_VP3028_H */
diff --git a/drivers/media/pci/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c
new file mode 100644 (file)
index 0000000..3d70469
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h"
+#include "mantis_hif.h"
+#include "mantis_reg.h"
+
+#include "mantis_ca.h"
+
+static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return mantis_hif_read_mem(ca, addr);
+}
+
+static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return mantis_hif_write_mem(ca, addr, data);
+}
+
+static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return mantis_hif_read_iom(ca, addr);
+}
+
+static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return mantis_hif_write_iom(ca, addr, data);
+}
+
+static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
+       udelay(500); /* Wait.. */
+       mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
+       udelay(500);
+       mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
+       msleep(1000);
+       dvb_ca_en50221_camready_irq(&ca->en50221, 0);
+
+       return 0;
+}
+
+static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
+
+       return 0;
+}
+
+static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
+/*     mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */
+
+       return 0;
+}
+
+static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+{
+       struct mantis_ca *ca = en50221->data;
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
+
+       if (ca->slot_state == MODULE_INSERTED) {
+               dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
+               return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+       } else {
+               dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
+       }
+
+       return 0;
+}
+
+int mantis_ca_init(struct mantis_pci *mantis)
+{
+       struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter;
+       struct mantis_ca *ca;
+       int ca_flags = 0, result;
+
+       dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
+       ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
+       if (!ca) {
+               dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
+               result = -ENOMEM;
+               goto err;
+       }
+
+       ca->ca_priv             = mantis;
+       mantis->mantis_ca       = ca;
+       ca_flags                = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
+       /* register CA interface */
+       ca->en50221.owner               = THIS_MODULE;
+       ca->en50221.read_attribute_mem  = mantis_ca_read_attr_mem;
+       ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem;
+       ca->en50221.read_cam_control    = mantis_ca_read_cam_ctl;
+       ca->en50221.write_cam_control   = mantis_ca_write_cam_ctl;
+       ca->en50221.slot_reset          = mantis_ca_slot_reset;
+       ca->en50221.slot_shutdown       = mantis_ca_slot_shutdown;
+       ca->en50221.slot_ts_enable      = mantis_ts_control;
+       ca->en50221.poll_slot_status    = mantis_slot_status;
+       ca->en50221.data                = ca;
+
+       mutex_init(&ca->ca_lock);
+
+       init_waitqueue_head(&ca->hif_data_wq);
+       init_waitqueue_head(&ca->hif_opdone_wq);
+       init_waitqueue_head(&ca->hif_write_wq);
+
+       dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
+       result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
+       if (result != 0) {
+               dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
+               goto err;
+       }
+       dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
+       mantis_evmgr_init(ca);
+       return 0;
+err:
+       kfree(ca);
+       return result;
+}
+EXPORT_SYMBOL_GPL(mantis_ca_init);
+
+void mantis_ca_exit(struct mantis_pci *mantis)
+{
+       struct mantis_ca *ca = mantis->mantis_ca;
+
+       dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
+
+       mantis_evmgr_exit(ca);
+       dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
+       if (ca)
+               dvb_ca_en50221_release(&ca->en50221);
+
+       kfree(ca);
+}
+EXPORT_SYMBOL_GPL(mantis_ca_exit);
diff --git a/drivers/media/pci/mantis/mantis_ca.h b/drivers/media/pci/mantis/mantis_ca.h
new file mode 100644 (file)
index 0000000..dc63e55
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_CA_H
+#define __MANTIS_CA_H
+
+extern int mantis_ca_init(struct mantis_pci *mantis);
+extern void mantis_ca_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_CA_H */
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
new file mode 100644 (file)
index 0000000..0207d1f
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+
+#include "mantis_vp1033.h"
+#include "mantis_vp1034.h"
+#include "mantis_vp1041.h"
+#include "mantis_vp2033.h"
+#include "mantis_vp2040.h"
+#include "mantis_vp3030.h"
+
+#include "mantis_dma.h"
+#include "mantis_ca.h"
+#include "mantis_dvb.h"
+#include "mantis_uart.h"
+#include "mantis_ioc.h"
+#include "mantis_pci.h"
+#include "mantis_i2c.h"
+#include "mantis_reg.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
+
+static int devs;
+
+#define DRIVER_NAME    "Mantis"
+
+static char *label[10] = {
+       "DMA",
+       "IRQ-0",
+       "IRQ-1",
+       "OCERR",
+       "PABRT",
+       "RIPRR",
+       "PPERR",
+       "FTRGT",
+       "RISCI",
+       "RACK"
+};
+
+static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
+{
+       u32 stat = 0, mask = 0;
+       u32 rst_stat = 0, rst_mask = 0;
+
+       struct mantis_pci *mantis;
+       struct mantis_ca *ca;
+
+       mantis = (struct mantis_pci *) dev_id;
+       if (unlikely(mantis == NULL)) {
+               dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
+               return IRQ_NONE;
+       }
+       ca = mantis->mantis_ca;
+
+       stat = mmread(MANTIS_INT_STAT);
+       mask = mmread(MANTIS_INT_MASK);
+       if (!(stat & mask))
+               return IRQ_NONE;
+
+       rst_mask  = MANTIS_GPIF_WRACK  |
+                   MANTIS_GPIF_OTHERR |
+                   MANTIS_SBUF_WSTO   |
+                   MANTIS_GPIF_EXTIRQ;
+
+       rst_stat  = mmread(MANTIS_GPIF_STATUS);
+       rst_stat &= rst_mask;
+       mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
+       mantis->mantis_int_stat = stat;
+       mantis->mantis_int_mask = mask;
+       dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
+       if (stat & MANTIS_INT_RISCEN) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
+       }
+       if (stat & MANTIS_INT_IRQ0) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
+               mantis->gpif_status = rst_stat;
+               wake_up(&ca->hif_write_wq);
+               schedule_work(&ca->hif_evm_work);
+       }
+       if (stat & MANTIS_INT_IRQ1) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
+               schedule_work(&mantis->uart_work);
+       }
+       if (stat & MANTIS_INT_OCERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
+       }
+       if (stat & MANTIS_INT_PABORT) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
+       }
+       if (stat & MANTIS_INT_RIPERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
+       }
+       if (stat & MANTIS_INT_PPERR) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
+       }
+       if (stat & MANTIS_INT_FTRGT) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
+       }
+       if (stat & MANTIS_INT_RISCI) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
+               mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+               tasklet_schedule(&mantis->tasklet);
+       }
+       if (stat & MANTIS_INT_I2CDONE) {
+               dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+               wake_up(&mantis->i2c_wq);
+       }
+       mmwrite(stat, MANTIS_INT_STAT);
+       stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
+                 MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
+                 MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
+                 MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
+                 MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
+                 MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1    |
+                 MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
+                 MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
+                 MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
+                 MANTIS_INT_RISCI);
+
+       if (stat)
+               dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
+
+       dprintk(MANTIS_DEBUG, 0, "\n");
+       return IRQ_HANDLED;
+}
+
+static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+       struct mantis_pci *mantis;
+       struct mantis_hwconfig *config;
+       int err = 0;
+
+       mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
+       if (mantis == NULL) {
+               printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+               err = -ENOMEM;
+               goto fail0;
+       }
+
+       mantis->num             = devs;
+       mantis->verbose         = verbose;
+       mantis->pdev            = pdev;
+       config                  = (struct mantis_hwconfig *) pci_id->driver_data;
+       config->irq_handler     = &mantis_irq_handler;
+       mantis->hwconfig        = config;
+
+       err = mantis_pci_init(mantis);
+       if (err) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
+               goto fail1;
+       }
+
+       err = mantis_stream_control(mantis, STREAM_TO_HIF);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
+               goto fail1;
+       }
+
+       err = mantis_i2c_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
+               goto fail2;
+       }
+
+       err = mantis_get_mac(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
+               goto fail2;
+       }
+
+       err = mantis_dma_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
+               goto fail3;
+       }
+
+       err = mantis_dvb_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
+               goto fail4;
+       }
+       err = mantis_uart_init(mantis);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err);
+               goto fail6;
+       }
+
+       devs++;
+
+       return err;
+
+
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
+       mantis_uart_exit(mantis);
+
+fail6:
+fail4:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
+       mantis_dma_exit(mantis);
+
+fail3:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
+       mantis_i2c_exit(mantis);
+
+fail2:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
+       mantis_pci_exit(mantis);
+
+fail1:
+       dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
+       kfree(mantis);
+
+fail0:
+       return err;
+}
+
+static void __devexit mantis_pci_remove(struct pci_dev *pdev)
+{
+       struct mantis_pci *mantis = pci_get_drvdata(pdev);
+
+       if (mantis) {
+
+               mantis_uart_exit(mantis);
+               mantis_dvb_exit(mantis);
+               mantis_dma_exit(mantis);
+               mantis_i2c_exit(mantis);
+               mantis_pci_exit(mantis);
+               kfree(mantis);
+       }
+       return;
+}
+
+static struct pci_device_id mantis_pci_table[] = {
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config),
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config),
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config),
+       MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config),
+       MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config),
+       MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config),
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config),
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config),
+       MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config),
+       MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config),
+       MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config),
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, mantis_pci_table);
+
+static struct pci_driver mantis_pci_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = mantis_pci_table,
+       .probe          = mantis_pci_probe,
+       .remove         = mantis_pci_remove,
+};
+
+static int __devinit mantis_init(void)
+{
+       return pci_register_driver(&mantis_pci_driver);
+}
+
+static void __devexit mantis_exit(void)
+{
+       return pci_unregister_driver(&mantis_pci_driver);
+}
+
+module_init(mantis_init);
+module_exit(mantis_exit);
+
+MODULE_DESCRIPTION("MANTIS driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
new file mode 100644 (file)
index 0000000..f2410cf
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include "mantis_uart.h"
+
+#include "mantis_link.h"
+
+#define MANTIS_ERROR           0
+#define MANTIS_NOTICE          1
+#define MANTIS_INFO            2
+#define MANTIS_DEBUG           3
+#define MANTIS_TMG             9
+
+#define dprintk(y, z, format, arg...) do {                                                             \
+       if (z) {                                                                                        \
+               if      ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y))                     \
+                       printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);      \
+               else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y))                    \
+                       printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);   \
+               else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y))                      \
+                       printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);     \
+               else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y))                     \
+                       printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);    \
+               else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y))                       \
+                       printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);    \
+       } else {                                                                                        \
+               if (mantis->verbose > 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->mmio + (addr)))
+#define mmread(addr)           mread(mantis->mmio + (addr))
+
+#define MANTIS_TS_188          0
+#define MANTIS_TS_204          1
+
+#define TWINHAN_TECHNOLOGIES   0x1822
+#define MANTIS                 0x4e35
+
+#define TECHNISAT              0x1ae4
+#define TERRATEC               0x153b
+
+#define MAKE_ENTRY(__subven, __subdev, __configptr) {                  \
+               .vendor         = TWINHAN_TECHNOLOGIES,                 \
+               .device         = MANTIS,                               \
+               .subvendor      = (__subven),                           \
+               .subdevice      = (__subdev),                           \
+               .driver_data    = (unsigned long) (__configptr)         \
+}
+
+enum mantis_i2c_mode {
+       MANTIS_PAGE_MODE = 0,
+       MANTIS_BYTE_MODE,
+};
+
+struct mantis_pci;
+
+struct mantis_hwconfig {
+       char                    *model_name;
+       char                    *dev_type;
+       u32                     ts_size;
+
+       enum mantis_baud        baud_rate;
+       enum mantis_parity      parity;
+       u32                     bytes;
+
+       irqreturn_t (*irq_handler)(int irq, void *dev_id);
+       int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe);
+
+       u8                      power;
+       u8                      reset;
+
+       enum mantis_i2c_mode    i2c_mode;
+};
+
+struct mantis_pci {
+       unsigned int            verbose;
+
+       /*      PCI stuff               */
+       u16                     vendor_id;
+       u16                     device_id;
+       u16                     subsystem_vendor;
+       u16                     subsystem_device;
+
+       u8                      latency;
+
+       struct pci_dev          *pdev;
+
+       unsigned long           mantis_addr;
+       void __iomem            *mmio;
+
+       u8                      irq;
+       u8                      revision;
+
+       unsigned int            num;
+
+       /*      RISC Core               */
+       u32                     busy_block;
+       u32                     last_block;
+       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;
+       struct mutex            i2c_lock;
+
+       /*      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_hwconfig  *hwconfig;
+
+       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             */
+       u32                     gpio_status;
+
+       u32                     gpif_status;
+
+       struct mantis_ca        *mantis_ca;
+
+       wait_queue_head_t       uart_wq;
+       struct work_struct      uart_work;
+       spinlock_t              uart_lock;
+
+       struct rc_dev           *rc;
+       char                    input_name[80];
+       char                    input_phys[80];
+};
+
+#define MANTIS_HIF_STATUS      (mantis->gpio_status)
+
+#endif /* __MANTIS_COMMON_H */
diff --git a/drivers/media/pci/mantis/mantis_core.c b/drivers/media/pci/mantis/mantis_core.c
new file mode 100644 (file)
index 0000000..684d906
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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"
+#include "mantis_vp1033.h"
+#include "mantis_vp1034.h"
+#include "mantis_vp1041.h"
+#include "mantis_vp2033.h"
+#include "mantis_vp2040.h"
+#include "mantis_vp3030.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
+               },
+       };
+
+       err = i2c_transfer(&mantis->adapter, msg, 2);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_ERROR, 1,
+                       "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
+                       err, data[0], data[1]);
+
+               return err;
+       }
+
+       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
+       };
+
+       err = i2c_transfer(&mantis->adapter, &msg, 1);
+       if (err < 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_mac_address(struct mantis_pci *mantis)
+{
+       int err;
+
+       mantis->mac_address[0] = 0x08;
+       err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
+
+               return err;
+       }
+       dprintk(verbose, MANTIS_ERROR, 0,
+               "    MAC Address=[%pM]\n", mantis->mac_address);
+
+       return 0;
+}
+
+#define MANTIS_MODEL_UNKNOWN   "UNKNOWN"
+#define MANTIS_DEV_UNKNOWN     "UNKNOWN"
+
+struct mantis_hwconfig unknown_device = {
+       .model_name     = MANTIS_MODEL_UNKNOWN,
+       .dev_type       = MANTIS_DEV_UNKNOWN,
+};
+
+static void mantis_load_config(struct mantis_pci *mantis)
+{
+       switch (mantis->subsystem_device) {
+       case MANTIS_VP_1033_DVB_S:      /* VP-1033 */
+               mantis->hwconfig = &vp1033_mantis_config;
+               break;
+       case MANTIS_VP_1034_DVB_S:      /* VP-1034 */
+               mantis->hwconfig = &vp1034_mantis_config;
+               break;
+       case MANTIS_VP_1041_DVB_S2:     /* VP-1041 */
+       case TECHNISAT_SKYSTAR_HD2:
+               mantis->hwconfig = &vp1041_mantis_config;
+               break;
+       case MANTIS_VP_2033_DVB_C:      /* VP-2033 */
+               mantis->hwconfig = &vp2033_mantis_config;
+               break;
+       case MANTIS_VP_2040_DVB_C:      /* VP-2040 */
+       case CINERGY_C: /* VP-2040 clone */
+       case TECHNISAT_CABLESTAR_HD2:
+               mantis->hwconfig = &vp2040_mantis_config;
+               break;
+       case MANTIS_VP_3030_DVB_T:      /* VP-3030 */
+               mantis->hwconfig = &vp3030_mantis_config;
+               break;
+       default:
+               mantis->hwconfig = &unknown_device;
+               break;
+       }
+}
+
+int mantis_core_init(struct mantis_pci *mantis)
+{
+       int err = 0;
+
+       mantis_load_config(mantis);
+       dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
+               mantis->hwconfig->model_name, mantis->hwconfig->dev_type,
+               mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));
+       dprintk(verbose, MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
+               mantis->revision,
+               mantis->subsystem_vendor, mantis->subsystem_device);
+       dprintk(verbose, MANTIS_ERROR, 0,
+               "irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
+               mantis->pdev->irq, mantis->latency,
+               mantis->mantis_addr, mantis->mantis_mmio);
+
+       err = mantis_i2c_init(mantis);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
+               return err;
+       }
+       err = get_mac_address(mantis);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
+               return err;
+       }
+       err = mantis_dma_init(mantis);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
+               return err;
+       }
+       err = mantis_dvb_init(mantis);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
+               return err;
+       }
+       err = mantis_uart_init(mantis);
+       if (err < 0) {
+               dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART 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");
+
+       mantis_uart_exit(mantis);
+       dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");
+
+       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;
+}
+
+/* Turn the given bit on or off. */
+void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+{
+       u32 cur;
+
+       cur = mmread(MANTIS_GPIF_ADDR);
+       if (value)
+               mantis->gpio_status = cur | (1 << bitpos);
+       else
+               mantis->gpio_status = cur & (~(1 << bitpos));
+
+       mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
+       mmwrite(0x00, MANTIS_GPIF_DOUT);
+       udelay(100);
+}
+
+/* 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/pci/mantis/mantis_core.h b/drivers/media/pci/mantis/mantis_core.h
new file mode 100644 (file)
index 0000000..833ee42
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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);
+
+#endif /* __MANTIS_CORE_H */
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
new file mode 100644 (file)
index 0000000..566c407
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <asm/page.h>
+#include <linux/vmalloc.h>
+#include <linux/pci.h>
+
+#include <asm/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_dma.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(risc_pos)           (risc_pos = 0)
+#define RISC_INSTR(risc_pos, opcode)   (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode))
+
+#define MANTIS_BUF_SIZE                (64 * 1024)
+#define MANTIS_BLOCK_BYTES      (MANTIS_BUF_SIZE / 4)
+#define MANTIS_DMA_TR_BYTES     (2 * 1024) /* upper limit: 4095 bytes. */
+#define MANTIS_BLOCK_COUNT     (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
+
+#define MANTIS_DMA_TR_UNITS     (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
+/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */
+#define MANTIS_RISC_SIZE       PAGE_SIZE /* RISC program must fit here. */
+
+int mantis_dma_exit(struct mantis_pci *mantis)
+{
+       if (mantis->buf_cpu) {
+               dprintk(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(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;
+}
+EXPORT_SYMBOL_GPL(mantis_dma_exit);
+
+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(MANTIS_ERROR, 1,
+                               "DMA buffer allocation failed");
+
+                       goto err;
+               }
+               dprintk(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(MANTIS_ERROR, 1,
+                               "RISC program allocation failed");
+
+                       mantis_dma_exit(mantis);
+
+                       goto err;
+               }
+               dprintk(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(MANTIS_ERROR, 1, "Out of memory (?) .....");
+       return -ENOMEM;
+}
+
+int mantis_dma_init(struct mantis_pci *mantis)
+{
+       int err = 0;
+
+       dprintk(MANTIS_DEBUG, 1, "Mantis DMA init");
+       if (mantis_alloc_buffers(mantis) < 0) {
+               dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
+
+               /* Stop RISC Engine */
+               mmwrite(0, MANTIS_DMA_CTL);
+
+               goto err;
+       }
+
+       return 0;
+err:
+       return err;
+}
+EXPORT_SYMBOL_GPL(mantis_dma_init);
+
+static inline void mantis_risc_program(struct mantis_pci *mantis)
+{
+       u32 buf_pos = 0;
+       u32 line, step;
+       u32 risc_pos;
+
+       dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
+       RISC_FLUSH(risc_pos);
+
+       dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u",
+               MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES);
+
+       for (line = 0; line < MANTIS_BLOCK_COUNT; line++) {
+               for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) {
+                       dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step);
+                       if (step == 0) {
+                               RISC_INSTR(risc_pos, RISC_WRITE |
+                                          RISC_IRQ     |
+                                          RISC_STATUS(line) |
+                                          MANTIS_DMA_TR_BYTES);
+                       } else {
+                               RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES);
+                       }
+                       RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos);
+                       buf_pos += MANTIS_DMA_TR_BYTES;
+                 }
+       }
+       RISC_INSTR(risc_pos, RISC_JUMP);
+       RISC_INSTR(risc_pos, mantis->risc_dma);
+}
+
+void mantis_dma_start(struct mantis_pci *mantis)
+{
+       dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine");
+
+       mantis_risc_program(mantis);
+       mmwrite(mantis->risc_dma, MANTIS_RISC_START);
+       mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+       mmwrite(0, MANTIS_DMA_CTL);
+       mantis->last_block = mantis->busy_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)
+{
+       dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
+
+       mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR);
+
+       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;
+       struct mantis_hwconfig *config = mantis->hwconfig;
+
+       while (mantis->last_block != mantis->busy_block) {
+               dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
+                       mantis->last_block, mantis->busy_block);
+
+               (config->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/pci/mantis/mantis_dma.h b/drivers/media/pci/mantis/mantis_dma.h
new file mode 100644 (file)
index 0000000..6be00fa
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_DMA_H
+#define __MANTIS_DMA_H
+
+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 void mantis_dma_xfer(unsigned long data);
+
+#endif /* __MANTIS_DMA_H */
diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c
new file mode 100644 (file)
index 0000000..5d15c6b
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+       Mantis PCI bridge driver
+       Copyright (C) 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/kernel.h>
+#include <linux/bitops.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_dma.h"
+#include "mantis_ca.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
+{
+       struct mantis_hwconfig *config = mantis->hwconfig;
+
+       switch (power) {
+       case POWER_ON:
+               dprintk(MANTIS_DEBUG, 1, "Power ON");
+               mantis_gpio_set_bits(mantis, config->power, POWER_ON);
+               msleep(100);
+               mantis_gpio_set_bits(mantis, config->power, POWER_ON);
+               msleep(100);
+               break;
+
+       case POWER_OFF:
+               dprintk(MANTIS_DEBUG, 1, "Power OFF");
+               mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
+               msleep(100);
+               break;
+
+       default:
+               dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
+               return -1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_frontend_power);
+
+void mantis_frontend_soft_reset(struct mantis_pci *mantis)
+{
+       struct mantis_hwconfig *config = mantis->hwconfig;
+
+       dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
+       mantis_gpio_set_bits(mantis, config->reset, 0);
+       msleep(100);
+       mantis_gpio_set_bits(mantis, config->reset, 0);
+       msleep(100);
+       mantis_gpio_set_bits(mantis, config->reset, 1);
+       msleep(100);
+       mantis_gpio_set_bits(mantis, config->reset, 1);
+       msleep(100);
+
+       return;
+}
+EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
+
+static int mantis_frontend_shutdown(struct mantis_pci *mantis)
+{
+       int err;
+
+       mantis_frontend_soft_reset(mantis);
+       err = mantis_frontend_power(mantis, POWER_OFF);
+       if (err != 0) {
+               dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
+               return 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(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
+       if (!dvbdmx->dmx.frontend) {
+               dprintk(MANTIS_DEBUG, 1, "no frontend ?");
+               return -EINVAL;
+       }
+
+       mantis->feeds++;
+       dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds);
+
+       if (mantis->feeds == 1)  {
+               dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
+               mantis_dma_start(mantis);
+               tasklet_enable(&mantis->tasklet);
+       }
+
+       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(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
+       if (!dvbdmx->dmx.frontend) {
+               dprintk(MANTIS_DEBUG, 1, "no frontend ?");
+               return -EINVAL;
+       }
+
+       mantis->feeds--;
+       if (mantis->feeds == 0) {
+               dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
+               tasklet_disable(&mantis->tasklet);
+               mantis_dma_stop(mantis);
+       }
+
+       return 0;
+}
+
+int __devinit mantis_dvb_init(struct mantis_pci *mantis)
+{
+       struct mantis_hwconfig *config = mantis->hwconfig;
+       int result = -1;
+
+       dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
+
+       result = dvb_register_adapter(&mantis->dvb_adapter,
+                                     "Mantis DVB adapter",
+                                     THIS_MODULE,
+                                     &mantis->pdev->dev,
+                                     adapter_nr);
+
+       if (result < 0) {
+
+               dprintk(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;
+
+       dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
+       result = dvb_dmx_init(&mantis->demux);
+       if (result < 0) {
+               dprintk(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(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
+
+       result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
+       if (result < 0) {
+
+               dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
+               goto err1;
+       }
+
+       mantis->fe_hw.source            = DMX_FRONTEND_0;
+       result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+       if (result < 0) {
+
+               dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+               goto err2;
+       }
+
+       mantis->fe_mem.source           = DMX_MEMORY_FE;
+       result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+       if (result < 0) {
+               dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+               goto err3;
+       }
+
+       result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+       if (result < 0) {
+               dprintk(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);
+       tasklet_disable(&mantis->tasklet);
+       if (mantis->hwconfig) {
+               result = config->frontend_init(mantis, mantis->fe);
+               if (result < 0) {
+                       dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
+                       goto err5;
+               } else {
+                       if (mantis->fe == NULL) {
+                               dprintk(MANTIS_ERROR, 1, "FE <NULL>");
+                               goto err5;
+                       }
+
+                       if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
+                               dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
+
+                               if (mantis->fe->ops.release)
+                                       mantis->fe->ops.release(mantis->fe);
+
+                               mantis->fe = NULL;
+                               goto err5;
+                       }
+               }
+       }
+
+       return 0;
+
+       /* Error conditions ..  */
+err5:
+       tasklet_kill(&mantis->tasklet);
+       dvb_net_release(&mantis->dvbnet);
+       if (mantis->fe) {
+               dvb_unregister_frontend(mantis->fe);
+               dvb_frontend_detach(mantis->fe);
+       }
+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;
+}
+EXPORT_SYMBOL_GPL(mantis_dvb_init);
+
+int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
+{
+       int err;
+
+       if (mantis->fe) {
+               /* mantis_ca_exit(mantis); */
+               err = mantis_frontend_shutdown(mantis);
+               if (err != 0)
+                       dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
+               dvb_unregister_frontend(mantis->fe);
+               dvb_frontend_detach(mantis->fe);
+       }
+
+       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);
+
+       dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
+       dvb_unregister_adapter(&mantis->dvb_adapter);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_dvb_exit);
diff --git a/drivers/media/pci/mantis/mantis_dvb.h b/drivers/media/pci/mantis/mantis_dvb.h
new file mode 100644 (file)
index 0000000..464199d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_DVB_H
+#define __MANTIS_DVB_H
+
+enum mantis_power {
+       POWER_OFF       = 0,
+       POWER_ON        = 1
+};
+
+extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power);
+extern void mantis_frontend_soft_reset(struct mantis_pci *mantis);
+
+extern int mantis_dvb_init(struct mantis_pci *mantis);
+extern int mantis_dvb_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_DVB_H */
diff --git a/drivers/media/pci/mantis/mantis_evm.c b/drivers/media/pci/mantis/mantis_evm.c
new file mode 100644 (file)
index 0000000..71ce528
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h"
+#include "mantis_hif.h"
+#include "mantis_reg.h"
+
+static void mantis_hifevm_work(struct work_struct *work)
+{
+       struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       u32 gpif_stat;
+
+       gpif_stat = mmread(MANTIS_GPIF_STATUS);
+
+       if (gpif_stat & MANTIS_GPIF_DETSTAT) {
+               if (gpif_stat & MANTIS_CARD_PLUGIN) {
+                       dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num);
+                       mmwrite(0xdada0000, MANTIS_CARD_RESET);
+                       mantis_event_cam_plugin(ca);
+                       dvb_ca_en50221_camchange_irq(&ca->en50221,
+                                                    0,
+                                                    DVB_CA_EN50221_CAMCHANGE_INSERTED);
+               }
+       } else {
+               if (gpif_stat & MANTIS_CARD_PLUGOUT) {
+                       dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num);
+                       mmwrite(0xdada0000, MANTIS_CARD_RESET);
+                       mantis_event_cam_unplug(ca);
+                       dvb_ca_en50221_camchange_irq(&ca->en50221,
+                                                    0,
+                                                    DVB_CA_EN50221_CAMCHANGE_REMOVED);
+               }
+       }
+
+       if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num);
+
+       if (mantis->gpif_status & MANTIS_SBUF_WSTO)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num);
+
+       if (mantis->gpif_status & MANTIS_GPIF_OTHERR)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num);
+
+       if (gpif_stat & MANTIS_SBUF_OVFLW)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num);
+
+       if (gpif_stat & MANTIS_GPIF_BRRDY)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num);
+
+       if (gpif_stat & MANTIS_GPIF_INTSTAT)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num);
+
+       if (gpif_stat & MANTIS_SBUF_EMPTY)
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
+
+       if (gpif_stat & MANTIS_SBUF_OPDONE) {
+               dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
+               ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
+               ca->hif_event = MANTIS_SBUF_OPDONE;
+               wake_up(&ca->hif_opdone_wq);
+       }
+}
+
+int mantis_evmgr_init(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager");
+       INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work);
+       mantis_pcmcia_init(ca);
+       schedule_work(&ca->hif_evm_work);
+       mantis_hif_init(ca);
+       return 0;
+}
+
+void mantis_evmgr_exit(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
+       flush_work_sync(&ca->hif_evm_work);
+       mantis_hif_exit(ca);
+       mantis_pcmcia_exit(ca);
+}
diff --git a/drivers/media/pci/mantis/mantis_hif.c b/drivers/media/pci/mantis/mantis_hif.c
new file mode 100644 (file)
index 0000000..10c68df
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+
+#include "mantis_hif.h"
+#include "mantis_link.h" /* temporary due to physical layer stuff */
+
+#include "mantis_reg.h"
+
+
+static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       int rc = 0;
+
+       if (wait_event_timeout(ca->hif_opdone_wq,
+                              ca->hif_event & MANTIS_SBUF_OPDONE,
+                              msecs_to_jiffies(500)) == -ERESTARTSYS) {
+
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
+               rc = -EREMOTEIO;
+       }
+       dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
+       ca->hif_event &= ~MANTIS_SBUF_OPDONE;
+       return rc;
+}
+
+static int mantis_hif_write_wait(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 opdone = 0, timeout = 0;
+       int rc = 0;
+
+       if (wait_event_timeout(ca->hif_write_wq,
+                              mantis->gpif_status & MANTIS_GPIF_WRACK,
+                              msecs_to_jiffies(500)) == -ERESTARTSYS) {
+
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
+               rc = -EREMOTEIO;
+       }
+       dprintk(MANTIS_DEBUG, 1, "Write Acknowledged");
+       mantis->gpif_status &= ~MANTIS_GPIF_WRACK;
+       while (!opdone) {
+               opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE);
+               udelay(500);
+               timeout++;
+               if (timeout > 100) {
+                       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num);
+                       rc = -ETIMEDOUT;
+                       break;
+               }
+       }
+       dprintk(MANTIS_DEBUG, 1, "HIF Write success");
+       return rc;
+}
+
+
+int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 hif_addr = 0, data, count = 4;
+
+       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num);
+       mutex_lock(&ca->ca_lock);
+       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+       hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
+       hif_addr |=  MANTIS_HIF_STATUS;
+       hif_addr |=  addr;
+
+       mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
+       mmwrite(count, MANTIS_GPIF_BRBYTES);
+       udelay(20);
+       mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+       if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num);
+               mutex_unlock(&ca->ca_lock);
+               return -EREMOTEIO;
+       }
+       data = mmread(MANTIS_GPIF_DIN);
+       mutex_unlock(&ca->ca_lock);
+       dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data);
+       return (data >> 24) & 0xff;
+}
+
+int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
+{
+       struct mantis_slot *slot = ca->slot;
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 hif_addr = 0;
+
+       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
+       mutex_lock(&ca->ca_lock);
+       hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
+       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+       hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
+       hif_addr |=  MANTIS_HIF_STATUS;
+       hif_addr |=  addr;
+
+       mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */
+       mmwrite(hif_addr, MANTIS_GPIF_ADDR);
+       mmwrite(data, MANTIS_GPIF_DOUT);
+
+       if (mantis_hif_write_wait(ca) != 0) {
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+               mutex_unlock(&ca->ca_lock);
+               return -EREMOTEIO;
+       }
+       dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr);
+       mutex_unlock(&ca->ca_lock);
+
+       return 0;
+}
+
+int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 data, hif_addr = 0;
+
+       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num);
+       mutex_lock(&ca->ca_lock);
+       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+       hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
+       hif_addr |=  MANTIS_HIF_STATUS;
+       hif_addr |=  addr;
+
+       mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
+       mmwrite(1, MANTIS_GPIF_BRBYTES);
+       udelay(20);
+       mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+       if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+               mutex_unlock(&ca->ca_lock);
+               return -EREMOTEIO;
+       }
+       data = mmread(MANTIS_GPIF_DIN);
+       dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data);
+       udelay(50);
+       mutex_unlock(&ca->ca_lock);
+
+       return (u8) data;
+}
+
+int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 hif_addr = 0;
+
+       dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
+       mutex_lock(&ca->ca_lock);
+       hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+       hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
+       hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
+       hif_addr |=  MANTIS_HIF_STATUS;
+       hif_addr |=  addr;
+
+       mmwrite(hif_addr, MANTIS_GPIF_ADDR);
+       mmwrite(data, MANTIS_GPIF_DOUT);
+
+       if (mantis_hif_write_wait(ca) != 0) {
+               dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+               mutex_unlock(&ca->ca_lock);
+               return -EREMOTEIO;
+       }
+       dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr);
+       mutex_unlock(&ca->ca_lock);
+       udelay(50);
+
+       return 0;
+}
+
+int mantis_hif_init(struct mantis_ca *ca)
+{
+       struct mantis_slot *slot = ca->slot;
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 irqcfg;
+
+       slot[0].slave_cfg = 0x70773028;
+       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num);
+
+       mutex_lock(&ca->ca_lock);
+       irqcfg = mmread(MANTIS_GPIF_IRQCFG);
+       irqcfg = MANTIS_MASK_BRRDY      |
+                MANTIS_MASK_WRACK      |
+                MANTIS_MASK_EXTIRQ     |
+                MANTIS_MASK_WSTO       |
+                MANTIS_MASK_OTHERR     |
+                MANTIS_MASK_OVFLW;
+
+       mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
+       mutex_unlock(&ca->ca_lock);
+
+       return 0;
+}
+
+void mantis_hif_exit(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+       u32 irqcfg;
+
+       dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num);
+       mutex_lock(&ca->ca_lock);
+       irqcfg = mmread(MANTIS_GPIF_IRQCFG);
+       irqcfg &= ~MANTIS_MASK_BRRDY;
+       mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
+       mutex_unlock(&ca->ca_lock);
+}
diff --git a/drivers/media/pci/mantis/mantis_hif.h b/drivers/media/pci/mantis/mantis_hif.h
new file mode 100644 (file)
index 0000000..9094f9e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_HIF_H
+#define __MANTIS_HIF_H
+
+#define MANTIS_HIF_MEMRD               1
+#define MANTIS_HIF_MEMWR               2
+#define MANTIS_HIF_IOMRD               3
+#define MANTIS_HIF_IOMWR               4
+
+#endif /* __MANTIS_HIF_H */
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c
new file mode 100644 (file)
index 0000000..e779451
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/io.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_i2c.h"
+
+#define TRIALS                 10000
+
+static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+       u32 rxd, i, stat, trials;
+
+       dprintk(MANTIS_INFO, 0, "        %s:  Address=[0x%02x] <R>[ ",
+               __func__, 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(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
+               mmwrite(rxd, MANTIS_I2CDATA_CTL);
+
+               /* wait for xfer completion */
+               for (trials = 0; trials < TRIALS; trials++) {
+                       stat = mmread(MANTIS_INT_STAT);
+                       if (stat & MANTIS_INT_I2CDONE)
+                               break;
+               }
+
+               dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
+
+               /* wait for xfer completion */
+               for (trials = 0; trials < TRIALS; trials++) {
+                       stat = mmread(MANTIS_INT_STAT);
+                       if (stat & MANTIS_INT_I2CRACK)
+                               break;
+               }
+
+               dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
+
+               rxd = mmread(MANTIS_I2CDATA_CTL);
+               msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
+               dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
+       }
+       dprintk(MANTIS_INFO, 0, "]\n");
+
+       return 0;
+}
+
+static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+       int i;
+       u32 txd = 0, stat, trials;
+
+       dprintk(MANTIS_INFO, 0, "        %s: Address=[0x%02x] <W>[ ",
+               __func__, msg->addr);
+
+       for (i = 0; i < msg->len; i++) {
+               dprintk(MANTIS_INFO, 0, "%02x ", 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(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
+               mmwrite(txd, MANTIS_I2CDATA_CTL);
+
+               /* wait for xfer completion */
+               for (trials = 0; trials < TRIALS; trials++) {
+                       stat = mmread(MANTIS_INT_STAT);
+                       if (stat & MANTIS_INT_I2CDONE)
+                               break;
+               }
+
+               dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
+
+               /* wait for xfer completion */
+               for (trials = 0; trials < TRIALS; trials++) {
+                       stat = mmread(MANTIS_INT_STAT);
+                       if (stat & MANTIS_INT_I2CRACK)
+                               break;
+               }
+
+               dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
+       }
+       dprintk(MANTIS_INFO, 0, "]\n");
+
+       return 0;
+}
+
+static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+       int ret = 0, i = 0, trials;
+       u32 stat, data, txd;
+       struct mantis_pci *mantis;
+       struct mantis_hwconfig *config;
+
+       mantis = i2c_get_adapdata(adapter);
+       BUG_ON(!mantis);
+       config = mantis->hwconfig;
+       BUG_ON(!config);
+
+       dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
+       mutex_lock(&mantis->i2c_lock);
+
+       while (i < num) {
+               /* Byte MODE */
+               if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
+                   ((i + 1) < num)                     &&
+                   (msgs[i].len < 2)                   &&
+                   (msgs[i + 1].len < 2)               &&
+                   (msgs[i + 1].flags & I2C_M_RD)) {
+
+                       dprintk(MANTIS_DEBUG, 0, "        Byte MODE:\n");
+
+                       /* Read operation */
+                       txd = msgs[i].addr << 25 | (0x1 << 24)
+                                                | (msgs[i].buf[0] << 16)
+                                                | MANTIS_I2C_RATE_3;
+
+                       mmwrite(txd, MANTIS_I2CDATA_CTL);
+                       /* wait for xfer completion */
+                       for (trials = 0; trials < TRIALS; trials++) {
+                               stat = mmread(MANTIS_INT_STAT);
+                               if (stat & MANTIS_INT_I2CDONE)
+                                       break;
+                       }
+
+                       /* check for xfer completion */
+                       if (stat & MANTIS_INT_I2CDONE) {
+                               /* check xfer was acknowledged */
+                               if (stat & MANTIS_INT_I2CRACK) {
+                                       data = mmread(MANTIS_I2CDATA_CTL);
+                                       msgs[i + 1].buf[0] = (data >> 8) & 0xff;
+                                       dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
+                               } else {
+                                       /* I/O error */
+                                       dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
+                                       ret = -EIO;
+                                       break;
+                               }
+                       } else {
+                               /* I/O error */
+                               dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
+                               ret = -EIO;
+                               break;
+                       }
+                       i += 2; /* Write/Read operation in one go */
+               }
+
+               if (i < num) {
+                       if (msgs[i].flags & I2C_M_RD)
+                               ret = mantis_i2c_read(mantis, &msgs[i]);
+                       else
+                               ret = mantis_i2c_write(mantis, &msgs[i]);
+
+                       i++;
+                       if (ret < 0)
+                               goto bail_out;
+               }
+
+       }
+
+       mutex_unlock(&mantis->i2c_lock);
+
+       return num;
+
+bail_out:
+       mutex_unlock(&mantis->i2c_lock);
+       return ret;
+}
+
+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,
+};
+
+int __devinit mantis_i2c_init(struct mantis_pci *mantis)
+{
+       u32 intstat, intmask;
+       struct i2c_adapter *i2c_adapter = &mantis->adapter;
+       struct pci_dev *pdev            = mantis->pdev;
+
+       init_waitqueue_head(&mantis->i2c_wq);
+       mutex_init(&mantis->i2c_lock);
+       strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
+       i2c_set_adapdata(i2c_adapter, mantis);
+
+       i2c_adapter->owner      = THIS_MODULE;
+       i2c_adapter->algo       = &mantis_algo;
+       i2c_adapter->algo_data  = NULL;
+       i2c_adapter->timeout    = 500;
+       i2c_adapter->retries    = 3;
+       i2c_adapter->dev.parent = &pdev->dev;
+
+       mantis->i2c_rc          = i2c_add_adapter(i2c_adapter);
+       if (mantis->i2c_rc < 0)
+               return mantis->i2c_rc;
+
+       dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
+
+       intstat = mmread(MANTIS_INT_STAT);
+       intmask = mmread(MANTIS_INT_MASK);
+       mmwrite(intstat, MANTIS_INT_STAT);
+       dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+       intmask = mmread(MANTIS_INT_MASK);
+       mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_i2c_init);
+
+int mantis_i2c_exit(struct mantis_pci *mantis)
+{
+       u32 intmask;
+
+       dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+       intmask = mmread(MANTIS_INT_MASK);
+       mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
+
+       dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
+       return i2c_del_adapter(&mantis->adapter);
+}
+EXPORT_SYMBOL_GPL(mantis_i2c_exit);
diff --git a/drivers/media/pci/mantis/mantis_i2c.h b/drivers/media/pci/mantis/mantis_i2c.h
new file mode 100644 (file)
index 0000000..1342df2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_I2C_H
+#define __MANTIS_I2C_H
+
+#define I2C_STOP               (1 <<  0)
+#define I2C_READ               (1 <<  1)
+
+extern int mantis_i2c_init(struct mantis_pci *mantis);
+extern int mantis_i2c_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_I2C_H */
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
new file mode 100644 (file)
index 0000000..db6d54d
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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 <media/rc-core.h>
+#include <linux/pci.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_uart.h"
+
+#define MODULE_NAME "mantis_core"
+#define RC_MAP_MANTIS "rc-mantis"
+
+static struct rc_map_table mantis_ir_table[] = {
+       { 0x29, KEY_POWER       },
+       { 0x28, KEY_FAVORITES   },
+       { 0x30, KEY_TEXT        },
+       { 0x17, KEY_INFO        }, /* Preview */
+       { 0x23, KEY_EPG         },
+       { 0x3b, KEY_F22         }, /* Record List */
+       { 0x3c, KEY_1           },
+       { 0x3e, KEY_2           },
+       { 0x39, KEY_3           },
+       { 0x36, KEY_4           },
+       { 0x22, KEY_5           },
+       { 0x20, KEY_6           },
+       { 0x32, KEY_7           },
+       { 0x26, KEY_8           },
+       { 0x24, KEY_9           },
+       { 0x2a, KEY_0           },
+
+       { 0x33, KEY_CANCEL      },
+       { 0x2c, KEY_BACK        },
+       { 0x15, KEY_CLEAR       },
+       { 0x3f, KEY_TAB         },
+       { 0x10, KEY_ENTER       },
+       { 0x14, KEY_UP          },
+       { 0x0d, KEY_RIGHT       },
+       { 0x0e, KEY_DOWN        },
+       { 0x11, KEY_LEFT        },
+
+       { 0x21, KEY_VOLUMEUP    },
+       { 0x35, KEY_VOLUMEDOWN  },
+       { 0x3d, KEY_CHANNELDOWN },
+       { 0x3a, KEY_CHANNELUP   },
+       { 0x2e, KEY_RECORD      },
+       { 0x2b, KEY_PLAY        },
+       { 0x13, KEY_PAUSE       },
+       { 0x25, KEY_STOP        },
+
+       { 0x1f, KEY_REWIND      },
+       { 0x2d, KEY_FASTFORWARD },
+       { 0x1e, KEY_PREVIOUS    }, /* Replay |< */
+       { 0x1d, KEY_NEXT        }, /* Skip   >| */
+
+       { 0x0b, KEY_CAMERA      }, /* Capture */
+       { 0x0f, KEY_LANGUAGE    }, /* SAP */
+       { 0x18, KEY_MODE        }, /* PIP */
+       { 0x12, KEY_ZOOM        }, /* Full screen */
+       { 0x1c, KEY_SUBTITLE    },
+       { 0x2f, KEY_MUTE        },
+       { 0x16, KEY_F20         }, /* L/R */
+       { 0x38, KEY_F21         }, /* Hibernate */
+
+       { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */
+       { 0x31, KEY_AGAIN       }, /* Recall */
+       { 0x1a, KEY_KPPLUS      }, /* Zoom+ */
+       { 0x19, KEY_KPMINUS     }, /* Zoom- */
+       { 0x27, KEY_RED         },
+       { 0x0C, KEY_GREEN       },
+       { 0x01, KEY_YELLOW      },
+       { 0x00, KEY_BLUE        },
+};
+
+static struct rc_map_list ir_mantis_map = {
+       .map = {
+               .scan = mantis_ir_table,
+               .size = ARRAY_SIZE(mantis_ir_table),
+               .rc_type = RC_TYPE_UNKNOWN,
+               .name = RC_MAP_MANTIS,
+       }
+};
+
+int mantis_input_init(struct mantis_pci *mantis)
+{
+       struct rc_dev *dev;
+       int err;
+
+       err = rc_map_register(&ir_mantis_map);
+       if (err)
+               goto out;
+
+       dev = rc_allocate_device();
+       if (!dev) {
+               dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
+               err = -ENOMEM;
+               goto out_map;
+       }
+
+       sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
+       sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
+
+       dev->input_name         = mantis->input_name;
+       dev->input_phys         = mantis->input_phys;
+       dev->input_id.bustype   = BUS_PCI;
+       dev->input_id.vendor    = mantis->vendor_id;
+       dev->input_id.product   = mantis->device_id;
+       dev->input_id.version   = 1;
+       dev->driver_name        = MODULE_NAME;
+       dev->map_name           = RC_MAP_MANTIS;
+       dev->dev.parent         = &mantis->pdev->dev;
+
+       err = rc_register_device(dev);
+       if (err) {
+               dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
+               goto out_dev;
+       }
+
+       mantis->rc = dev;
+       return 0;
+
+out_dev:
+       rc_free_device(dev);
+out_map:
+       rc_map_unregister(&ir_mantis_map);
+out:
+       return err;
+}
+
+int mantis_exit(struct mantis_pci *mantis)
+{
+       rc_unregister_device(mantis->rc);
+       rc_map_unregister(&ir_mantis_map);
+       return 0;
+}
+
diff --git a/drivers/media/pci/mantis/mantis_ioc.c b/drivers/media/pci/mantis/mantis_ioc.c
new file mode 100644 (file)
index 0000000..24fcdc6
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <linux/i2c.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_ioc.h"
+
+static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
+{
+       struct i2c_adapter *adapter = &mantis->adapter;
+       int err;
+       u8 buf = reg;
+
+       struct i2c_msg msg[] = {
+               { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
+               { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
+       };
+
+       err = i2c_transfer(adapter, msg, 2);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
+                       err, data[0], data[1]);
+
+               return err;
+       }
+
+       return 0;
+}
+int mantis_get_mac(struct mantis_pci *mantis)
+{
+       int err;
+       u8 mac_addr[6] = {0};
+
+       err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
+       if (err < 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
+
+               return err;
+       }
+
+       dprintk(MANTIS_ERROR, 0, "    MAC Address=[%pM]\n", mac_addr);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_get_mac);
+
+/* Turn the given bit on or off. */
+void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+{
+       u32 cur;
+
+       dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
+       cur = mmread(MANTIS_GPIF_ADDR);
+       if (value)
+               mantis->gpio_status = cur | (1 << bitpos);
+       else
+               mantis->gpio_status = cur & (~(1 << bitpos));
+
+       dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
+       mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
+       mmwrite(0x00, MANTIS_GPIF_DOUT);
+}
+EXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
+
+int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
+{
+       u32 reg;
+
+       reg = mmread(MANTIS_CONTROL);
+       switch (stream_ctl) {
+       case STREAM_TO_HIF:
+               dprintk(MANTIS_DEBUG, 1, "Set stream to HIF");
+               reg &= 0xff - MANTIS_BYPASS;
+               mmwrite(reg, MANTIS_CONTROL);
+               reg |= MANTIS_BYPASS;
+               mmwrite(reg, MANTIS_CONTROL);
+               break;
+
+       case STREAM_TO_CAM:
+               dprintk(MANTIS_DEBUG, 1, "Set stream to CAM");
+               reg |= MANTIS_BYPASS;
+               mmwrite(reg, MANTIS_CONTROL);
+               reg &= 0xff - MANTIS_BYPASS;
+               mmwrite(reg, MANTIS_CONTROL);
+               break;
+       default:
+               dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl);
+               return -1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_stream_control);
diff --git a/drivers/media/pci/mantis/mantis_ioc.h b/drivers/media/pci/mantis/mantis_ioc.h
new file mode 100644 (file)
index 0000000..d56e002
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_IOC_H
+#define __MANTIS_IOC_H
+
+#define GPIF_A00               0x00
+#define GPIF_A01               0x01
+#define GPIF_A02               0x02
+#define GPIF_A03               0x03
+#define GPIF_A04               0x04
+#define GPIF_A05               0x05
+#define GPIF_A06               0x06
+#define GPIF_A07               0x07
+#define GPIF_A08               0x08
+#define GPIF_A09               0x09
+#define GPIF_A10               0x0a
+#define GPIF_A11               0x0b
+
+#define GPIF_A12               0x0c
+#define GPIF_A13               0x0d
+#define GPIF_A14               0x0e
+
+enum mantis_stream_control {
+       STREAM_TO_HIF = 0,
+       STREAM_TO_CAM
+};
+
+extern int mantis_get_mac(struct mantis_pci *mantis);
+extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
+
+extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
+
+#endif /* __MANTIS_IOC_H */
diff --git a/drivers/media/pci/mantis/mantis_link.h b/drivers/media/pci/mantis/mantis_link.h
new file mode 100644 (file)
index 0000000..2a81477
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_LINK_H
+#define __MANTIS_LINK_H
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include "dvb_ca_en50221.h"
+
+enum mantis_sbuf_status {
+       MANTIS_SBUF_DATA_AVAIL          = 1,
+       MANTIS_SBUF_DATA_EMPTY          = 2,
+       MANTIS_SBUF_DATA_OVFLW          = 3
+};
+
+struct mantis_slot {
+       u32                             timeout;
+       u32                             slave_cfg;
+       u32                             bar;
+};
+
+/* Physical layer */
+enum mantis_slot_state {
+       MODULE_INSERTED                 = 3,
+       MODULE_XTRACTED                 = 4
+};
+
+struct mantis_ca {
+       struct mantis_slot              slot[4];
+
+       struct work_struct              hif_evm_work;
+
+       u32                             hif_event;
+       wait_queue_head_t               hif_opdone_wq;
+       wait_queue_head_t               hif_brrdyw_wq;
+       wait_queue_head_t               hif_data_wq;
+       wait_queue_head_t               hif_write_wq; /* HIF Write op */
+
+       enum mantis_sbuf_status         sbuf_status;
+
+       enum mantis_slot_state          slot_state;
+
+       void                            *ca_priv;
+
+       struct dvb_ca_en50221           en50221;
+       struct mutex                    ca_lock;
+};
+
+/* CA */
+extern void mantis_event_cam_plugin(struct mantis_ca *ca);
+extern void mantis_event_cam_unplug(struct mantis_ca *ca);
+extern int mantis_pcmcia_init(struct mantis_ca *ca);
+extern void mantis_pcmcia_exit(struct mantis_ca *ca);
+extern int mantis_evmgr_init(struct mantis_ca *ca);
+extern void mantis_evmgr_exit(struct mantis_ca *ca);
+
+/* HIF */
+extern int mantis_hif_init(struct mantis_ca *ca);
+extern void mantis_hif_exit(struct mantis_ca *ca);
+extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr);
+extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data);
+extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr);
+extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data);
+
+#endif /* __MANTIS_LINK_H */
diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c
new file mode 100644 (file)
index 0000000..371558a
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+
+#include <asm/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_pci.h"
+
+#define DRIVER_NAME            "Mantis Core"
+
+int __devinit mantis_pci_init(struct mantis_pci *mantis)
+{
+       u8 latency;
+       struct mantis_hwconfig *config  = mantis->hwconfig;
+       struct pci_dev *pdev            = mantis->pdev;
+       int err, ret = 0;
+
+       dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
+               config->model_name,
+               config->dev_type,
+               mantis->pdev->bus->number,
+               PCI_SLOT(mantis->pdev->devfn),
+               PCI_FUNC(mantis->pdev->devfn));
+
+       err = pci_enable_device(pdev);
+       if (err != 0) {
+               ret = -ENODEV;
+               dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err);
+               goto fail0;
+       }
+
+       err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (err != 0) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err);
+               ret = -ENOMEM;
+               goto fail1;
+       }
+
+       pci_set_master(pdev);
+
+       if (!request_mem_region(pci_resource_start(pdev, 0),
+                               pci_resource_len(pdev, 0),
+                               DRIVER_NAME)) {
+
+               dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !");
+               ret = -ENODEV;
+               goto fail1;
+       }
+
+       mantis->mmio = ioremap(pci_resource_start(pdev, 0),
+                              pci_resource_len(pdev, 0));
+
+       if (!mantis->mmio) {
+               dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !");
+               ret = -ENODEV;
+               goto fail2;
+       }
+
+       pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
+       mantis->latency = latency;
+       mantis->revision = pdev->revision;
+
+       dprintk(MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
+               mantis->revision,
+               mantis->pdev->subsystem_vendor,
+               mantis->pdev->subsystem_device);
+
+       dprintk(MANTIS_ERROR, 0,
+               "irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
+               mantis->pdev->irq,
+               mantis->latency,
+               mantis->mantis_addr,
+               mantis->mmio);
+
+       err = request_irq(pdev->irq,
+                         config->irq_handler,
+                         IRQF_SHARED,
+                         DRIVER_NAME,
+                         mantis);
+
+       if (err != 0) {
+
+               dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err);
+               ret = -ENODEV;
+               goto fail3;
+       }
+
+       pci_set_drvdata(pdev, mantis);
+       return ret;
+
+       /* Error conditions */
+fail3:
+       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret);
+       if (mantis->mmio)
+               iounmap(mantis->mmio);
+
+fail2:
+       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret);
+       release_mem_region(pci_resource_start(pdev, 0),
+                          pci_resource_len(pdev, 0));
+
+fail1:
+       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret);
+       pci_disable_device(pdev);
+
+fail0:
+       dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
+       pci_set_drvdata(pdev, NULL);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(mantis_pci_init);
+
+void mantis_pci_exit(struct mantis_pci *mantis)
+{
+       struct pci_dev *pdev = mantis->pdev;
+
+       dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
+       free_irq(pdev->irq, mantis);
+       if (mantis->mmio) {
+               iounmap(mantis->mmio);
+               release_mem_region(pci_resource_start(pdev, 0),
+                                  pci_resource_len(pdev, 0));
+       }
+
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+EXPORT_SYMBOL_GPL(mantis_pci_exit);
+
+MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/mantis/mantis_pci.h b/drivers/media/pci/mantis/mantis_pci.h
new file mode 100644 (file)
index 0000000..65f0045
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_PCI_H
+#define __MANTIS_PCI_H
+
+extern int mantis_pci_init(struct mantis_pci *mantis);
+extern void mantis_pci_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_PCI_H */
diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c
new file mode 100644 (file)
index 0000000..2f188c0
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h" /* temporary due to physical layer stuff */
+#include "mantis_reg.h"
+
+/*
+ * If Slot state is already PLUG_IN event and we are called
+ * again, definitely it is jitter alone
+ */
+void mantis_event_cam_plugin(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       u32 gpif_irqcfg;
+
+       if (ca->slot_state == MODULE_XTRACTED) {
+               dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num);
+               udelay(50);
+               mmwrite(0xda000000, MANTIS_CARD_RESET);
+               gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
+               gpif_irqcfg |= MANTIS_MASK_PLUGOUT;
+               gpif_irqcfg &= ~MANTIS_MASK_PLUGIN;
+               mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
+               udelay(500);
+               ca->slot_state = MODULE_INSERTED;
+       }
+       udelay(100);
+}
+
+/*
+ * If Slot state is already UN_PLUG event and we are called
+ * again, definitely it is jitter alone
+ */
+void mantis_event_cam_unplug(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       u32 gpif_irqcfg;
+
+       if (ca->slot_state == MODULE_INSERTED) {
+               dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num);
+               udelay(50);
+               mmwrite(0x00da0000, MANTIS_CARD_RESET);
+               gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
+               gpif_irqcfg |= MANTIS_MASK_PLUGIN;
+               gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT;
+               mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
+               udelay(500);
+               ca->slot_state = MODULE_XTRACTED;
+       }
+       udelay(100);
+}
+
+int mantis_pcmcia_init(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       u32 gpif_stat, card_stat;
+
+       mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK);
+       gpif_stat = mmread(MANTIS_GPIF_STATUS);
+       card_stat = mmread(MANTIS_GPIF_IRQCFG);
+
+       if (gpif_stat & MANTIS_GPIF_DETSTAT) {
+               dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num);
+               mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG);
+               ca->slot_state = MODULE_INSERTED;
+               dvb_ca_en50221_camchange_irq(&ca->en50221,
+                                            0,
+                                            DVB_CA_EN50221_CAMCHANGE_INSERTED);
+       } else {
+               dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num);
+               mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG);
+               ca->slot_state = MODULE_XTRACTED;
+               dvb_ca_en50221_camchange_irq(&ca->en50221,
+                                            0,
+                                            DVB_CA_EN50221_CAMCHANGE_REMOVED);
+       }
+
+       return 0;
+}
+
+void mantis_pcmcia_exit(struct mantis_ca *ca)
+{
+       struct mantis_pci *mantis = ca->ca_priv;
+
+       mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS);
+       mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK);
+}
diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h
new file mode 100644 (file)
index 0000000..7761f9d
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_GPIF_RD                 (0xff << 24)
+#define MANTIS_GPIF_WR                 (0xff << 16)
+#define MANTIS_CPU_DO                  (0x01 << 10)
+#define MANTIS_DRV_DO                  (0x01 <<  9)
+#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)
+
+/* DEBUG */
+#define MANTIS_DEBUGREG                        0x0c
+#define MANTIS_DATINV                  (0x0e <<  7)
+#define MANTIS_TOP_DEBUGSEL            (0x07 <<  4)
+#define MANTIS_PCMCIA_DEBUGSEL         (0x0f <<  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)
+
+/* DATA */
+#define MANTIS_CMD_DATA_R1             0x20
+#define MANTIS_CMD_DATA_3              (0xff << 24)
+#define MANTIS_CMD_DATA_2              (0xff << 16)
+#define MANTIS_CMD_DATA_1              (0xff <<  8)
+#define MANTIS_CMD_DATA_0              (0xff <<  0)
+
+#define MANTIS_CMD_DATA_R2             0x24
+#define MANTIS_CMD_DATA_7              (0xff << 24)
+#define MANTIS_CMD_DATA_6              (0xff << 16)
+#define MANTIS_CMD_DATA_5              (0xff <<  8)
+#define MANTIS_CMD_DATA_4              (0xff <<  0)
+
+#define MANTIS_CONTROL                 0x28
+#define MANTIS_DET                     (0x01 <<  7)
+#define MANTIS_DAT_CF_EN               (0x01 <<  6)
+#define MANTIS_ACS                     (0x03 <<  4)
+#define MANTIS_VCCEN                   (0x01 <<  3)
+#define MANTIS_BYPASS                  (0x01 <<  2)
+#define MANTIS_MRST                    (0x01 <<  1)
+#define MANTIS_CRST_INT                        (0x01 <<  0)
+
+#define MANTIS_GPIF_CFGSLA             0x84
+#define MANTIS_GPIF_WAITSMPL           (0x07 << 28)
+#define MANTIS_GPIF_BYTEADDRSUB                (0x01 << 25)
+#define MANTIS_GPIF_WAITPOL            (0x01 << 24)
+#define MANTIS_GPIF_NCDELAY            (0x07 << 20)
+#define MANTIS_GPIF_RW2CSDELAY         (0x07 << 16)
+#define MANTIS_GPIF_SLFTIMEDMODE       (0x01 << 15)
+#define MANTIS_GPIF_SLFTIMEDDELY       (0x7f <<  8)
+#define MANTIS_GPIF_DEVTYPE            (0x07 <<  4)
+#define MANTIS_GPIF_BIGENDIAN          (0x01 <<  3)
+#define MANTIS_GPIF_FETCHCMD           (0x03 <<  1)
+#define MANTIS_GPIF_HWORDDEV           (0x01 <<  0)
+
+#define MANTIS_GPIF_WSTOPER            0x90
+#define MANTIS_GPIF_WSTOPERWREN3       (0x01 << 31)
+#define MANTIS_GPIF_PARBOOTN           (0x01 << 29)
+#define MANTIS_GPIF_WSTOPERSLID3       (0x1f << 24)
+#define MANTIS_GPIF_WSTOPERWREN2       (0x01 << 23)
+#define MANTIS_GPIF_WSTOPERSLID2       (0x1f << 16)
+#define MANTIS_GPIF_WSTOPERWREN1       (0x01 << 15)
+#define MANTIS_GPIF_WSTOPERSLID1       (0x1f <<  8)
+#define MANTIS_GPIF_WSTOPERWREN0       (0x01 <<  7)
+#define MANTIS_GPIF_WSTOPERSLID0       (0x1f <<  0)
+
+#define MANTIS_GPIF_CS2RW              0x94
+#define MANTIS_GPIF_CS2RWWREN3         (0x01 << 31)
+#define MANTIS_GPIF_CS2RWDELY3         (0x3f << 24)
+#define MANTIS_GPIF_CS2RWWREN2         (0x01 << 23)
+#define MANTIS_GPIF_CS2RWDELY2         (0x3f << 16)
+#define MANTIS_GPIF_CS2RWWREN1         (0x01 << 15)
+#define MANTIS_GPIF_CS2RWDELY1         (0x3f <<  8)
+#define MANTIS_GPIF_CS2RWWREN0         (0x01 <<  7)
+#define MANTIS_GPIF_CS2RWDELY0         (0x3f <<  0)
+
+#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_BRADDR             0xa0
+#define MANTIS_GPIF_PCMCIAREG          (0x01           << 27)
+#define MANTIS_GPIF_PCMCIAIOM          (0x01           << 26)
+#define MANTIS_GPIF_BR_ADDR            (0xfffffff      <<  0)
+
+#define MANTIS_GPIF_BRBYTES            0xa4
+#define MANTIS_GPIF_BRCNT              (0xfff          <<  0)
+
+#define MANTIS_PCMCIA_RESET            0xa8
+#define MANTIS_PCMCIA_RSTVAL           (0xff << 0)
+
+#define MANTIS_CARD_RESET              0xac
+
+#define MANTIS_GPIF_ADDR               0xb0
+#define MANTIS_GPIF_HIFRDWRN           (0x01           << 31)
+#define MANTIS_GPIF_PCMCIAREG          (0x01           << 27)
+#define MANTIS_GPIF_PCMCIAIOM          (0x01           << 26)
+#define MANTIS_GPIF_HIFADDR            (0xfffffff      <<  0)
+
+#define MANTIS_GPIF_DOUT               0xb4
+#define MANTIS_GPIF_HIFDOUT            (0xfffffff      <<  0)
+
+#define MANTIS_GPIF_DIN                        0xb8
+#define MANTIS_GPIF_HIFDIN             (0xfffffff      <<  0)
+
+#define MANTIS_GPIF_SPARE              0xbc
+#define MANTIS_GPIF_LOGICRD            (0xffff         << 16)
+#define MANTIS_GPIF_LOGICRW            (0xffff         <<  0)
+
+#endif /* __MANTIS_REG_H */
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c
new file mode 100644 (file)
index 0000000..18340da
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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/kernel.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_uart.h"
+
+struct mantis_uart_params {
+       enum mantis_baud        baud_rate;
+       enum mantis_parity      parity;
+};
+
+static struct {
+       char string[7];
+} rates[5] = {
+       { "9600" },
+       { "19200" },
+       { "38400" },
+       { "57600" },
+       { "115200" }
+};
+
+static struct {
+       char string[5];
+} parity[3] = {
+       { "NONE" },
+       { "ODD" },
+       { "EVEN" }
+};
+
+#define UART_MAX_BUF                   16
+
+int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
+{
+       struct mantis_hwconfig *config = mantis->hwconfig;
+       u32 stat = 0, i;
+
+       /* get data */
+       for (i = 0; i < (config->bytes + 1); i++) {
+
+               stat = mmread(MANTIS_UART_STAT);
+
+               if (stat & MANTIS_UART_RXFIFO_FULL) {
+                       dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
+               }
+               data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
+
+               dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
+
+               if (data[i] & (1 << 7)) {
+                       dprintk(MANTIS_ERROR, 1, "UART framing error");
+                       return -EINVAL;
+               }
+               if (data[i] & (1 << 6)) {
+                       dprintk(MANTIS_ERROR, 1, "UART parity error");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static void mantis_uart_work(struct work_struct *work)
+{
+       struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
+       struct mantis_hwconfig *config = mantis->hwconfig;
+       u8 buf[16];
+       int i;
+
+       mantis_uart_read(mantis, buf);
+
+       for (i = 0; i < (config->bytes + 1); i++)
+               dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
+
+       dprintk(MANTIS_DEBUG, 0, "\n");
+}
+
+static int mantis_uart_setup(struct mantis_pci *mantis,
+                            struct mantis_uart_params *params)
+{
+       u32 reg;
+
+       mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
+
+       reg = mmread(MANTIS_UART_BAUD);
+
+       switch (params->baud_rate) {
+       case MANTIS_BAUD_9600:
+               reg |= 0xd8;
+               break;
+       case MANTIS_BAUD_19200:
+               reg |= 0x6c;
+               break;
+       case MANTIS_BAUD_38400:
+               reg |= 0x36;
+               break;
+       case MANTIS_BAUD_57600:
+               reg |= 0x23;
+               break;
+       case MANTIS_BAUD_115200:
+               reg |= 0x11;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       mmwrite(reg, MANTIS_UART_BAUD);
+
+       return 0;
+}
+
+int mantis_uart_init(struct mantis_pci *mantis)
+{
+       struct mantis_hwconfig *config = mantis->hwconfig;
+       struct mantis_uart_params params;
+
+       /* default parity: */
+       params.baud_rate = config->baud_rate;
+       params.parity = config->parity;
+       dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
+               rates[params.baud_rate].string,
+               parity[params.parity].string);
+
+       init_waitqueue_head(&mantis->uart_wq);
+       spin_lock_init(&mantis->uart_lock);
+
+       INIT_WORK(&mantis->uart_work, mantis_uart_work);
+
+       /* disable interrupt */
+       mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
+
+       mantis_uart_setup(mantis, &params);
+
+       /* default 1 byte */
+       mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
+
+       /* flush buffer */
+       mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
+
+       /* enable interrupt */
+       mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
+       mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
+
+       schedule_work(&mantis->uart_work);
+       dprintk(MANTIS_DEBUG, 1, "UART successfully initialized");
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_uart_init);
+
+void mantis_uart_exit(struct mantis_pci *mantis)
+{
+       /* disable interrupt */
+       mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
+       flush_work_sync(&mantis->uart_work);
+}
+EXPORT_SYMBOL_GPL(mantis_uart_exit);
diff --git a/drivers/media/pci/mantis/mantis_uart.h b/drivers/media/pci/mantis/mantis_uart.h
new file mode 100644 (file)
index 0000000..ffb62a0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+       Mantis PCI bridge driver
+
+       Copyright (C) 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_UART_H
+#define __MANTIS_UART_H
+
+#define MANTIS_UART_CTL                        0xe0
+#define MANTIS_UART_RXINT              (1 << 4)
+#define MANTIS_UART_RXFLUSH            (1 << 2)
+
+#define MANTIS_UART_RXD                        0xe8
+#define MANTIS_UART_BAUD               0xec
+
+#define MANTIS_UART_STAT               0xf0
+#define MANTIS_UART_RXFIFO_DATA                (1 << 7)
+#define MANTIS_UART_RXFIFO_EMPTY       (1 << 6)
+#define MANTIS_UART_RXFIFO_FULL                (1 << 3)
+#define MANTIS_UART_FRAME_ERR          (1 << 2)
+#define MANTIS_UART_PARITY_ERR         (1 << 1)
+#define MANTIS_UART_RXTHRESH_INT       (1 << 0)
+
+enum mantis_baud {
+       MANTIS_BAUD_9600        = 0,
+       MANTIS_BAUD_19200,
+       MANTIS_BAUD_38400,
+       MANTIS_BAUD_57600,
+       MANTIS_BAUD_115200
+};
+
+enum mantis_parity {
+       MANTIS_PARITY_NONE      = 0,
+       MANTIS_PARITY_EVEN,
+       MANTIS_PARITY_ODD,
+};
+
+struct mantis_pci;
+
+extern int mantis_uart_init(struct mantis_pci *mantis);
+extern void mantis_uart_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_UART_H */
diff --git a/drivers/media/pci/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c
new file mode 100644 (file)
index 0000000..ad013e9
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+       Mantis VP-1033 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "stv0299.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1033.h"
+#include "mantis_reg.h"
+
+u8 lgtdqcs001f_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       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,
+};
+
+#define MANTIS_MODEL_NAME      "VP-1033"
+#define MANTIS_DEV_TYPE                "DVB-S/DSS"
+
+int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mantis_pci *mantis       = fe->dvb->priv;
+       struct i2c_adapter *adapter     = &mantis->adapter;
+
+       u8 buf[4];
+       u32 div;
+
+
+       struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
+
+       div = p->frequency / 250;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] =  div & 0xff;
+       buf[2] =  0x83;
+       buf[3] =  0xc0;
+
+       if (p->frequency < 1531000)
+               buf[3] |= 0x04;
+       else
+               buf[3] &= ~0x04;
+       if (i2c_transfer(adapter, &msg, 1) < 0) {
+               dprintk(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;
+}
+
+struct stv0299_config lgtdqcs001f_config = {
+       .demod_address          = 0x68,
+       .inittab                = lgtdqcs001f_inittab,
+       .mclk                   = 88000000UL,
+       .invert                 = 0,
+       .skip_reinit            = 0,
+       .volt13_op0_op1         = STV0299_VOLT13_OP0,
+       .min_delay_ms           = 100,
+       .set_symbol_rate        = lgtdqcs001f_set_symbol_rate,
+};
+
+static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter     = &mantis->adapter;
+
+       int err = 0;
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               mantis_frontend_soft_reset(mantis);
+               msleep(250);
+
+               dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
+               fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
+
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
+                       dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
+                               lgtdqcs001f_config.demod_address);
+
+                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
+               } else {
+                       return -1;
+               }
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+       mantis->fe = fe;
+       dprintk(MANTIS_ERROR, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp1033_config = {
+       .model_name             = MANTIS_MODEL_NAME,
+       .dev_type               = MANTIS_DEV_TYPE,
+       .ts_size                = MANTIS_TS_204,
+
+       .baud_rate              = MANTIS_BAUD_9600,
+       .parity                 = MANTIS_PARITY_NONE,
+       .bytes                  = 0,
+
+       .frontend_init          = vp1033_frontend_init,
+       .power                  = GPIF_A12,
+       .reset                  = GPIF_A13,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp1033.h b/drivers/media/pci/mantis/mantis_vp1033.h
new file mode 100644 (file)
index 0000000..7daaa1b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Mantis VP-1033 driver
+
+       Copyright (C) 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 "mantis_common.h"
+
+#define MANTIS_VP_1033_DVB_S   0x0016
+
+extern struct mantis_hwconfig vp1033_config;
+
+#endif /* __MANTIS_VP1033_H */
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
new file mode 100644 (file)
index 0000000..430ae84
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+       Mantis VP-1034 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mb86a16.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1034.h"
+#include "mantis_reg.h"
+
+struct mb86a16_config vp1034_mb86a16_config = {
+       .demod_address  = 0x08,
+       .set_voltage    = vp1034_set_voltage,
+};
+
+#define MANTIS_MODEL_NAME      "VP-1034"
+#define MANTIS_DEV_TYPE                "DVB-S/DSS"
+
+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:
+               dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
+               mantis_gpio_set_bits(mantis, 13, 1);
+               mantis_gpio_set_bits(mantis, 14, 0);
+               break;
+       case SEC_VOLTAGE_18:
+               dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
+               mantis_gpio_set_bits(mantis, 13, 1);
+               mantis_gpio_set_bits(mantis, 14, 1);
+               break;
+       case SEC_VOLTAGE_OFF:
+               dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
+               break;
+       default:
+               dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage);
+               return -EINVAL;
+       }
+       mmwrite(0x00, MANTIS_GPIF_DOUT);
+
+       return 0;
+}
+
+static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter     = &mantis->adapter;
+
+       int err = 0;
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               mantis_frontend_soft_reset(mantis);
+               msleep(250);
+
+               dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
+               fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter);
+               if (fe) {
+                       dprintk(MANTIS_ERROR, 1,
+                       "found MB86A16 DVB-S/DSS frontend @0x%02x",
+                       vp1034_mb86a16_config.demod_address);
+
+               } else {
+                       return -1;
+               }
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+       mantis->fe = fe;
+       dprintk(MANTIS_ERROR, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp1034_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_204,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp1034_frontend_init,
+       .power          = GPIF_A12,
+       .reset          = GPIF_A13,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h
new file mode 100644 (file)
index 0000000..323f38e
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+       Mantis VP-1034 driver
+
+       Copyright (C) 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 "dvb_frontend.h"
+#include "mantis_common.h"
+
+
+#define MANTIS_VP_1034_DVB_S   0x0014
+
+extern struct mantis_hwconfig 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/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
new file mode 100644 (file)
index 0000000..07aa887
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+       Mantis VP-1041 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1041.h"
+#include "stb0899_reg.h"
+#include "stb0899_drv.h"
+#include "stb0899_cfg.h"
+#include "stb6100_cfg.h"
+#include "stb6100.h"
+#include "lnbp21.h"
+
+#define MANTIS_MODEL_NAME      "VP-1041"
+#define MANTIS_DEV_TYPE                "DSS/DVB-S/DVB-S2"
+
+static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
+
+       /* 0x0000000b, *//* SYSREG */
+       { STB0899_DEV_ID                , 0x30 },
+       { STB0899_DISCNTRL1             , 0x32 },
+       { STB0899_DISCNTRL2             , 0x80 },
+       { STB0899_DISRX_ST0             , 0x04 },
+       { STB0899_DISRX_ST1             , 0x00 },
+       { STB0899_DISPARITY             , 0x00 },
+       { STB0899_DISSTATUS             , 0x20 },
+       { STB0899_DISF22                , 0x99 },
+       { STB0899_DISF22RX              , 0xa8 },
+       /* SYSREG ? */
+       { STB0899_ACRPRESC              , 0x11 },
+       { STB0899_ACRDIV1               , 0x0a },
+       { STB0899_ACRDIV2               , 0x05 },
+       { STB0899_DACR1                 , 0x00 },
+       { STB0899_DACR2                 , 0x00 },
+       { STB0899_OUTCFG                , 0x00 },
+       { STB0899_MODECFG               , 0x00 },
+       { STB0899_IRQSTATUS_3           , 0xfe },
+       { STB0899_IRQSTATUS_2           , 0x03 },
+       { STB0899_IRQSTATUS_1           , 0x7c },
+       { STB0899_IRQSTATUS_0           , 0xf4 },
+       { STB0899_IRQMSK_3              , 0xf3 },
+       { STB0899_IRQMSK_2              , 0xfc },
+       { STB0899_IRQMSK_1              , 0xff },
+       { STB0899_IRQMSK_0              , 0xff },
+       { STB0899_IRQCFG                , 0x00 },
+       { STB0899_I2CCFG                , 0x88 },
+       { STB0899_I2CRPT                , 0x58 },
+       { STB0899_IOPVALUE5             , 0x00 },
+       { STB0899_IOPVALUE4             , 0x33 },
+       { STB0899_IOPVALUE3             , 0x6d },
+       { STB0899_IOPVALUE2             , 0x90 },
+       { STB0899_IOPVALUE1             , 0x60 },
+       { STB0899_IOPVALUE0             , 0x00 },
+       { STB0899_GPIO00CFG             , 0x82 },
+       { STB0899_GPIO01CFG             , 0x82 },
+       { STB0899_GPIO02CFG             , 0x82 },
+       { STB0899_GPIO03CFG             , 0x82 },
+       { STB0899_GPIO04CFG             , 0x82 },
+       { STB0899_GPIO05CFG             , 0x82 },
+       { STB0899_GPIO06CFG             , 0x82 },
+       { STB0899_GPIO07CFG             , 0x82 },
+       { STB0899_GPIO08CFG             , 0x82 },
+       { STB0899_GPIO09CFG             , 0x82 },
+       { STB0899_GPIO10CFG             , 0x82 },
+       { STB0899_GPIO11CFG             , 0x82 },
+       { STB0899_GPIO12CFG             , 0x82 },
+       { STB0899_GPIO13CFG             , 0x82 },
+       { STB0899_GPIO14CFG             , 0x82 },
+       { STB0899_GPIO15CFG             , 0x82 },
+       { STB0899_GPIO16CFG             , 0x82 },
+       { STB0899_GPIO17CFG             , 0x82 },
+       { STB0899_GPIO18CFG             , 0x82 },
+       { STB0899_GPIO19CFG             , 0x82 },
+       { STB0899_GPIO20CFG             , 0x82 },
+       { STB0899_SDATCFG               , 0xb8 },
+       { STB0899_SCLTCFG               , 0xba },
+       { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
+       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
+       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
+       { STB0899_DIRCLKCFG             , 0x82 },
+       { STB0899_CLKOUT27CFG           , 0x7e },
+       { STB0899_STDBYCFG              , 0x82 },
+       { STB0899_CS0CFG                , 0x82 },
+       { STB0899_CS1CFG                , 0x82 },
+       { STB0899_DISEQCOCFG            , 0x20 },
+       { STB0899_GPIO32CFG             , 0x82 },
+       { STB0899_GPIO33CFG             , 0x82 },
+       { STB0899_GPIO34CFG             , 0x82 },
+       { STB0899_GPIO35CFG             , 0x82 },
+       { STB0899_GPIO36CFG             , 0x82 },
+       { STB0899_GPIO37CFG             , 0x82 },
+       { STB0899_GPIO38CFG             , 0x82 },
+       { STB0899_GPIO39CFG             , 0x82 },
+       { STB0899_NCOARSE               , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+       { STB0899_FILTCTRL              , 0x00 },
+       { STB0899_SYSCTRL               , 0x01 },
+       { STB0899_STOPCLK1              , 0x20 },
+       { STB0899_STOPCLK2              , 0x00 },
+       { STB0899_INTBUFSTATUS          , 0x00 },
+       { STB0899_INTBUFCTRL            , 0x0a },
+       { 0xffff                        , 0xff },
+};
+
+static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
+       { STB0899_DEMOD                 , 0x00 },
+       { STB0899_RCOMPC                , 0xc9 },
+       { STB0899_AGC1CN                , 0x01 },
+       { STB0899_AGC1REF               , 0x10 },
+       { STB0899_RTC                   , 0x23 },
+       { STB0899_TMGCFG                , 0x4e },
+       { STB0899_AGC2REF               , 0x34 },
+       { STB0899_TLSR                  , 0x84 },
+       { STB0899_CFD                   , 0xf7 },
+       { STB0899_ACLC                  , 0x87 },
+       { STB0899_BCLC                  , 0x94 },
+       { STB0899_EQON                  , 0x41 },
+       { STB0899_LDT                   , 0xf1 },
+       { STB0899_LDT2                  , 0xe3 },
+       { STB0899_EQUALREF              , 0xb4 },
+       { STB0899_TMGRAMP               , 0x10 },
+       { STB0899_TMGTHD                , 0x30 },
+       { STB0899_IDCCOMP               , 0xfd },
+       { STB0899_QDCCOMP               , 0xff },
+       { STB0899_POWERI                , 0x0c },
+       { STB0899_POWERQ                , 0x0f },
+       { STB0899_RCOMP                 , 0x6c },
+       { STB0899_AGCIQIN               , 0x80 },
+       { STB0899_AGC2I1                , 0x06 },
+       { STB0899_AGC2I2                , 0x00 },
+       { STB0899_TLIR                  , 0x30 },
+       { STB0899_RTF                   , 0x7f },
+       { STB0899_DSTATUS               , 0x00 },
+       { STB0899_LDI                   , 0xbc },
+       { STB0899_CFRM                  , 0xea },
+       { STB0899_CFRL                  , 0x31 },
+       { STB0899_NIRM                  , 0x2b },
+       { STB0899_NIRL                  , 0x80 },
+       { STB0899_ISYMB                 , 0x1d },
+       { STB0899_QSYMB                 , 0xa6 },
+       { STB0899_SFRH                  , 0x2f },
+       { STB0899_SFRM                  , 0x68 },
+       { STB0899_SFRL                  , 0x40 },
+       { STB0899_SFRUPH                , 0x2f },
+       { STB0899_SFRUPM                , 0x68 },
+       { STB0899_SFRUPL                , 0x40 },
+       { STB0899_EQUAI1                , 0x02 },
+       { STB0899_EQUAQ1                , 0xff },
+       { STB0899_EQUAI2                , 0x04 },
+       { STB0899_EQUAQ2                , 0x05 },
+       { STB0899_EQUAI3                , 0x02 },
+       { STB0899_EQUAQ3                , 0xfd },
+       { STB0899_EQUAI4                , 0x03 },
+       { STB0899_EQUAQ4                , 0x07 },
+       { STB0899_EQUAI5                , 0x08 },
+       { STB0899_EQUAQ5                , 0xf5 },
+       { STB0899_DSTATUS2              , 0x00 },
+       { STB0899_VSTATUS               , 0x00 },
+       { STB0899_VERROR                , 0x86 },
+       { STB0899_IQSWAP                , 0x2a },
+       { STB0899_ECNT1M                , 0x00 },
+       { STB0899_ECNT1L                , 0x00 },
+       { STB0899_ECNT2M                , 0x00 },
+       { STB0899_ECNT2L                , 0x00 },
+       { STB0899_ECNT3M                , 0x0a },
+       { STB0899_ECNT3L                , 0xad },
+       { STB0899_FECAUTO1              , 0x06 },
+       { STB0899_FECM                  , 0x01 },
+       { STB0899_VTH12                 , 0xb0 },
+       { STB0899_VTH23                 , 0x7a },
+       { STB0899_VTH34                 , 0x58 },
+       { STB0899_VTH56                 , 0x38 },
+       { STB0899_VTH67                 , 0x34 },
+       { STB0899_VTH78                 , 0x24 },
+       { STB0899_PRVIT                 , 0xff },
+       { STB0899_VITSYNC               , 0x19 },
+       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+       { STB0899_TSULC                 , 0x42 },
+       { STB0899_RSLLC                 , 0x41 },
+       { STB0899_TSLPL                 , 0x12 },
+       { STB0899_TSCFGH                , 0x0c },
+       { STB0899_TSCFGM                , 0x00 },
+       { STB0899_TSCFGL                , 0x00 },
+       { STB0899_TSOUT                 , 0x69 }, /* 0x0d for CAM */
+       { STB0899_RSSYNCDEL             , 0x00 },
+       { STB0899_TSINHDELH             , 0x02 },
+       { STB0899_TSINHDELM             , 0x00 },
+       { STB0899_TSINHDELL             , 0x00 },
+       { STB0899_TSLLSTKM              , 0x1b },
+       { STB0899_TSLLSTKL              , 0xb3 },
+       { STB0899_TSULSTKM              , 0x00 },
+       { STB0899_TSULSTKL              , 0x00 },
+       { STB0899_PCKLENUL              , 0xbc },
+       { STB0899_PCKLENLL              , 0xcc },
+       { STB0899_RSPCKLEN              , 0xbd },
+       { STB0899_TSSTATUS              , 0x90 },
+       { STB0899_ERRCTRL1              , 0xb6 },
+       { STB0899_ERRCTRL2              , 0x95 },
+       { STB0899_ERRCTRL3              , 0x8d },
+       { STB0899_DMONMSK1              , 0x27 },
+       { STB0899_DMONMSK0              , 0x03 },
+       { STB0899_DEMAPVIT              , 0x5c },
+       { STB0899_PLPARM                , 0x19 },
+       { STB0899_PDELCTRL              , 0x48 },
+       { STB0899_PDELCTRL2             , 0x00 },
+       { STB0899_BBHCTRL1              , 0x00 },
+       { STB0899_BBHCTRL2              , 0x00 },
+       { STB0899_HYSTTHRESH            , 0x77 },
+       { STB0899_MATCSTM               , 0x00 },
+       { STB0899_MATCSTL               , 0x00 },
+       { STB0899_UPLCSTM               , 0x00 },
+       { STB0899_UPLCSTL               , 0x00 },
+       { STB0899_DFLCSTM               , 0x00 },
+       { STB0899_DFLCSTL               , 0x00 },
+       { STB0899_SYNCCST               , 0x00 },
+       { STB0899_SYNCDCSTM             , 0x00 },
+       { STB0899_SYNCDCSTL             , 0x00 },
+       { STB0899_ISI_ENTRY             , 0x00 },
+       { STB0899_ISI_BIT_EN            , 0x00 },
+       { STB0899_MATSTRM               , 0xf0 },
+       { STB0899_MATSTRL               , 0x02 },
+       { STB0899_UPLSTRM               , 0x45 },
+       { STB0899_UPLSTRL               , 0x60 },
+       { STB0899_DFLSTRM               , 0xe3 },
+       { STB0899_DFLSTRL               , 0x00 },
+       { STB0899_SYNCSTR               , 0x47 },
+       { STB0899_SYNCDSTRM             , 0x05 },
+       { STB0899_SYNCDSTRL             , 0x18 },
+       { STB0899_CFGPDELSTATUS1        , 0x19 },
+       { STB0899_CFGPDELSTATUS2        , 0x2b },
+       { STB0899_BBFERRORM             , 0x00 },
+       { STB0899_BBFERRORL             , 0x01 },
+       { STB0899_UPKTERRORM            , 0x00 },
+       { STB0899_UPKTERRORL            , 0x00 },
+       { 0xffff                        , 0xff },
+};
+
+struct stb0899_config vp1041_stb0899_config = {
+       .init_dev               = vp1041_stb0899_s1_init_1,
+       .init_s2_demod          = stb0899_s2_init_2,
+       .init_s1_demod          = vp1041_stb0899_s1_init_3,
+       .init_s2_fec            = stb0899_s2_init_4,
+       .init_tst               = stb0899_s1_init_5,
+
+       .demod_address          = 0x68, /*  0xd0 >> 1 */
+
+       .xtal_freq              = 27000000,
+       .inversion              = IQ_SWAP_ON, /* 1 */
+
+       .lo_clk                 = 76500000,
+       .hi_clk                 = 99000000,
+
+       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
+       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
+       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
+       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
+       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
+       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
+       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
+       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
+       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
+
+       .tuner_get_frequency    = stb6100_get_frequency,
+       .tuner_set_frequency    = stb6100_set_frequency,
+       .tuner_set_bandwidth    = stb6100_set_bandwidth,
+       .tuner_get_bandwidth    = stb6100_get_bandwidth,
+       .tuner_set_rfsiggain    = NULL,
+};
+
+struct stb6100_config vp1041_stb6100_config = {
+       .tuner_address  = 0x60,
+       .refclock       = 27000000,
+};
+
+static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter     = &mantis->adapter;
+
+       int err = 0;
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               mantis_frontend_soft_reset(mantis);
+               msleep(250);
+               mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter);
+               if (mantis->fe) {
+                       dprintk(MANTIS_ERROR, 1,
+                               "found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
+                               vp1041_stb0899_config.demod_address);
+
+                       if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) {
+                               if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0))
+                                       dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
+                       }
+               } else {
+                       return -EREMOTEIO;
+               }
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+
+
+       dprintk(MANTIS_ERROR, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp1041_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_188,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp1041_frontend_init,
+       .power          = GPIF_A12,
+       .reset          = GPIF_A13,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp1041.h b/drivers/media/pci/mantis/mantis_vp1041.h
new file mode 100644 (file)
index 0000000..1ae5b3d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+       Mantis VP-1041 driver
+
+       Copyright (C) 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_VP1041_H
+#define __MANTIS_VP1041_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_1041_DVB_S2  0x0031
+#define SKYSTAR_HD2_10         0x0001
+#define SKYSTAR_HD2_20         0x0003
+#define CINERGY_S2_PCI_HD      0x1179
+
+extern struct mantis_hwconfig vp1041_config;
+
+#endif /* __MANTIS_VP1041_H */
diff --git a/drivers/media/pci/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c
new file mode 100644 (file)
index 0000000..1ca6837
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+       Mantis VP-2033 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "tda1002x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp2033.h"
+
+#define MANTIS_MODEL_NAME      "VP-2033"
+#define MANTIS_DEV_TYPE                "DVB-C"
+
+struct tda1002x_config vp2033_tda1002x_cu1216_config = {
+       .demod_address = 0x18 >> 1,
+       .invert = 1,
+};
+
+struct tda10023_config vp2033_tda10023_cu1216_config = {
+       .demod_address = 0x18 >> 1,
+       .invert = 1,
+};
+
+static u8 read_pwm(struct mantis_pci *mantis)
+{
+       struct i2c_adapter *adapter = &mantis->adapter;
+
+       u8 b = 0xff;
+       u8 pwm;
+       struct i2c_msg msg[] = {
+               {.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
+               {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
+       };
+
+       if ((i2c_transfer(adapter, msg, 2) != 2)
+           || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mantis_pci *mantis = fe->dvb->priv;
+       struct i2c_adapter *adapter = &mantis->adapter;
+
+       u8 buf[6];
+       struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
+       int i;
+
+#define CU1216_IF 36125000
+#define TUNER_MUL 62500
+
+       u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0xce;
+       buf[3] = (p->frequency < 150000000 ? 0x01 :
+                 p->frequency < 445000000 ? 0x02 : 0x04);
+       buf[4] = 0xde;
+       buf[5] = 0x20;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       if (i2c_transfer(adapter, &msg, 1) != 1)
+               return -EIO;
+
+       /* wait for the pll lock */
+       msg.flags = I2C_M_RD;
+       msg.len = 1;
+       for (i = 0; i < 20; i++) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
+                       break;
+
+               msleep(10);
+       }
+
+       /* switch the charge pump to the lower current */
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = &buf[2];
+       buf[2] &= ~0x40;
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       if (i2c_transfer(adapter, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter = &mantis->adapter;
+
+       int err = 0;
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               mantis_frontend_soft_reset(mantis);
+               msleep(250);
+
+               dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
+               fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
+                                    adapter,
+                                    read_pwm(mantis));
+
+               if (fe) {
+                       dprintk(MANTIS_ERROR, 1,
+                               "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
+                               vp2033_tda1002x_cu1216_config.demod_address);
+               } else {
+                       fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
+                                            adapter,
+                                            read_pwm(mantis));
+
+                       if (fe) {
+                               dprintk(MANTIS_ERROR, 1,
+                                       "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
+                                       vp2033_tda1002x_cu1216_config.demod_address);
+                       }
+               }
+
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
+                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
+               } else {
+                       return -1;
+               }
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+
+       mantis->fe = fe;
+       dprintk(MANTIS_DEBUG, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp2033_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_204,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp2033_frontend_init,
+       .power          = GPIF_A12,
+       .reset          = GPIF_A13,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp2033.h b/drivers/media/pci/mantis/mantis_vp2033.h
new file mode 100644 (file)
index 0000000..c55242b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Mantis VP-2033 driver
+
+       Copyright (C) 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 "mantis_common.h"
+
+#define MANTIS_VP_2033_DVB_C   0x0008
+
+extern struct mantis_hwconfig vp2033_config;
+
+#endif /* __MANTIS_VP2033_H */
diff --git a/drivers/media/pci/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c
new file mode 100644 (file)
index 0000000..d480741
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+       Mantis VP-2040 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "tda1002x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp2040.h"
+
+#define MANTIS_MODEL_NAME      "VP-2040"
+#define MANTIS_DEV_TYPE                "DVB-C"
+
+struct tda1002x_config vp2040_tda1002x_cu1216_config = {
+       .demod_address  = 0x18 >> 1,
+       .invert         = 1,
+};
+
+struct tda10023_config vp2040_tda10023_cu1216_config = {
+       .demod_address  = 0x18 >> 1,
+       .invert         = 1,
+};
+
+static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mantis_pci *mantis       = fe->dvb->priv;
+       struct i2c_adapter *adapter     = &mantis->adapter;
+
+       u8 buf[6];
+       struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
+       int i;
+
+#define CU1216_IF 36125000
+#define TUNER_MUL 62500
+
+       u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0xce;
+       buf[3] = (p->frequency < 150000000 ? 0x01 :
+                 p->frequency < 445000000 ? 0x02 : 0x04);
+       buf[4] = 0xde;
+       buf[5] = 0x20;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       if (i2c_transfer(adapter, &msg, 1) != 1)
+               return -EIO;
+
+       /* wait for the pll lock */
+       msg.flags = I2C_M_RD;
+       msg.len = 1;
+       for (i = 0; i < 20; i++) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
+                       break;
+
+               msleep(10);
+       }
+
+       /* switch the charge pump to the lower current */
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = &buf[2];
+       buf[2] &= ~0x40;
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       if (i2c_transfer(adapter, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static u8 read_pwm(struct mantis_pci *mantis)
+{
+       struct i2c_adapter *adapter = &mantis->adapter;
+
+       u8 b = 0xff;
+       u8 pwm;
+       struct i2c_msg msg[] = {
+               {.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
+               {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
+       };
+
+       if ((i2c_transfer(adapter, msg, 2) != 2)
+           || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter = &mantis->adapter;
+
+       int err = 0;
+
+       err = mantis_frontend_power(mantis, POWER_ON);
+       if (err == 0) {
+               mantis_frontend_soft_reset(mantis);
+               msleep(250);
+
+               dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
+               fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config,
+                                    adapter,
+                                    read_pwm(mantis));
+
+               if (fe) {
+                       dprintk(MANTIS_ERROR, 1,
+                               "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
+                               vp2040_tda1002x_cu1216_config.demod_address);
+               } else {
+                       fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config,
+                                            adapter,
+                                            read_pwm(mantis));
+
+                       if (fe) {
+                               dprintk(MANTIS_ERROR, 1,
+                                       "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
+                                       vp2040_tda1002x_cu1216_config.demod_address);
+                       }
+               }
+
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
+                       dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
+               } else {
+                       return -1;
+               }
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+       }
+       mantis->fe = fe;
+       dprintk(MANTIS_DEBUG, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp2040_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_204,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp2040_frontend_init,
+       .power          = GPIF_A12,
+       .reset          = GPIF_A13,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp2040.h b/drivers/media/pci/mantis/mantis_vp2040.h
new file mode 100644 (file)
index 0000000..d125e21
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+       Mantis VP-2040 driver
+
+       Copyright (C) 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_VP2040_H
+#define __MANTIS_VP2040_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_2040_DVB_C   0x0043
+#define CINERGY_C              0x1178
+#define CABLESTAR_HD2          0x0002
+
+extern struct mantis_hwconfig vp2040_config;
+
+#endif /* __MANTIS_VP2040_H */
diff --git a/drivers/media/pci/mantis/mantis_vp3028.c b/drivers/media/pci/mantis/mantis_vp3028.c
new file mode 100644 (file)
index 0000000..4155c83
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+       Mantis VP-3028 driver
+
+       Copyright (C) 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_vp3028.h"
+
+struct zl10353_config mantis_vp3028_config = {
+       .demod_address  = 0x0f,
+};
+
+#define MANTIS_MODEL_NAME      "VP-3028"
+#define MANTIS_DEV_TYPE                "DVB-T"
+
+struct mantis_hwconfig vp3028_mantis_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_188,
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+};
diff --git a/drivers/media/pci/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h
new file mode 100644 (file)
index 0000000..b07be6a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+       Mantis VP-3028 driver
+
+       Copyright (C) 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_VP3028_H
+#define __MANTIS_VP3028_H
+
+#include "dvb_frontend.h"
+#include "mantis_common.h"
+#include "zl10353.h"
+
+#define MANTIS_VP_3028_DVB_T   0x0028
+
+extern struct zl10353_config mantis_vp3028_config;
+extern struct mantis_hwconfig vp3028_mantis_config;
+
+#endif /* __MANTIS_VP3028_H */
diff --git a/drivers/media/pci/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c
new file mode 100644 (file)
index 0000000..c09308c
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+       Mantis VP-3030 driver
+
+       Copyright (C) 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "zl10353.h"
+#include "tda665x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp3030.h"
+
+struct zl10353_config mantis_vp3030_config = {
+       .demod_address          = 0x0f,
+};
+
+struct tda665x_config env57h12d5_config = {
+       .name                   = "ENV57H12D5 (ET-50DT)",
+       .addr                   = 0x60,
+       .frequency_min          =  47000000,
+       .frequency_max          = 862000000,
+       .frequency_offst        =   3616667,
+       .ref_multiplier         = 6, /* 1/6 MHz */
+       .ref_divider            = 100000, /* 1/6 MHz */
+};
+
+#define MANTIS_MODEL_NAME      "VP-3030"
+#define MANTIS_DEV_TYPE                "DVB-T"
+
+
+static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+       struct i2c_adapter *adapter     = &mantis->adapter;
+       struct mantis_hwconfig *config  = mantis->hwconfig;
+       int err = 0;
+
+       mantis_gpio_set_bits(mantis, config->reset, 0);
+       msleep(100);
+       err = mantis_frontend_power(mantis, POWER_ON);
+       msleep(100);
+       mantis_gpio_set_bits(mantis, config->reset, 1);
+
+       if (err == 0) {
+               msleep(250);
+               dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
+               fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter);
+
+               if (!fe)
+                       return -1;
+
+               dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter);
+       } else {
+               dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+                       adapter->name,
+                       err);
+
+               return -EIO;
+
+       }
+       mantis->fe = fe;
+       dprintk(MANTIS_ERROR, 1, "Done!");
+
+       return 0;
+}
+
+struct mantis_hwconfig vp3030_config = {
+       .model_name     = MANTIS_MODEL_NAME,
+       .dev_type       = MANTIS_DEV_TYPE,
+       .ts_size        = MANTIS_TS_188,
+
+       .baud_rate      = MANTIS_BAUD_9600,
+       .parity         = MANTIS_PARITY_NONE,
+       .bytes          = 0,
+
+       .frontend_init  = vp3030_frontend_init,
+       .power          = GPIF_A12,
+       .reset          = GPIF_A13,
+
+       .i2c_mode       = MANTIS_BYTE_MODE
+};
diff --git a/drivers/media/pci/mantis/mantis_vp3030.h b/drivers/media/pci/mantis/mantis_vp3030.h
new file mode 100644 (file)
index 0000000..5f12c42
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+       Mantis VP-3030 driver
+
+       Copyright (C) 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 "mantis_common.h"
+
+#define MANTIS_VP_3030_DVB_T   0x0024
+
+extern struct mantis_hwconfig vp3030_config;
+
+#endif /* __MANTIS_VP3030_H */
diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig
new file mode 100644 (file)
index 0000000..64c8470
--- /dev/null
@@ -0,0 +1,13 @@
+config DVB_NGENE
+       tristate "Micronas nGene support"
+       depends on DVB_CORE && PCI && I2C
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110x if !DVB_FE_CUSTOMISE
+       select DVB_STV090x if !DVB_FE_CUSTOMISE
+       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_DRXK if !DVB_FE_CUSTOMISE
+       select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
+       ---help---
+         Support for Micronas PCI express cards with nGene bridge.
+
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile
new file mode 100644 (file)
index 0000000..6399708
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the nGene device driver
+#
+
+ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
+
+obj-$(CONFIG_DVB_NGENE) += ngene.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/common/tuners/
+
+# For the staging CI driver cxd2099
+ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c
new file mode 100644 (file)
index 0000000..a6cd695
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * ngene-cards.c: nGene PCIe bridge driver - card specific info
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Modifications for new nGene firmware,
+ *                         support for EEPROM-copying,
+ *                         support for new dual DVB-S2 card prototype
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#include "ngene.h"
+
+/* demods/tuners */
+#include "stv6110x.h"
+#include "stv090x.h"
+#include "lnbh24.h"
+#include "lgdt330x.h"
+#include "mt2131.h"
+#include "tda18271c2dd.h"
+#include "drxk.h"
+#include "drxd.h"
+#include "dvb-pll.h"
+
+
+/****************************************************************************/
+/* Demod/tuner attachment ***************************************************/
+/****************************************************************************/
+
+static int tuner_attach_stv6110(struct ngene_channel *chan)
+{
+       struct i2c_adapter *i2c;
+       struct stv090x_config *feconf = (struct stv090x_config *)
+               chan->dev->card_info->fe_config[chan->number];
+       struct stv6110x_config *tunerconf = (struct stv6110x_config *)
+               chan->dev->card_info->tuner_config[chan->number];
+       struct stv6110x_devctl *ctl;
+
+       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
+       if (chan->number < 2)
+               i2c = &chan->dev->channel[0].i2c_adapter;
+       else
+               i2c = &chan->dev->channel[1].i2c_adapter;
+
+       ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
+       if (ctl == NULL) {
+               printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
+               return -ENODEV;
+       }
+
+       feconf->tuner_init          = ctl->tuner_init;
+       feconf->tuner_sleep         = ctl->tuner_sleep;
+       feconf->tuner_set_mode      = ctl->tuner_set_mode;
+       feconf->tuner_set_frequency = ctl->tuner_set_frequency;
+       feconf->tuner_get_frequency = ctl->tuner_get_frequency;
+       feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+       feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+       feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
+       feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
+       feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
+       feconf->tuner_get_status    = ctl->tuner_get_status;
+
+       return 0;
+}
+
+
+static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct ngene_channel *chan = fe->sec_priv;
+       int status;
+
+       if (enable) {
+               down(&chan->dev->pll_mutex);
+               status = chan->gate_ctrl(fe, 1);
+       } else {
+               status = chan->gate_ctrl(fe, 0);
+               up(&chan->dev->pll_mutex);
+       }
+       return status;
+}
+
+static int tuner_attach_tda18271(struct ngene_channel *chan)
+{
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+
+       i2c = &chan->dev->channel[0].i2c_adapter;
+       if (chan->fe->ops.i2c_gate_ctrl)
+               chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
+       fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60);
+       if (chan->fe->ops.i2c_gate_ctrl)
+               chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
+       if (!fe) {
+               printk(KERN_ERR "No TDA18271 found!\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int tuner_attach_probe(struct ngene_channel *chan)
+{
+       if (chan->demod_type == 0)
+               return tuner_attach_stv6110(chan);
+       if (chan->demod_type == 1)
+               return tuner_attach_tda18271(chan);
+       return -EINVAL;
+}
+
+static int demod_attach_stv0900(struct ngene_channel *chan)
+{
+       struct i2c_adapter *i2c;
+       struct stv090x_config *feconf = (struct stv090x_config *)
+               chan->dev->card_info->fe_config[chan->number];
+
+       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
+       /* Note: Both adapters share the same i2c bus, but the demod     */
+       /*       driver requires that each demod has its own i2c adapter */
+       if (chan->number < 2)
+               i2c = &chan->dev->channel[0].i2c_adapter;
+       else
+               i2c = &chan->dev->channel[1].i2c_adapter;
+
+       chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
+                       (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
+                                               : STV090x_DEMODULATOR_1);
+       if (chan->fe == NULL) {
+               printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
+               return -ENODEV;
+       }
+
+       /* store channel info */
+       if (feconf->tuner_i2c_lock)
+               chan->fe->analog_demod_priv = chan;
+
+       if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
+                       0, chan->dev->card_info->lnb[chan->number])) {
+               printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
+               dvb_frontend_detach(chan->fe);
+               chan->fe = NULL;
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
+{
+       struct ngene_channel *chan = fe->analog_demod_priv;
+
+       if (lock)
+               down(&chan->dev->pll_mutex);
+       else
+               up(&chan->dev->pll_mutex);
+}
+
+static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
+{
+       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
+                                  .buf  = val,  .len   = 1 } };
+       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
+}
+
+static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
+                         u16 reg, u8 *val)
+{
+       u8 msg[2] = {reg>>8, reg&0xff};
+       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
+                                  .buf  = msg, .len   = 2},
+                                 {.addr = adr, .flags = I2C_M_RD,
+                                  .buf  = val, .len   = 1} };
+       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
+}
+
+static int port_has_stv0900(struct i2c_adapter *i2c, int port)
+{
+       u8 val;
+       if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0)
+               return 0;
+       return 1;
+}
+
+static int port_has_drxk(struct i2c_adapter *i2c, int port)
+{
+       u8 val;
+
+       if (i2c_read(i2c, 0x29+port, &val) < 0)
+               return 0;
+       return 1;
+}
+
+static int demod_attach_drxk(struct ngene_channel *chan,
+                            struct i2c_adapter *i2c)
+{
+       struct drxk_config config;
+
+       memset(&config, 0, sizeof(config));
+       config.microcode_name = "drxk_a3.mc";
+       config.qam_demod_parameter_count = 4;
+       config.adr = 0x29 + (chan->number ^ 2);
+
+       chan->fe = dvb_attach(drxk_attach, &config, i2c);
+       if (!chan->fe) {
+               printk(KERN_ERR "No DRXK found!\n");
+               return -ENODEV;
+       }
+       chan->fe->sec_priv = chan;
+       chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
+       chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+       return 0;
+}
+
+static int cineS2_probe(struct ngene_channel *chan)
+{
+       struct i2c_adapter *i2c;
+       struct stv090x_config *fe_conf;
+       u8 buf[3];
+       struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
+       int rc;
+
+       /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
+       if (chan->number < 2)
+               i2c = &chan->dev->channel[0].i2c_adapter;
+       else
+               i2c = &chan->dev->channel[1].i2c_adapter;
+
+       if (port_has_stv0900(i2c, chan->number)) {
+               chan->demod_type = 0;
+               fe_conf = chan->dev->card_info->fe_config[chan->number];
+               /* demod found, attach it */
+               rc = demod_attach_stv0900(chan);
+               if (rc < 0 || chan->number < 2)
+                       return rc;
+
+               /* demod #2: reprogram outputs DPN1 & DPN2 */
+               i2c_msg.addr = fe_conf->address;
+               i2c_msg.len = 3;
+               buf[0] = 0xf1;
+               switch (chan->number) {
+               case 2:
+                       buf[1] = 0x5c;
+                       buf[2] = 0xc2;
+                       break;
+               case 3:
+                       buf[1] = 0x61;
+                       buf[2] = 0xcc;
+                       break;
+               default:
+                       return -ENODEV;
+               }
+               rc = i2c_transfer(i2c, &i2c_msg, 1);
+               if (rc != 1) {
+                       printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
+                       return -EIO;
+               }
+       } else if (port_has_drxk(i2c, chan->number^2)) {
+               chan->demod_type = 1;
+               demod_attach_drxk(chan, i2c);
+       } else {
+               printk(KERN_ERR "No demod found on chan %d\n", chan->number);
+               return -ENODEV;
+       }
+       return 0;
+}
+
+
+static struct lgdt330x_config aver_m780 = {
+       .demod_address = 0xb2 >> 1,
+       .demod_chip    = LGDT3303,
+       .serial_mpeg   = 0x00, /* PARALLEL */
+       .clock_polarity_flip = 1,
+};
+
+static struct mt2131_config m780_tunerconfig = {
+       0xc0 >> 1
+};
+
+/* A single func to attach the demo and tuner, rather than
+ * use two sep funcs like the current design mandates.
+ */
+static int demod_attach_lg330x(struct ngene_channel *chan)
+{
+       chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter);
+       if (chan->fe == NULL) {
+               printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n");
+               return -ENODEV;
+       }
+
+       dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter,
+                  &m780_tunerconfig, 0);
+
+       return (chan->fe) ? 0 : -ENODEV;
+}
+
+static int demod_attach_drxd(struct ngene_channel *chan)
+{
+       struct drxd_config *feconf;
+
+       feconf = chan->dev->card_info->fe_config[chan->number];
+
+       chan->fe = dvb_attach(drxd_attach, feconf, chan,
+                       &chan->i2c_adapter, &chan->dev->pci_dev->dev);
+       if (!chan->fe) {
+               pr_err("No DRXD found!\n");
+               return -ENODEV;
+       }
+
+       if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address,
+                       &chan->i2c_adapter,
+                       feconf->pll_type)) {
+               pr_err("No pll(%d) found!\n", feconf->pll_type);
+               return -ENODEV;
+       }
+       return 0;
+}
+
+/****************************************************************************/
+/* EEPROM TAGS **************************************************************/
+/****************************************************************************/
+
+#define MICNG_EE_START      0x0100
+#define MICNG_EE_END        0x0FF0
+
+#define MICNG_EETAG_END0    0x0000
+#define MICNG_EETAG_END1    0xFFFF
+
+/* 0x0001 - 0x000F reserved for housekeeping */
+/* 0xFFFF - 0xFFFE reserved for housekeeping */
+
+/* Micronas assigned tags
+   EEProm tags for hardware support */
+
+#define MICNG_EETAG_DRXD1_OSCDEVIATION  0x1000  /* 2 Bytes data */
+#define MICNG_EETAG_DRXD2_OSCDEVIATION  0x1001  /* 2 Bytes data */
+
+#define MICNG_EETAG_MT2060_1_1STIF      0x1100  /* 2 Bytes data */
+#define MICNG_EETAG_MT2060_2_1STIF      0x1101  /* 2 Bytes data */
+
+/* Tag range for OEMs */
+
+#define MICNG_EETAG_OEM_FIRST  0xC000
+#define MICNG_EETAG_OEM_LAST   0xFFEF
+
+static int i2c_write_eeprom(struct i2c_adapter *adapter,
+                           u8 adr, u16 reg, u8 data)
+{
+       u8 m[3] = {(reg >> 8), (reg & 0xff), data};
+       struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m,
+                             .len = sizeof(m)};
+
+       if (i2c_transfer(adapter, &msg, 1) != 1) {
+               pr_err(DEVICE_NAME ": Error writing EEPROM!\n");
+               return -EIO;
+       }
+       return 0;
+}
+
+static int i2c_read_eeprom(struct i2c_adapter *adapter,
+                          u8 adr, u16 reg, u8 *data, int len)
+{
+       u8 msg[2] = {(reg >> 8), (reg & 0xff)};
+       struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
+                                  .buf = msg, .len = 2 },
+                                 {.addr = adr, .flags = I2C_M_RD,
+                                  .buf = data, .len = len} };
+
+       if (i2c_transfer(adapter, msgs, 2) != 2) {
+               pr_err(DEVICE_NAME ": Error reading EEPROM\n");
+               return -EIO;
+       }
+       return 0;
+}
+
+static int ReadEEProm(struct i2c_adapter *adapter,
+                     u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
+{
+       int status = 0;
+       u16 Addr = MICNG_EE_START, Length, tag = 0;
+       u8  EETag[3];
+
+       while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
+               if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
+                       return -1;
+               tag = (EETag[0] << 8) | EETag[1];
+               if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
+                       return -1;
+               if (tag == Tag)
+                       break;
+               Addr += sizeof(u16) + 1 + EETag[2];
+       }
+       if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
+               pr_err(DEVICE_NAME
+                      ": Reached EOEE @ Tag = %04x Length = %3d\n",
+                      tag, EETag[2]);
+               return -1;
+       }
+       Length = EETag[2];
+       if (Length > MaxLen)
+               Length = (u16) MaxLen;
+       if (Length > 0) {
+               Addr += sizeof(u16) + 1;
+               status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
+               if (!status) {
+                       *pLength = EETag[2];
+                       if (Length < EETag[2])
+                               ; /*status=STATUS_BUFFER_OVERFLOW; */
+               }
+       }
+       return status;
+}
+
+static int WriteEEProm(struct i2c_adapter *adapter,
+                      u16 Tag, u32 Length, u8 *data)
+{
+       int status = 0;
+       u16 Addr = MICNG_EE_START;
+       u8 EETag[3];
+       u16 tag = 0;
+       int retry, i;
+
+       while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
+               if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
+                       return -1;
+               tag = (EETag[0] << 8) | EETag[1];
+               if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
+                       return -1;
+               if (tag == Tag)
+                       break;
+               Addr += sizeof(u16) + 1 + EETag[2];
+       }
+       if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
+               pr_err(DEVICE_NAME
+                      ": Reached EOEE @ Tag = %04x Length = %3d\n",
+                      tag, EETag[2]);
+               return -1;
+       }
+
+       if (Length > EETag[2])
+               return -EINVAL;
+       /* Note: We write the data one byte at a time to avoid
+          issues with page sizes. (which are different for
+          each manufacture and eeprom size)
+        */
+       Addr += sizeof(u16) + 1;
+       for (i = 0; i < Length; i++, Addr++) {
+               status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
+
+               if (status)
+                       break;
+
+               /* Poll for finishing write cycle */
+               retry = 10;
+               while (retry) {
+                       u8 Tmp;
+
+                       msleep(50);
+                       status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
+                       if (status)
+                               break;
+                       if (Tmp != data[i])
+                               pr_err(DEVICE_NAME
+                                      "eeprom write error\n");
+                       retry -= 1;
+               }
+               if (status) {
+                       pr_err(DEVICE_NAME
+                              ": Timeout polling eeprom\n");
+                       break;
+               }
+       }
+       return status;
+}
+
+static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
+{
+       int stat;
+       u8 buf[2];
+       u32 len = 0;
+
+       stat = ReadEEProm(adapter, tag, 2, buf, &len);
+       if (stat)
+               return stat;
+       if (len != 2)
+               return -EINVAL;
+
+       *data = (buf[0] << 8) | buf[1];
+       return 0;
+}
+
+static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
+{
+       int stat;
+       u8 buf[2];
+
+       buf[0] = data >> 8;
+       buf[1] = data & 0xff;
+       stat = WriteEEProm(adapter, tag, 2, buf);
+       if (stat)
+               return stat;
+       return 0;
+}
+
+static s16 osc_deviation(void *priv, s16 deviation, int flag)
+{
+       struct ngene_channel *chan = priv;
+       struct i2c_adapter *adap = &chan->i2c_adapter;
+       u16 data = 0;
+
+       if (flag) {
+               data = (u16) deviation;
+               pr_info(DEVICE_NAME ": write deviation %d\n",
+                      deviation);
+               eeprom_write_ushort(adap, 0x1000 + chan->number, data);
+       } else {
+               if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
+                       data = 0;
+               pr_info(DEVICE_NAME ": read deviation %d\n",
+                      (s16) data);
+       }
+
+       return (s16) data;
+}
+
+/****************************************************************************/
+/* Switch control (I2C gates, etc.) *****************************************/
+/****************************************************************************/
+
+
+static struct stv090x_config fe_cineS2 = {
+       .device         = STV0900,
+       .demod_mode     = STV090x_DUAL,
+       .clk_mode       = STV090x_CLK_EXT,
+
+       .xtal           = 27000000,
+       .address        = 0x68,
+
+       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+
+       .repeater_level = STV090x_RPTLEVEL_16,
+
+       .adc1_range     = STV090x_ADC_1Vpp,
+       .adc2_range     = STV090x_ADC_1Vpp,
+
+       .diseqc_envelope_mode = true,
+
+       .tuner_i2c_lock = cineS2_tuner_i2c_lock,
+};
+
+static struct stv090x_config fe_cineS2_2 = {
+       .device         = STV0900,
+       .demod_mode     = STV090x_DUAL,
+       .clk_mode       = STV090x_CLK_EXT,
+
+       .xtal           = 27000000,
+       .address        = 0x69,
+
+       .ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+       .ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
+
+       .repeater_level = STV090x_RPTLEVEL_16,
+
+       .adc1_range     = STV090x_ADC_1Vpp,
+       .adc2_range     = STV090x_ADC_1Vpp,
+
+       .diseqc_envelope_mode = true,
+
+       .tuner_i2c_lock = cineS2_tuner_i2c_lock,
+};
+
+static struct stv6110x_config tuner_cineS2_0 = {
+       .addr   = 0x60,
+       .refclk = 27000000,
+       .clk_div = 1,
+};
+
+static struct stv6110x_config tuner_cineS2_1 = {
+       .addr   = 0x63,
+       .refclk = 27000000,
+       .clk_div = 1,
+};
+
+static struct ngene_info ngene_info_cineS2 = {
+       .type           = NGENE_SIDEWINDER,
+       .name           = "Linux4Media cineS2 DVB-S2 Twin Tuner",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
+       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900},
+       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110},
+       .fe_config      = {&fe_cineS2, &fe_cineS2},
+       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1},
+       .lnb            = {0x0b, 0x08},
+       .tsf            = {3, 3},
+       .fw_version     = 18,
+       .msi_supported  = true,
+};
+
+static struct ngene_info ngene_info_satixS2 = {
+       .type           = NGENE_SIDEWINDER,
+       .name           = "Mystique SaTiX-S2 Dual",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
+       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900},
+       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110},
+       .fe_config      = {&fe_cineS2, &fe_cineS2},
+       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1},
+       .lnb            = {0x0b, 0x08},
+       .tsf            = {3, 3},
+       .fw_version     = 18,
+       .msi_supported  = true,
+};
+
+static struct ngene_info ngene_info_satixS2v2 = {
+       .type           = NGENE_SIDEWINDER,
+       .name           = "Mystique SaTiX-S2 Dual (v2)",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
+                          NGENE_IO_TSOUT},
+       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
+       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
+       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
+       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
+       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
+       .tsf            = {3, 3},
+       .fw_version     = 18,
+       .msi_supported  = true,
+};
+
+static struct ngene_info ngene_info_cineS2v5 = {
+       .type           = NGENE_SIDEWINDER,
+       .name           = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
+                          NGENE_IO_TSOUT},
+       .demod_attach   = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
+       .tuner_attach   = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
+       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
+       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
+       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
+       .tsf            = {3, 3},
+       .fw_version     = 18,
+       .msi_supported  = true,
+};
+
+
+static struct ngene_info ngene_info_duoFlex = {
+       .type           = NGENE_SIDEWINDER,
+       .name           = "Digital Devices DuoFlex PCIe or miniPCIe",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
+                          NGENE_IO_TSOUT},
+       .demod_attach   = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
+       .tuner_attach   = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe},
+       .fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
+       .tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
+       .lnb            = {0x0a, 0x08, 0x0b, 0x09},
+       .tsf            = {3, 3},
+       .fw_version     = 18,
+       .msi_supported  = true,
+};
+
+static struct ngene_info ngene_info_m780 = {
+       .type           = NGENE_APP,
+       .name           = "Aver M780 ATSC/QAM-B",
+
+       /* Channel 0 is analog, which is currently unsupported */
+       .io_type        = { NGENE_IO_NONE, NGENE_IO_TSIN },
+       .demod_attach   = { NULL, demod_attach_lg330x },
+
+       /* Ensure these are NULL else the frame will call them (as funcs) */
+       .tuner_attach   = { 0, 0, 0, 0 },
+       .fe_config      = { NULL, &aver_m780 },
+       .avf            = { 0 },
+
+       /* A custom electrical interface config for the demod to bridge */
+       .tsf            = { 4, 4 },
+       .fw_version     = 15,
+};
+
+static struct drxd_config fe_terratec_dvbt_0 = {
+       .index          = 0,
+       .demod_address  = 0x70,
+       .demod_revision = 0xa2,
+       .demoda_address = 0x00,
+       .pll_address    = 0x60,
+       .pll_type       = DVB_PLL_THOMSON_DTT7520X,
+       .clock          = 20000,
+       .osc_deviation  = osc_deviation,
+};
+
+static struct drxd_config fe_terratec_dvbt_1 = {
+       .index          = 1,
+       .demod_address  = 0x71,
+       .demod_revision = 0xa2,
+       .demoda_address = 0x00,
+       .pll_address    = 0x60,
+       .pll_type       = DVB_PLL_THOMSON_DTT7520X,
+       .clock          = 20000,
+       .osc_deviation  = osc_deviation,
+};
+
+static struct ngene_info ngene_info_terratec = {
+       .type           = NGENE_TERRATEC,
+       .name           = "Terratec Integra/Cinergy2400i Dual DVB-T",
+       .io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
+       .demod_attach   = {demod_attach_drxd, demod_attach_drxd},
+       .fe_config      = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
+       .i2c_access     = 1,
+};
+
+/****************************************************************************/
+
+
+
+/****************************************************************************/
+/* PCI Subsystem ID *********************************************************/
+/****************************************************************************/
+
+#define NGENE_ID(_subvend, _subdev, _driverdata) { \
+       .vendor = NGENE_VID, .device = NGENE_PID, \
+       .subvendor = _subvend, .subdevice = _subdev, \
+       .driver_data = (unsigned long) &_driverdata }
+
+/****************************************************************************/
+
+static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
+       NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
+       NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
+       NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
+       NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
+       NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
+       NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex),
+       NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
+       NGENE_ID(0x1461, 0x062e, ngene_info_m780),
+       NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
+       {0}
+};
+MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
+
+/****************************************************************************/
+/* Init/Exit ****************************************************************/
+/****************************************************************************/
+
+static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
+                                            enum pci_channel_state state)
+{
+       printk(KERN_ERR DEVICE_NAME ": PCI error\n");
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+       if (state == pci_channel_io_frozen)
+               return PCI_ERS_RESULT_NEED_RESET;
+       return PCI_ERS_RESULT_CAN_RECOVER;
+}
+
+static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
+{
+       printk(KERN_INFO DEVICE_NAME ": link reset\n");
+       return 0;
+}
+
+static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
+{
+       printk(KERN_INFO DEVICE_NAME ": slot reset\n");
+       return 0;
+}
+
+static void ngene_resume(struct pci_dev *dev)
+{
+       printk(KERN_INFO DEVICE_NAME ": resume\n");
+}
+
+static struct pci_error_handlers ngene_errors = {
+       .error_detected = ngene_error_detected,
+       .link_reset = ngene_link_reset,
+       .slot_reset = ngene_slot_reset,
+       .resume = ngene_resume,
+};
+
+static struct pci_driver ngene_pci_driver = {
+       .name        = "ngene",
+       .id_table    = ngene_id_tbl,
+       .probe       = ngene_probe,
+       .remove      = __devexit_p(ngene_remove),
+       .err_handler = &ngene_errors,
+       .shutdown    = ngene_shutdown,
+};
+
+static __init int module_init_ngene(void)
+{
+       printk(KERN_INFO
+              "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
+       return pci_register_driver(&ngene_pci_driver);
+}
+
+static __exit void module_exit_ngene(void)
+{
+       pci_unregister_driver(&ngene_pci_driver);
+}
+
+module_init(module_init_ngene);
+module_exit(module_exit_ngene);
+
+MODULE_DESCRIPTION("nGene");
+MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
new file mode 100644 (file)
index 0000000..c8e0d5b
--- /dev/null
@@ -0,0 +1,1707 @@
+/*
+ * ngene.c: nGene PCIe bridge driver
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Modifications for new nGene firmware,
+ *                         support for EEPROM-copying,
+ *                         support for new dual DVB-S2 card prototype
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/byteorder/generic.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include "ngene.h"
+
+static int one_adapter;
+module_param(one_adapter, int, 0444);
+MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
+
+static int shutdown_workaround;
+module_param(shutdown_workaround, int, 0644);
+MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets.");
+
+static int debug;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Print debugging information.");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define dprintk        if (debug) printk
+
+#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
+#define ngwritel(dat, adr)         writel((dat), (char *)(dev->iomem + (adr)))
+#define ngwriteb(dat, adr)         writeb((dat), (char *)(dev->iomem + (adr)))
+#define ngreadl(adr)               readl(dev->iomem + (adr))
+#define ngreadb(adr)               readb(dev->iomem + (adr))
+#define ngcpyto(adr, src, count)   memcpy_toio((char *) \
+                                  (dev->iomem + (adr)), (src), (count))
+#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \
+                                  (dev->iomem + (adr)), (count))
+
+/****************************************************************************/
+/* nGene interrupt handler **************************************************/
+/****************************************************************************/
+
+static void event_tasklet(unsigned long data)
+{
+       struct ngene *dev = (struct ngene *)data;
+
+       while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) {
+               struct EVENT_BUFFER Event =
+                       dev->EventQueue[dev->EventQueueReadIndex];
+               dev->EventQueueReadIndex =
+                       (dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1);
+
+               if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify))
+                       dev->TxEventNotify(dev, Event.TimeStamp);
+               if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify))
+                       dev->RxEventNotify(dev, Event.TimeStamp,
+                                          Event.RXCharacter);
+       }
+}
+
+static void demux_tasklet(unsigned long data)
+{
+       struct ngene_channel *chan = (struct ngene_channel *)data;
+       struct SBufferHeader *Cur = chan->nextBuffer;
+
+       spin_lock_irq(&chan->state_lock);
+
+       while (Cur->ngeneBuffer.SR.Flags & 0x80) {
+               if (chan->mode & NGENE_IO_TSOUT) {
+                       u32 Flags = chan->DataFormatFlags;
+                       if (Cur->ngeneBuffer.SR.Flags & 0x20)
+                               Flags |= BEF_OVERFLOW;
+                       if (chan->pBufferExchange) {
+                               if (!chan->pBufferExchange(chan,
+                                                          Cur->Buffer1,
+                                                          chan->Capture1Length,
+                                                          Cur->ngeneBuffer.SR.
+                                                          Clock, Flags)) {
+                                       /*
+                                          We didn't get data
+                                          Clear in service flag to make sure we
+                                          get called on next interrupt again.
+                                          leave fill/empty (0x80) flag alone
+                                          to avoid hardware running out of
+                                          buffers during startup, we hold only
+                                          in run state ( the source may be late
+                                          delivering data )
+                                       */
+
+                                       if (chan->HWState == HWSTATE_RUN) {
+                                               Cur->ngeneBuffer.SR.Flags &=
+                                                       ~0x40;
+                                               break;
+                                               /* Stop processing stream */
+                                       }
+                               } else {
+                                       /* We got a valid buffer,
+                                          so switch to run state */
+                                       chan->HWState = HWSTATE_RUN;
+                               }
+                       } else {
+                               printk(KERN_ERR DEVICE_NAME ": OOPS\n");
+                               if (chan->HWState == HWSTATE_RUN) {
+                                       Cur->ngeneBuffer.SR.Flags &= ~0x40;
+                                       break;  /* Stop processing stream */
+                               }
+                       }
+                       if (chan->AudioDTOUpdated) {
+                               printk(KERN_INFO DEVICE_NAME
+                                      ": Update AudioDTO = %d\n",
+                                      chan->AudioDTOValue);
+                               Cur->ngeneBuffer.SR.DTOUpdate =
+                                       chan->AudioDTOValue;
+                               chan->AudioDTOUpdated = 0;
+                       }
+               } else {
+                       if (chan->HWState == HWSTATE_RUN) {
+                               u32 Flags = chan->DataFormatFlags;
+                               IBufferExchange *exch1 = chan->pBufferExchange;
+                               IBufferExchange *exch2 = chan->pBufferExchange2;
+                               if (Cur->ngeneBuffer.SR.Flags & 0x01)
+                                       Flags |= BEF_EVEN_FIELD;
+                               if (Cur->ngeneBuffer.SR.Flags & 0x20)
+                                       Flags |= BEF_OVERFLOW;
+                               spin_unlock_irq(&chan->state_lock);
+                               if (exch1)
+                                       exch1(chan, Cur->Buffer1,
+                                               chan->Capture1Length,
+                                               Cur->ngeneBuffer.SR.Clock,
+                                               Flags);
+                               if (exch2)
+                                       exch2(chan, Cur->Buffer2,
+                                               chan->Capture2Length,
+                                               Cur->ngeneBuffer.SR.Clock,
+                                               Flags);
+                               spin_lock_irq(&chan->state_lock);
+                       } else if (chan->HWState != HWSTATE_STOP)
+                               chan->HWState = HWSTATE_RUN;
+               }
+               Cur->ngeneBuffer.SR.Flags = 0x00;
+               Cur = Cur->Next;
+       }
+       chan->nextBuffer = Cur;
+
+       spin_unlock_irq(&chan->state_lock);
+}
+
+static irqreturn_t irq_handler(int irq, void *dev_id)
+{
+       struct ngene *dev = (struct ngene *)dev_id;
+       u32 icounts = 0;
+       irqreturn_t rc = IRQ_NONE;
+       u32 i = MAX_STREAM;
+       u8 *tmpCmdDoneByte;
+
+       if (dev->BootFirmware) {
+               icounts = ngreadl(NGENE_INT_COUNTS);
+               if (icounts != dev->icounts) {
+                       ngwritel(0, FORCE_NMI);
+                       dev->cmd_done = 1;
+                       wake_up(&dev->cmd_wq);
+                       dev->icounts = icounts;
+                       rc = IRQ_HANDLED;
+               }
+               return rc;
+       }
+
+       ngwritel(0, FORCE_NMI);
+
+       spin_lock(&dev->cmd_lock);
+       tmpCmdDoneByte = dev->CmdDoneByte;
+       if (tmpCmdDoneByte &&
+           (*tmpCmdDoneByte ||
+           (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) {
+               dev->CmdDoneByte = NULL;
+               dev->cmd_done = 1;
+               wake_up(&dev->cmd_wq);
+               rc = IRQ_HANDLED;
+       }
+       spin_unlock(&dev->cmd_lock);
+
+       if (dev->EventBuffer->EventStatus & 0x80) {
+               u8 nextWriteIndex =
+                       (dev->EventQueueWriteIndex + 1) &
+                       (EVENT_QUEUE_SIZE - 1);
+               if (nextWriteIndex != dev->EventQueueReadIndex) {
+                       dev->EventQueue[dev->EventQueueWriteIndex] =
+                               *(dev->EventBuffer);
+                       dev->EventQueueWriteIndex = nextWriteIndex;
+               } else {
+                       printk(KERN_ERR DEVICE_NAME ": event overflow\n");
+                       dev->EventQueueOverflowCount += 1;
+                       dev->EventQueueOverflowFlag = 1;
+               }
+               dev->EventBuffer->EventStatus &= ~0x80;
+               tasklet_schedule(&dev->event_tasklet);
+               rc = IRQ_HANDLED;
+       }
+
+       while (i > 0) {
+               i--;
+               spin_lock(&dev->channel[i].state_lock);
+               /* if (dev->channel[i].State>=KSSTATE_RUN) { */
+               if (dev->channel[i].nextBuffer) {
+                       if ((dev->channel[i].nextBuffer->
+                            ngeneBuffer.SR.Flags & 0xC0) == 0x80) {
+                               dev->channel[i].nextBuffer->
+                                       ngeneBuffer.SR.Flags |= 0x40;
+                               tasklet_schedule(
+                                       &dev->channel[i].demux_tasklet);
+                               rc = IRQ_HANDLED;
+                       }
+               }
+               spin_unlock(&dev->channel[i].state_lock);
+       }
+
+       /* Request might have been processed by a previous call. */
+       return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+/* nGene command interface **************************************************/
+/****************************************************************************/
+
+static void dump_command_io(struct ngene *dev)
+{
+       u8 buf[8], *b;
+
+       ngcpyfrom(buf, HOST_TO_NGENE, 8);
+       printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf);
+
+       ngcpyfrom(buf, NGENE_TO_HOST, 8);
+       printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf);
+
+       b = dev->hosttongene;
+       printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b);
+
+       b = dev->ngenetohost;
+       printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b);
+}
+
+static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
+{
+       int ret;
+       u8 *tmpCmdDoneByte;
+
+       dev->cmd_done = 0;
+
+       if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) {
+               dev->BootFirmware = 1;
+               dev->icounts = ngreadl(NGENE_INT_COUNTS);
+               ngwritel(0, NGENE_COMMAND);
+               ngwritel(0, NGENE_COMMAND_HI);
+               ngwritel(0, NGENE_STATUS);
+               ngwritel(0, NGENE_STATUS_HI);
+               ngwritel(0, NGENE_EVENT);
+               ngwritel(0, NGENE_EVENT_HI);
+       } else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) {
+               u64 fwio = dev->PAFWInterfaceBuffer;
+
+               ngwritel(fwio & 0xffffffff, NGENE_COMMAND);
+               ngwritel(fwio >> 32, NGENE_COMMAND_HI);
+               ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS);
+               ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI);
+               ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT);
+               ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI);
+       }
+
+       memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2);
+
+       if (dev->BootFirmware)
+               ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2);
+
+       spin_lock_irq(&dev->cmd_lock);
+       tmpCmdDoneByte = dev->ngenetohost + com->out_len;
+       if (!com->out_len)
+               tmpCmdDoneByte++;
+       *tmpCmdDoneByte = 0;
+       dev->ngenetohost[0] = 0;
+       dev->ngenetohost[1] = 0;
+       dev->CmdDoneByte = tmpCmdDoneByte;
+       spin_unlock_irq(&dev->cmd_lock);
+
+       /* Notify 8051. */
+       ngwritel(1, FORCE_INT);
+
+       ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ);
+       if (!ret) {
+               /*ngwritel(0, FORCE_NMI);*/
+
+               printk(KERN_ERR DEVICE_NAME
+                      ": Command timeout cmd=%02x prev=%02x\n",
+                      com->cmd.hdr.Opcode, dev->prev_cmd);
+               dump_command_io(dev);
+               return -1;
+       }
+       if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH)
+               dev->BootFirmware = 0;
+
+       dev->prev_cmd = com->cmd.hdr.Opcode;
+
+       if (!com->out_len)
+               return 0;
+
+       memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len);
+
+       return 0;
+}
+
+int ngene_command(struct ngene *dev, struct ngene_command *com)
+{
+       int result;
+
+       down(&dev->cmd_mutex);
+       result = ngene_command_mutex(dev, com);
+       up(&dev->cmd_mutex);
+       return result;
+}
+
+
+static int ngene_command_load_firmware(struct ngene *dev,
+                                      u8 *ngene_fw, u32 size)
+{
+#define FIRSTCHUNK (1024)
+       u32 cleft;
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE;
+       com.cmd.hdr.Length = 0;
+       com.in_len = 0;
+       com.out_len = 0;
+
+       ngene_command(dev, &com);
+
+       cleft = (size + 3) & ~3;
+       if (cleft > FIRSTCHUNK) {
+               ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK,
+                       cleft - FIRSTCHUNK);
+               cleft = FIRSTCHUNK;
+       }
+       ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft);
+
+       memset(&com, 0, sizeof(struct ngene_command));
+       com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH;
+       com.cmd.hdr.Length = 4;
+       com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA;
+       com.cmd.FWLoadFinish.Length = (unsigned short)cleft;
+       com.in_len = 4;
+       com.out_len = 0;
+
+       return ngene_command(dev, &com);
+}
+
+
+static int ngene_command_config_buf(struct ngene *dev, u8 config)
+{
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER;
+       com.cmd.hdr.Length = 1;
+       com.cmd.ConfigureBuffers.config = config;
+       com.in_len = 1;
+       com.out_len = 0;
+
+       if (ngene_command(dev, &com) < 0)
+               return -EIO;
+       return 0;
+}
+
+static int ngene_command_config_free_buf(struct ngene *dev, u8 *config)
+{
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER;
+       com.cmd.hdr.Length = 6;
+       memcpy(&com.cmd.ConfigureBuffers.config, config, 6);
+       com.in_len = 6;
+       com.out_len = 0;
+
+       if (ngene_command(dev, &com) < 0)
+               return -EIO;
+
+       return 0;
+}
+
+int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
+{
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN;
+       com.cmd.hdr.Length = 1;
+       com.cmd.SetGpioPin.select = select | (level << 7);
+       com.in_len = 1;
+       com.out_len = 0;
+
+       return ngene_command(dev, &com);
+}
+
+
+/*
+ 02000640 is sample on rising edge.
+ 02000740 is sample on falling edge.
+ 02000040 is ignore "valid" signal
+
+ 0: FD_CTL1 Bit 7,6 must be 0,1
+    7   disable(fw controlled)
+    6   0-AUX,1-TS
+    5   0-par,1-ser
+    4   0-lsb/1-msb
+    3,2 reserved
+    1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both
+ 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge
+ 2: FD_STA is read-only. 0-sync
+ 3: FD_INSYNC is number of 47s to trigger "in sync".
+ 4: FD_OUTSYNC is number of 47s to trigger "out of sync".
+ 5: FD_MAXBYTE1 is low-order of bytes per packet.
+ 6: FD_MAXBYTE2 is high-order of bytes per packet.
+ 7: Top byte is unused.
+*/
+
+/****************************************************************************/
+
+static u8 TSFeatureDecoderSetup[8 * 5] = {
+       0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,
+       0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */
+       0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */
+       0x72, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */
+       0x40, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* LGDT3303 */
+};
+
+/* Set NGENE I2S Config to 16 bit packed */
+static u8 I2SConfiguration[] = {
+       0x00, 0x10, 0x00, 0x00,
+       0x80, 0x10, 0x00, 0x00,
+};
+
+static u8 SPDIFConfiguration[10] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Set NGENE I2S Config to transport stream compatible mode */
+
+static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 };
+
+static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 };
+
+static u8 ITUDecoderSetup[4][16] = {
+       {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20,  /* SDTV */
+        0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00},
+       {0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+       {0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00,  /* HDTV 1080i50 */
+        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+       {0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,  /* HDTV 1080i60 */
+        0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
+};
+
+/*
+ * 50 48 60 gleich
+ * 27p50 9f 00 22 80 42 69 18 ...
+ * 27p60 93 00 22 80 82 69 1c ...
+ */
+
+/* Maxbyte to 1144 (for raw data) */
+static u8 ITUFeatureDecoderSetup[8] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00
+};
+
+void FillTSBuffer(void *Buffer, int Length, u32 Flags)
+{
+       u32 *ptr = Buffer;
+
+       memset(Buffer, TS_FILLER, Length);
+       while (Length > 0) {
+               if (Flags & DF_SWAP32)
+                       *ptr = 0x471FFF10;
+               else
+                       *ptr = 0x10FF1F47;
+               ptr += (188 / 4);
+               Length -= 188;
+       }
+}
+
+
+static void flush_buffers(struct ngene_channel *chan)
+{
+       u8 val;
+
+       do {
+               msleep(1);
+               spin_lock_irq(&chan->state_lock);
+               val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80;
+               spin_unlock_irq(&chan->state_lock);
+       } while (val);
+}
+
+static void clear_buffers(struct ngene_channel *chan)
+{
+       struct SBufferHeader *Cur = chan->nextBuffer;
+
+       do {
+               memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR));
+               if (chan->mode & NGENE_IO_TSOUT)
+                       FillTSBuffer(Cur->Buffer1,
+                                    chan->Capture1Length,
+                                    chan->DataFormatFlags);
+               Cur = Cur->Next;
+       } while (Cur != chan->nextBuffer);
+
+       if (chan->mode & NGENE_IO_TSOUT) {
+               chan->nextBuffer->ngeneBuffer.SR.DTOUpdate =
+                       chan->AudioDTOValue;
+               chan->AudioDTOUpdated = 0;
+
+               Cur = chan->TSIdleBuffer.Head;
+
+               do {
+                       memset(&Cur->ngeneBuffer.SR, 0,
+                              sizeof(Cur->ngeneBuffer.SR));
+                       FillTSBuffer(Cur->Buffer1,
+                                    chan->Capture1Length,
+                                    chan->DataFormatFlags);
+                       Cur = Cur->Next;
+               } while (Cur != chan->TSIdleBuffer.Head);
+       }
+}
+
+static int ngene_command_stream_control(struct ngene *dev, u8 stream,
+                                       u8 control, u8 mode, u8 flags)
+{
+       struct ngene_channel *chan = &dev->channel[stream];
+       struct ngene_command com;
+       u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300);
+       u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500);
+       u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
+       u16 BsSDO = 0x9B00;
+
+       down(&dev->stream_mutex);
+       memset(&com, 0, sizeof(com));
+       com.cmd.hdr.Opcode = CMD_CONTROL;
+       com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
+       com.cmd.StreamControl.Stream = stream | (control ? 8 : 0);
+       if (chan->mode & NGENE_IO_TSOUT)
+               com.cmd.StreamControl.Stream |= 0x07;
+       com.cmd.StreamControl.Control = control |
+               (flags & SFLAG_ORDER_LUMA_CHROMA);
+       com.cmd.StreamControl.Mode = mode;
+       com.in_len = sizeof(struct FW_STREAM_CONTROL);
+       com.out_len = 0;
+
+       dprintk(KERN_INFO DEVICE_NAME
+               ": Stream=%02x, Control=%02x, Mode=%02x\n",
+               com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control,
+               com.cmd.StreamControl.Mode);
+
+       chan->Mode = mode;
+
+       if (!(control & 0x80)) {
+               spin_lock_irq(&chan->state_lock);
+               if (chan->State == KSSTATE_RUN) {
+                       chan->State = KSSTATE_ACQUIRE;
+                       chan->HWState = HWSTATE_STOP;
+                       spin_unlock_irq(&chan->state_lock);
+                       if (ngene_command(dev, &com) < 0) {
+                               up(&dev->stream_mutex);
+                               return -1;
+                       }
+                       /* clear_buffers(chan); */
+                       flush_buffers(chan);
+                       up(&dev->stream_mutex);
+                       return 0;
+               }
+               spin_unlock_irq(&chan->state_lock);
+               up(&dev->stream_mutex);
+               return 0;
+       }
+
+       if (mode & SMODE_AUDIO_CAPTURE) {
+               com.cmd.StreamControl.CaptureBlockCount =
+                       chan->Capture1Length / AUDIO_BLOCK_SIZE;
+               com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
+       } else if (mode & SMODE_TRANSPORT_STREAM) {
+               com.cmd.StreamControl.CaptureBlockCount =
+                       chan->Capture1Length / TS_BLOCK_SIZE;
+               com.cmd.StreamControl.MaxLinesPerField =
+                       chan->Capture1Length / TS_BLOCK_SIZE;
+               com.cmd.StreamControl.Buffer_Address =
+                       chan->TSRingBuffer.PAHead;
+               if (chan->mode & NGENE_IO_TSOUT) {
+                       com.cmd.StreamControl.BytesPerVBILine =
+                               chan->Capture1Length / TS_BLOCK_SIZE;
+                       com.cmd.StreamControl.Stream |= 0x07;
+               }
+       } else {
+               com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine;
+               com.cmd.StreamControl.MaxLinesPerField = chan->nLines;
+               com.cmd.StreamControl.MinLinesPerField = 100;
+               com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
+
+               if (mode & SMODE_VBI_CAPTURE) {
+                       com.cmd.StreamControl.MaxVBILinesPerField =
+                               chan->nVBILines;
+                       com.cmd.StreamControl.MinVBILinesPerField = 0;
+                       com.cmd.StreamControl.BytesPerVBILine =
+                               chan->nBytesPerVBILine;
+               }
+               if (flags & SFLAG_COLORBAR)
+                       com.cmd.StreamControl.Stream |= 0x04;
+       }
+
+       spin_lock_irq(&chan->state_lock);
+       if (mode & SMODE_AUDIO_CAPTURE) {
+               chan->nextBuffer = chan->RingBuffer.Head;
+               if (mode & SMODE_AUDIO_SPDIF) {
+                       com.cmd.StreamControl.SetupDataLen =
+                               sizeof(SPDIFConfiguration);
+                       com.cmd.StreamControl.SetupDataAddr = BsSPI;
+                       memcpy(com.cmd.StreamControl.SetupData,
+                              SPDIFConfiguration, sizeof(SPDIFConfiguration));
+               } else {
+                       com.cmd.StreamControl.SetupDataLen = 4;
+                       com.cmd.StreamControl.SetupDataAddr = BsSDI;
+                       memcpy(com.cmd.StreamControl.SetupData,
+                              I2SConfiguration +
+                              4 * dev->card_info->i2s[stream], 4);
+               }
+       } else if (mode & SMODE_TRANSPORT_STREAM) {
+               chan->nextBuffer = chan->TSRingBuffer.Head;
+               if (stream >= STREAM_AUDIOIN1) {
+                       if (chan->mode & NGENE_IO_TSOUT) {
+                               com.cmd.StreamControl.SetupDataLen =
+                                       sizeof(TS_I2SOutConfiguration);
+                               com.cmd.StreamControl.SetupDataAddr = BsSDO;
+                               memcpy(com.cmd.StreamControl.SetupData,
+                                      TS_I2SOutConfiguration,
+                                      sizeof(TS_I2SOutConfiguration));
+                       } else {
+                               com.cmd.StreamControl.SetupDataLen =
+                                       sizeof(TS_I2SConfiguration);
+                               com.cmd.StreamControl.SetupDataAddr = BsSDI;
+                               memcpy(com.cmd.StreamControl.SetupData,
+                                      TS_I2SConfiguration,
+                                      sizeof(TS_I2SConfiguration));
+                       }
+               } else {
+                       com.cmd.StreamControl.SetupDataLen = 8;
+                       com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10;
+                       memcpy(com.cmd.StreamControl.SetupData,
+                              TSFeatureDecoderSetup +
+                              8 * dev->card_info->tsf[stream], 8);
+               }
+       } else {
+               chan->nextBuffer = chan->RingBuffer.Head;
+               com.cmd.StreamControl.SetupDataLen =
+                       16 + sizeof(ITUFeatureDecoderSetup);
+               com.cmd.StreamControl.SetupDataAddr = BsUVI;
+               memcpy(com.cmd.StreamControl.SetupData,
+                      ITUDecoderSetup[chan->itumode], 16);
+               memcpy(com.cmd.StreamControl.SetupData + 16,
+                      ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup));
+       }
+       clear_buffers(chan);
+       chan->State = KSSTATE_RUN;
+       if (mode & SMODE_TRANSPORT_STREAM)
+               chan->HWState = HWSTATE_RUN;
+       else
+               chan->HWState = HWSTATE_STARTUP;
+       spin_unlock_irq(&chan->state_lock);
+
+       if (ngene_command(dev, &com) < 0) {
+               up(&dev->stream_mutex);
+               return -1;
+       }
+       up(&dev->stream_mutex);
+       return 0;
+}
+
+void set_transfer(struct ngene_channel *chan, int state)
+{
+       u8 control = 0, mode = 0, flags = 0;
+       struct ngene *dev = chan->dev;
+       int ret;
+
+       /*
+       printk(KERN_INFO DEVICE_NAME ": st %d\n", state);
+       msleep(100);
+       */
+
+       if (state) {
+               if (chan->running) {
+                       printk(KERN_INFO DEVICE_NAME ": already running\n");
+                       return;
+               }
+       } else {
+               if (!chan->running) {
+                       printk(KERN_INFO DEVICE_NAME ": already stopped\n");
+                       return;
+               }
+       }
+
+       if (dev->card_info->switch_ctrl)
+               dev->card_info->switch_ctrl(chan, 1, state ^ 1);
+
+       if (state) {
+               spin_lock_irq(&chan->state_lock);
+
+               /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
+                         ngreadl(0x9310)); */
+               dvb_ringbuffer_flush(&dev->tsout_rbuf);
+               control = 0x80;
+               if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+                       chan->Capture1Length = 512 * 188;
+                       mode = SMODE_TRANSPORT_STREAM;
+               }
+               if (chan->mode & NGENE_IO_TSOUT) {
+                       chan->pBufferExchange = tsout_exchange;
+                       /* 0x66666666 = 50MHz *2^33 /250MHz */
+                       chan->AudioDTOValue = 0x80000000;
+                       chan->AudioDTOUpdated = 1;
+               }
+               if (chan->mode & NGENE_IO_TSIN)
+                       chan->pBufferExchange = tsin_exchange;
+               spin_unlock_irq(&chan->state_lock);
+       } else
+               ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
+                          ngreadl(0x9310)); */
+
+       ret = ngene_command_stream_control(dev, chan->number,
+                                          control, mode, flags);
+       if (!ret)
+               chan->running = state;
+       else
+               printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n",
+                      state);
+       if (!state) {
+               spin_lock_irq(&chan->state_lock);
+               chan->pBufferExchange = NULL;
+               dvb_ringbuffer_flush(&dev->tsout_rbuf);
+               spin_unlock_irq(&chan->state_lock);
+       }
+}
+
+
+/****************************************************************************/
+/* nGene hardware init and release functions ********************************/
+/****************************************************************************/
+
+static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb)
+{
+       struct SBufferHeader *Cur = rb->Head;
+       u32 j;
+
+       if (!Cur)
+               return;
+
+       for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) {
+               if (Cur->Buffer1)
+                       pci_free_consistent(dev->pci_dev,
+                                           rb->Buffer1Length,
+                                           Cur->Buffer1,
+                                           Cur->scList1->Address);
+
+               if (Cur->Buffer2)
+                       pci_free_consistent(dev->pci_dev,
+                                           rb->Buffer2Length,
+                                           Cur->Buffer2,
+                                           Cur->scList2->Address);
+       }
+
+       if (rb->SCListMem)
+               pci_free_consistent(dev->pci_dev, rb->SCListMemSize,
+                                   rb->SCListMem, rb->PASCListMem);
+
+       pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead);
+}
+
+static void free_idlebuffer(struct ngene *dev,
+                    struct SRingBufferDescriptor *rb,
+                    struct SRingBufferDescriptor *tb)
+{
+       int j;
+       struct SBufferHeader *Cur = tb->Head;
+
+       if (!rb->Head)
+               return;
+       free_ringbuffer(dev, rb);
+       for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) {
+               Cur->Buffer2 = NULL;
+               Cur->scList2 = NULL;
+               Cur->ngeneBuffer.Address_of_first_entry_2 = 0;
+               Cur->ngeneBuffer.Number_of_entries_2 = 0;
+       }
+}
+
+static void free_common_buffers(struct ngene *dev)
+{
+       u32 i;
+       struct ngene_channel *chan;
+
+       for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
+               chan = &dev->channel[i];
+               free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer);
+               free_ringbuffer(dev, &chan->RingBuffer);
+               free_ringbuffer(dev, &chan->TSRingBuffer);
+       }
+
+       if (dev->OverflowBuffer)
+               pci_free_consistent(dev->pci_dev,
+                                   OVERFLOW_BUFFER_SIZE,
+                                   dev->OverflowBuffer, dev->PAOverflowBuffer);
+
+       if (dev->FWInterfaceBuffer)
+               pci_free_consistent(dev->pci_dev,
+                                   4096,
+                                   dev->FWInterfaceBuffer,
+                                   dev->PAFWInterfaceBuffer);
+}
+
+/****************************************************************************/
+/* Ring buffer handling *****************************************************/
+/****************************************************************************/
+
+static int create_ring_buffer(struct pci_dev *pci_dev,
+                      struct SRingBufferDescriptor *descr, u32 NumBuffers)
+{
+       dma_addr_t tmp;
+       struct SBufferHeader *Head;
+       u32 i;
+       u32 MemSize = SIZEOF_SBufferHeader * NumBuffers;
+       u64 PARingBufferHead;
+       u64 PARingBufferCur;
+       u64 PARingBufferNext;
+       struct SBufferHeader *Cur, *Next;
+
+       descr->Head = NULL;
+       descr->MemSize = 0;
+       descr->PAHead = 0;
+       descr->NumBuffers = 0;
+
+       if (MemSize < 4096)
+               MemSize = 4096;
+
+       Head = pci_alloc_consistent(pci_dev, MemSize, &tmp);
+       PARingBufferHead = tmp;
+
+       if (!Head)
+               return -ENOMEM;
+
+       memset(Head, 0, MemSize);
+
+       PARingBufferCur = PARingBufferHead;
+       Cur = Head;
+
+       for (i = 0; i < NumBuffers - 1; i++) {
+               Next = (struct SBufferHeader *)
+                       (((u8 *) Cur) + SIZEOF_SBufferHeader);
+               PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader;
+               Cur->Next = Next;
+               Cur->ngeneBuffer.Next = PARingBufferNext;
+               Cur = Next;
+               PARingBufferCur = PARingBufferNext;
+       }
+       /* Last Buffer points back to first one */
+       Cur->Next = Head;
+       Cur->ngeneBuffer.Next = PARingBufferHead;
+
+       descr->Head       = Head;
+       descr->MemSize    = MemSize;
+       descr->PAHead     = PARingBufferHead;
+       descr->NumBuffers = NumBuffers;
+
+       return 0;
+}
+
+static int AllocateRingBuffers(struct pci_dev *pci_dev,
+                              dma_addr_t of,
+                              struct SRingBufferDescriptor *pRingBuffer,
+                              u32 Buffer1Length, u32 Buffer2Length)
+{
+       dma_addr_t tmp;
+       u32 i, j;
+       int status = 0;
+       u32 SCListMemSize = pRingBuffer->NumBuffers
+               * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) :
+                   NUM_SCATTER_GATHER_ENTRIES)
+               * sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+       u64 PASCListMem;
+       struct HW_SCATTER_GATHER_ELEMENT *SCListEntry;
+       u64 PASCListEntry;
+       struct SBufferHeader *Cur;
+       void *SCListMem;
+
+       if (SCListMemSize < 4096)
+               SCListMemSize = 4096;
+
+       SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp);
+
+       PASCListMem = tmp;
+       if (SCListMem == NULL)
+               return -ENOMEM;
+
+       memset(SCListMem, 0, SCListMemSize);
+
+       pRingBuffer->SCListMem = SCListMem;
+       pRingBuffer->PASCListMem = PASCListMem;
+       pRingBuffer->SCListMemSize = SCListMemSize;
+       pRingBuffer->Buffer1Length = Buffer1Length;
+       pRingBuffer->Buffer2Length = Buffer2Length;
+
+       SCListEntry = SCListMem;
+       PASCListEntry = PASCListMem;
+       Cur = pRingBuffer->Head;
+
+       for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) {
+               u64 PABuffer;
+
+               void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length,
+                                                   &tmp);
+               PABuffer = tmp;
+
+               if (Buffer == NULL)
+                       return -ENOMEM;
+
+               Cur->Buffer1 = Buffer;
+
+               SCListEntry->Address = PABuffer;
+               SCListEntry->Length  = Buffer1Length;
+
+               Cur->scList1 = SCListEntry;
+               Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry;
+               Cur->ngeneBuffer.Number_of_entries_1 =
+                       NUM_SCATTER_GATHER_ENTRIES;
+
+               SCListEntry += 1;
+               PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+#if NUM_SCATTER_GATHER_ENTRIES > 1
+               for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) {
+                       SCListEntry->Address = of;
+                       SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
+                       SCListEntry += 1;
+                       PASCListEntry +=
+                               sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+               }
+#endif
+
+               if (!Buffer2Length)
+                       continue;
+
+               Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp);
+               PABuffer = tmp;
+
+               if (Buffer == NULL)
+                       return -ENOMEM;
+
+               Cur->Buffer2 = Buffer;
+
+               SCListEntry->Address = PABuffer;
+               SCListEntry->Length  = Buffer2Length;
+
+               Cur->scList2 = SCListEntry;
+               Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry;
+               Cur->ngeneBuffer.Number_of_entries_2 =
+                       NUM_SCATTER_GATHER_ENTRIES;
+
+               SCListEntry   += 1;
+               PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+
+#if NUM_SCATTER_GATHER_ENTRIES > 1
+               for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) {
+                       SCListEntry->Address = of;
+                       SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
+                       SCListEntry += 1;
+                       PASCListEntry +=
+                               sizeof(struct HW_SCATTER_GATHER_ELEMENT);
+               }
+#endif
+
+       }
+
+       return status;
+}
+
+static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
+                           struct SRingBufferDescriptor *pRingBuffer)
+{
+       int status = 0;
+
+       /* Copy pointer to scatter gather list in TSRingbuffer
+          structure for buffer 2
+          Load number of buffer
+       */
+       u32 n = pRingBuffer->NumBuffers;
+
+       /* Point to first buffer entry */
+       struct SBufferHeader *Cur = pRingBuffer->Head;
+       int i;
+       /* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */
+       for (i = 0; i < n; i++) {
+               Cur->Buffer2 = pIdleBuffer->Head->Buffer1;
+               Cur->scList2 = pIdleBuffer->Head->scList1;
+               Cur->ngeneBuffer.Address_of_first_entry_2 =
+                       pIdleBuffer->Head->ngeneBuffer.
+                       Address_of_first_entry_1;
+               Cur->ngeneBuffer.Number_of_entries_2 =
+                       pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1;
+               Cur = Cur->Next;
+       }
+       return status;
+}
+
+static u32 RingBufferSizes[MAX_STREAM] = {
+       RING_SIZE_VIDEO,
+       RING_SIZE_VIDEO,
+       RING_SIZE_AUDIO,
+       RING_SIZE_AUDIO,
+       RING_SIZE_AUDIO,
+};
+
+static u32 Buffer1Sizes[MAX_STREAM] = {
+       MAX_VIDEO_BUFFER_SIZE,
+       MAX_VIDEO_BUFFER_SIZE,
+       MAX_AUDIO_BUFFER_SIZE,
+       MAX_AUDIO_BUFFER_SIZE,
+       MAX_AUDIO_BUFFER_SIZE
+};
+
+static u32 Buffer2Sizes[MAX_STREAM] = {
+       MAX_VBI_BUFFER_SIZE,
+       MAX_VBI_BUFFER_SIZE,
+       0,
+       0,
+       0
+};
+
+
+static int AllocCommonBuffers(struct ngene *dev)
+{
+       int status = 0, i;
+
+       dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096,
+                                                    &dev->PAFWInterfaceBuffer);
+       if (!dev->FWInterfaceBuffer)
+               return -ENOMEM;
+       dev->hosttongene = dev->FWInterfaceBuffer;
+       dev->ngenetohost = dev->FWInterfaceBuffer + 256;
+       dev->EventBuffer = dev->FWInterfaceBuffer + 512;
+
+       dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev,
+                                                  OVERFLOW_BUFFER_SIZE,
+                                                  &dev->PAOverflowBuffer);
+       if (!dev->OverflowBuffer)
+               return -ENOMEM;
+       memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE);
+
+       for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
+               int type = dev->card_info->io_type[i];
+
+               dev->channel[i].State = KSSTATE_STOP;
+
+               if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) {
+                       status = create_ring_buffer(dev->pci_dev,
+                                                   &dev->channel[i].RingBuffer,
+                                                   RingBufferSizes[i]);
+                       if (status < 0)
+                               break;
+
+                       if (type & (NGENE_IO_TV | NGENE_IO_AIN)) {
+                               status = AllocateRingBuffers(dev->pci_dev,
+                                                            dev->
+                                                            PAOverflowBuffer,
+                                                            &dev->channel[i].
+                                                            RingBuffer,
+                                                            Buffer1Sizes[i],
+                                                            Buffer2Sizes[i]);
+                               if (status < 0)
+                                       break;
+                       } else if (type & NGENE_IO_HDTV) {
+                               status = AllocateRingBuffers(dev->pci_dev,
+                                                            dev->
+                                                            PAOverflowBuffer,
+                                                            &dev->channel[i].
+                                                            RingBuffer,
+                                                          MAX_HDTV_BUFFER_SIZE,
+                                                            0);
+                               if (status < 0)
+                                       break;
+                       }
+               }
+
+               if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+
+                       status = create_ring_buffer(dev->pci_dev,
+                                                   &dev->channel[i].
+                                                   TSRingBuffer, RING_SIZE_TS);
+                       if (status < 0)
+                               break;
+
+                       status = AllocateRingBuffers(dev->pci_dev,
+                                                    dev->PAOverflowBuffer,
+                                                    &dev->channel[i].
+                                                    TSRingBuffer,
+                                                    MAX_TS_BUFFER_SIZE, 0);
+                       if (status)
+                               break;
+               }
+
+               if (type & NGENE_IO_TSOUT) {
+                       status = create_ring_buffer(dev->pci_dev,
+                                                   &dev->channel[i].
+                                                   TSIdleBuffer, 1);
+                       if (status < 0)
+                               break;
+                       status = AllocateRingBuffers(dev->pci_dev,
+                                                    dev->PAOverflowBuffer,
+                                                    &dev->channel[i].
+                                                    TSIdleBuffer,
+                                                    MAX_TS_BUFFER_SIZE, 0);
+                       if (status)
+                               break;
+                       FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer,
+                                        &dev->channel[i].TSRingBuffer);
+               }
+       }
+       return status;
+}
+
+static void ngene_release_buffers(struct ngene *dev)
+{
+       if (dev->iomem)
+               iounmap(dev->iomem);
+       free_common_buffers(dev);
+       vfree(dev->tsout_buf);
+       vfree(dev->tsin_buf);
+       vfree(dev->ain_buf);
+       vfree(dev->vin_buf);
+       vfree(dev);
+}
+
+static int ngene_get_buffers(struct ngene *dev)
+{
+       if (AllocCommonBuffers(dev))
+               return -ENOMEM;
+       if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) {
+               dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE);
+               if (!dev->tsout_buf)
+                       return -ENOMEM;
+               dvb_ringbuffer_init(&dev->tsout_rbuf,
+                                   dev->tsout_buf, TSOUT_BUF_SIZE);
+       }
+       if (dev->card_info->io_type[2]&NGENE_IO_TSIN) {
+               dev->tsin_buf = vmalloc(TSIN_BUF_SIZE);
+               if (!dev->tsin_buf)
+                       return -ENOMEM;
+               dvb_ringbuffer_init(&dev->tsin_rbuf,
+                                   dev->tsin_buf, TSIN_BUF_SIZE);
+       }
+       if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
+               dev->ain_buf = vmalloc(AIN_BUF_SIZE);
+               if (!dev->ain_buf)
+                       return -ENOMEM;
+               dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE);
+       }
+       if (dev->card_info->io_type[0] & NGENE_IO_HDTV) {
+               dev->vin_buf = vmalloc(VIN_BUF_SIZE);
+               if (!dev->vin_buf)
+                       return -ENOMEM;
+               dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE);
+       }
+       dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0),
+                            pci_resource_len(dev->pci_dev, 0));
+       if (!dev->iomem)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void ngene_init(struct ngene *dev)
+{
+       int i;
+
+       tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev);
+
+       memset_io(dev->iomem + 0xc000, 0x00, 0x220);
+       memset_io(dev->iomem + 0xc400, 0x00, 0x100);
+
+       for (i = 0; i < MAX_STREAM; i++) {
+               dev->channel[i].dev = dev;
+               dev->channel[i].number = i;
+       }
+
+       dev->fw_interface_version = 0;
+
+       ngwritel(0, NGENE_INT_ENABLE);
+
+       dev->icounts = ngreadl(NGENE_INT_COUNTS);
+
+       dev->device_version = ngreadl(DEV_VER) & 0x0f;
+       printk(KERN_INFO DEVICE_NAME ": Device version %d\n",
+              dev->device_version);
+}
+
+static int ngene_load_firm(struct ngene *dev)
+{
+       u32 size;
+       const struct firmware *fw = NULL;
+       u8 *ngene_fw;
+       char *fw_name;
+       int err, version;
+
+       version = dev->card_info->fw_version;
+
+       switch (version) {
+       default:
+       case 15:
+               version = 15;
+               size = 23466;
+               fw_name = "ngene_15.fw";
+               dev->cmd_timeout_workaround = true;
+               break;
+       case 16:
+               size = 23498;
+               fw_name = "ngene_16.fw";
+               dev->cmd_timeout_workaround = true;
+               break;
+       case 17:
+               size = 24446;
+               fw_name = "ngene_17.fw";
+               dev->cmd_timeout_workaround = true;
+               break;
+       case 18:
+               size = 0;
+               fw_name = "ngene_18.fw";
+               break;
+       }
+
+       if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
+               printk(KERN_ERR DEVICE_NAME
+                       ": Could not load firmware file %s.\n", fw_name);
+               printk(KERN_INFO DEVICE_NAME
+                       ": Copy %s to your hotplug directory!\n", fw_name);
+               return -1;
+       }
+       if (size == 0)
+               size = fw->size;
+       if (size != fw->size) {
+               printk(KERN_ERR DEVICE_NAME
+                       ": Firmware %s has invalid size!", fw_name);
+               err = -1;
+       } else {
+               printk(KERN_INFO DEVICE_NAME
+                       ": Loading firmware file %s.\n", fw_name);
+               ngene_fw = (u8 *) fw->data;
+               err = ngene_command_load_firmware(dev, ngene_fw, size);
+       }
+
+       release_firmware(fw);
+
+       return err;
+}
+
+static void ngene_stop(struct ngene *dev)
+{
+       down(&dev->cmd_mutex);
+       i2c_del_adapter(&(dev->channel[0].i2c_adapter));
+       i2c_del_adapter(&(dev->channel[1].i2c_adapter));
+       ngwritel(0, NGENE_INT_ENABLE);
+       ngwritel(0, NGENE_COMMAND);
+       ngwritel(0, NGENE_COMMAND_HI);
+       ngwritel(0, NGENE_STATUS);
+       ngwritel(0, NGENE_STATUS_HI);
+       ngwritel(0, NGENE_EVENT);
+       ngwritel(0, NGENE_EVENT_HI);
+       free_irq(dev->pci_dev->irq, dev);
+#ifdef CONFIG_PCI_MSI
+       if (dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
+#endif
+}
+
+static int ngene_buffer_config(struct ngene *dev)
+{
+       int stat;
+
+       if (dev->card_info->fw_version >= 17) {
+               u8 tsin12_config[6]   = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 };
+               u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 };
+               u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 };
+               u8 *bconf = tsin12_config;
+
+               if (dev->card_info->io_type[2]&NGENE_IO_TSIN &&
+                   dev->card_info->io_type[3]&NGENE_IO_TSIN) {
+                       bconf = tsin1234_config;
+                       if (dev->card_info->io_type[4]&NGENE_IO_TSOUT &&
+                           dev->ci.en)
+                               bconf = tsio1235_config;
+               }
+               stat = ngene_command_config_free_buf(dev, bconf);
+       } else {
+               int bconf = BUFFER_CONFIG_4422;
+
+               if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
+                       bconf = BUFFER_CONFIG_3333;
+               stat = ngene_command_config_buf(dev, bconf);
+       }
+       return stat;
+}
+
+
+static int ngene_start(struct ngene *dev)
+{
+       int stat;
+       int i;
+
+       pci_set_master(dev->pci_dev);
+       ngene_init(dev);
+
+       stat = request_irq(dev->pci_dev->irq, irq_handler,
+                          IRQF_SHARED, "nGene",
+                          (void *)dev);
+       if (stat < 0)
+               return stat;
+
+       init_waitqueue_head(&dev->cmd_wq);
+       init_waitqueue_head(&dev->tx_wq);
+       init_waitqueue_head(&dev->rx_wq);
+       sema_init(&dev->cmd_mutex, 1);
+       sema_init(&dev->stream_mutex, 1);
+       sema_init(&dev->pll_mutex, 1);
+       sema_init(&dev->i2c_switch_mutex, 1);
+       spin_lock_init(&dev->cmd_lock);
+       for (i = 0; i < MAX_STREAM; i++)
+               spin_lock_init(&dev->channel[i].state_lock);
+       ngwritel(1, TIMESTAMPS);
+
+       ngwritel(1, NGENE_INT_ENABLE);
+
+       stat = ngene_load_firm(dev);
+       if (stat < 0)
+               goto fail;
+
+#ifdef CONFIG_PCI_MSI
+       /* enable MSI if kernel and card support it */
+       if (pci_msi_enabled() && dev->card_info->msi_supported) {
+               unsigned long flags;
+
+               ngwritel(0, NGENE_INT_ENABLE);
+               free_irq(dev->pci_dev->irq, dev);
+               stat = pci_enable_msi(dev->pci_dev);
+               if (stat) {
+                       printk(KERN_INFO DEVICE_NAME
+                               ": MSI not available\n");
+                       flags = IRQF_SHARED;
+               } else {
+                       flags = 0;
+                       dev->msi_enabled = true;
+               }
+               stat = request_irq(dev->pci_dev->irq, irq_handler,
+                                       flags, "nGene", dev);
+               if (stat < 0)
+                       goto fail2;
+               ngwritel(1, NGENE_INT_ENABLE);
+       }
+#endif
+
+       stat = ngene_i2c_init(dev, 0);
+       if (stat < 0)
+               goto fail;
+
+       stat = ngene_i2c_init(dev, 1);
+       if (stat < 0)
+               goto fail;
+
+       return 0;
+
+fail:
+       ngwritel(0, NGENE_INT_ENABLE);
+       free_irq(dev->pci_dev->irq, dev);
+#ifdef CONFIG_PCI_MSI
+fail2:
+       if (dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
+#endif
+       return stat;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static void release_channel(struct ngene_channel *chan)
+{
+       struct dvb_demux *dvbdemux = &chan->demux;
+       struct ngene *dev = chan->dev;
+
+       if (chan->running)
+               set_transfer(chan, 0);
+
+       tasklet_kill(&chan->demux_tasklet);
+
+       if (chan->ci_dev) {
+               dvb_unregister_device(chan->ci_dev);
+               chan->ci_dev = NULL;
+       }
+
+       if (chan->fe2)
+               dvb_unregister_frontend(chan->fe2);
+
+       if (chan->fe) {
+               dvb_unregister_frontend(chan->fe);
+               dvb_frontend_detach(chan->fe);
+               chan->fe = NULL;
+       }
+
+       if (chan->has_demux) {
+               dvb_net_release(&chan->dvbnet);
+               dvbdemux->dmx.close(&dvbdemux->dmx);
+               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+                                             &chan->hw_frontend);
+               dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
+                                             &chan->mem_frontend);
+               dvb_dmxdev_release(&chan->dmxdev);
+               dvb_dmx_release(&chan->demux);
+               chan->has_demux = false;
+       }
+
+       if (chan->has_adapter) {
+               dvb_unregister_adapter(&dev->adapter[chan->number]);
+               chan->has_adapter = false;
+       }
+}
+
+static int init_channel(struct ngene_channel *chan)
+{
+       int ret = 0, nr = chan->number;
+       struct dvb_adapter *adapter = NULL;
+       struct dvb_demux *dvbdemux = &chan->demux;
+       struct ngene *dev = chan->dev;
+       struct ngene_info *ni = dev->card_info;
+       int io = ni->io_type[nr];
+
+       tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan);
+       chan->users = 0;
+       chan->type = io;
+       chan->mode = chan->type;        /* for now only one mode */
+
+       if (io & NGENE_IO_TSIN) {
+               chan->fe = NULL;
+               if (ni->demod_attach[nr]) {
+                       ret = ni->demod_attach[nr](chan);
+                       if (ret < 0)
+                               goto err;
+               }
+               if (chan->fe && ni->tuner_attach[nr]) {
+                       ret = ni->tuner_attach[nr](chan);
+                       if (ret < 0)
+                               goto err;
+               }
+       }
+
+       if (!dev->ci.en && (io & NGENE_IO_TSOUT))
+               return 0;
+
+       if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
+               if (nr >= STREAM_AUDIOIN1)
+                       chan->DataFormatFlags = DF_SWAP32;
+
+               if (nr == 0 || !one_adapter || dev->first_adapter == NULL) {
+                       adapter = &dev->adapter[nr];
+                       ret = dvb_register_adapter(adapter, "nGene",
+                                                  THIS_MODULE,
+                                                  &chan->dev->pci_dev->dev,
+                                                  adapter_nr);
+                       if (ret < 0)
+                               goto err;
+                       if (dev->first_adapter == NULL)
+                               dev->first_adapter = adapter;
+                       chan->has_adapter = true;
+               } else
+                       adapter = dev->first_adapter;
+       }
+
+       if (dev->ci.en && (io & NGENE_IO_TSOUT)) {
+               dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
+               set_transfer(chan, 1);
+               chan->dev->channel[2].DataFormatFlags = DF_SWAP32;
+               set_transfer(&chan->dev->channel[2], 1);
+               dvb_register_device(adapter, &chan->ci_dev,
+                                   &ngene_dvbdev_ci, (void *) chan,
+                                   DVB_DEVICE_SEC);
+               if (!chan->ci_dev)
+                       goto err;
+       }
+
+       if (chan->fe) {
+               if (dvb_register_frontend(adapter, chan->fe) < 0)
+                       goto err;
+               chan->has_demux = true;
+       }
+       if (chan->fe2) {
+               if (dvb_register_frontend(adapter, chan->fe2) < 0)
+                       goto err;
+               chan->fe2->tuner_priv = chan->fe->tuner_priv;
+               memcpy(&chan->fe2->ops.tuner_ops,
+                      &chan->fe->ops.tuner_ops,
+                      sizeof(struct dvb_tuner_ops));
+       }
+
+       if (chan->has_demux) {
+               ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
+                                             ngene_start_feed,
+                                             ngene_stop_feed, chan);
+               ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
+                                                &chan->hw_frontend,
+                                                &chan->mem_frontend, adapter);
+               ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx);
+       }
+
+       return ret;
+
+err:
+       if (chan->fe) {
+               dvb_frontend_detach(chan->fe);
+               chan->fe = NULL;
+       }
+       release_channel(chan);
+       return 0;
+}
+
+static int init_channels(struct ngene *dev)
+{
+       int i, j;
+
+       for (i = 0; i < MAX_STREAM; i++) {
+               dev->channel[i].number = i;
+               if (init_channel(&dev->channel[i]) < 0) {
+                       for (j = i - 1; j >= 0; j--)
+                               release_channel(&dev->channel[j]);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static struct cxd2099_cfg cxd_cfg = {
+       .bitrate = 62000,
+       .adr = 0x40,
+       .polarity = 0,
+       .clock_mode = 0,
+};
+
+static void cxd_attach(struct ngene *dev)
+{
+       struct ngene_ci *ci = &dev->ci;
+
+       ci->en = cxd2099_attach(&cxd_cfg, dev, &dev->channel[0].i2c_adapter);
+       ci->dev = dev;
+       return;
+}
+
+static void cxd_detach(struct ngene *dev)
+{
+       struct ngene_ci *ci = &dev->ci;
+
+       dvb_ca_en50221_release(ci->en);
+       kfree(ci->en);
+       ci->en = 0;
+}
+
+/***********************************/
+/* workaround for shutdown failure */
+/***********************************/
+
+static void ngene_unlink(struct ngene *dev)
+{
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_MEM_WRITE;
+       com.cmd.hdr.Length = 3;
+       com.cmd.MemoryWrite.address = 0x910c;
+       com.cmd.MemoryWrite.data = 0xff;
+       com.in_len = 3;
+       com.out_len = 1;
+
+       down(&dev->cmd_mutex);
+       ngwritel(0, NGENE_INT_ENABLE);
+       ngene_command_mutex(dev, &com);
+       up(&dev->cmd_mutex);
+}
+
+void ngene_shutdown(struct pci_dev *pdev)
+{
+       struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
+
+       if (!dev || !shutdown_workaround)
+               return;
+
+       printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n");
+       ngene_unlink(dev);
+       pci_disable_device(pdev);
+}
+
+/****************************************************************************/
+/* device probe/remove calls ************************************************/
+/****************************************************************************/
+
+void __devexit ngene_remove(struct pci_dev *pdev)
+{
+       struct ngene *dev = pci_get_drvdata(pdev);
+       int i;
+
+       tasklet_kill(&dev->event_tasklet);
+       for (i = MAX_STREAM - 1; i >= 0; i--)
+               release_channel(&dev->channel[i]);
+       if (dev->ci.en)
+               cxd_detach(dev);
+       ngene_stop(dev);
+       ngene_release_buffers(dev);
+       pci_set_drvdata(pdev, NULL);
+       pci_disable_device(pdev);
+}
+
+int __devinit ngene_probe(struct pci_dev *pci_dev,
+                         const struct pci_device_id *id)
+{
+       struct ngene *dev;
+       int stat = 0;
+
+       if (pci_enable_device(pci_dev) < 0)
+               return -ENODEV;
+
+       dev = vzalloc(sizeof(struct ngene));
+       if (dev == NULL) {
+               stat = -ENOMEM;
+               goto fail0;
+       }
+
+       dev->pci_dev = pci_dev;
+       dev->card_info = (struct ngene_info *)id->driver_data;
+       printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name);
+
+       pci_set_drvdata(pci_dev, dev);
+
+       /* Alloc buffers and start nGene */
+       stat = ngene_get_buffers(dev);
+       if (stat < 0)
+               goto fail1;
+       stat = ngene_start(dev);
+       if (stat < 0)
+               goto fail1;
+
+       cxd_attach(dev);
+
+       stat = ngene_buffer_config(dev);
+       if (stat < 0)
+               goto fail1;
+
+
+       dev->i2c_current_bus = -1;
+
+       /* Register DVB adapters and devices for both channels */
+       if (init_channels(dev) < 0)
+               goto fail2;
+
+       return 0;
+
+fail2:
+       ngene_stop(dev);
+fail1:
+       ngene_release_buffers(dev);
+fail0:
+       pci_disable_device(pci_dev);
+       pci_set_drvdata(pci_dev, NULL);
+       return stat;
+}
diff --git a/drivers/media/pci/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c
new file mode 100644 (file)
index 0000000..fcb16a6
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * ngene-dvb.c: nGene PCIe bridge driver - DVB functions
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Modifications for new nGene firmware,
+ *                         support for EEPROM-copying,
+ *                         support for new dual DVB-S2 card prototype
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/byteorder/generic.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include "ngene.h"
+
+
+/****************************************************************************/
+/* COMMAND API interface ****************************************************/
+/****************************************************************************/
+
+static ssize_t ts_write(struct file *file, const char *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct ngene_channel *chan = dvbdev->priv;
+       struct ngene *dev = chan->dev;
+
+       if (wait_event_interruptible(dev->tsout_rbuf.queue,
+                                    dvb_ringbuffer_free
+                                    (&dev->tsout_rbuf) >= count) < 0)
+               return 0;
+
+       dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
+
+       return count;
+}
+
+static ssize_t ts_read(struct file *file, char *buf,
+                      size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct ngene_channel *chan = dvbdev->priv;
+       struct ngene *dev = chan->dev;
+       int left, avail;
+
+       left = count;
+       while (left) {
+               if (wait_event_interruptible(
+                           dev->tsin_rbuf.queue,
+                           dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
+                       return -EAGAIN;
+               avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
+               if (avail > left)
+                       avail = left;
+               dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
+               left -= avail;
+               buf += avail;
+       }
+       return count;
+}
+
+static const struct file_operations ci_fops = {
+       .owner   = THIS_MODULE,
+       .read    = ts_read,
+       .write   = ts_write,
+       .open    = dvb_generic_open,
+       .release = dvb_generic_release,
+};
+
+struct dvb_device ngene_dvbdev_ci = {
+       .priv    = 0,
+       .readers = -1,
+       .writers = -1,
+       .users   = -1,
+       .fops    = &ci_fops,
+};
+
+
+/****************************************************************************/
+/* DVB functions and API interface ******************************************/
+/****************************************************************************/
+
+static void swap_buffer(u32 *p, u32 len)
+{
+       while (len) {
+               *p = swab32(*p);
+               p++;
+               len -= 4;
+       }
+}
+
+/* start of filler packet */
+static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER };
+
+/* #define DEBUG_CI_XFER */
+#ifdef DEBUG_CI_XFER
+static u32 ok;
+static u32 overflow;
+static u32 stripped;
+#endif
+
+void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
+{
+       struct ngene_channel *chan = priv;
+       struct ngene *dev = chan->dev;
+
+
+       if (flags & DF_SWAP32)
+               swap_buffer(buf, len);
+
+       if (dev->ci.en && chan->number == 2) {
+               while (len >= 188) {
+                       if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) {
+                               if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) {
+                                       dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188);
+                                       wake_up(&dev->tsin_rbuf.queue);
+#ifdef DEBUG_CI_XFER
+                                       ok++;
+#endif
+                               }
+#ifdef DEBUG_CI_XFER
+                               else
+                                       overflow++;
+#endif
+                       }
+#ifdef DEBUG_CI_XFER
+                       else
+                               stripped++;
+
+                       if (ok % 100 == 0 && overflow)
+                               printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped);
+#endif
+                       buf += 188;
+                       len -= 188;
+               }
+               return NULL;
+       }
+
+       if (chan->users > 0)
+               dvb_dmx_swfilter(&chan->demux, buf, len);
+
+       return NULL;
+}
+
+void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
+{
+       struct ngene_channel *chan = priv;
+       struct ngene *dev = chan->dev;
+       u32 alen;
+
+       alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
+       alen -= alen % 188;
+
+       if (alen < len)
+               FillTSBuffer(buf + alen, len - alen, flags);
+       else
+               alen = len;
+       dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
+       if (flags & DF_SWAP32)
+               swap_buffer((u32 *)buf, alen);
+       wake_up_interruptible(&dev->tsout_rbuf.queue);
+       return buf;
+}
+
+
+
+int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct ngene_channel *chan = dvbdmx->priv;
+
+       if (chan->users == 0) {
+               if (!chan->dev->cmd_timeout_workaround || !chan->running)
+                       set_transfer(chan, 1);
+       }
+
+       return ++chan->users;
+}
+
+int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct ngene_channel *chan = dvbdmx->priv;
+
+       if (--chan->users)
+               return chan->users;
+
+       if (!chan->dev->cmd_timeout_workaround)
+               set_transfer(chan, 0);
+
+       return 0;
+}
+
+int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
+                           int (*start_feed)(struct dvb_demux_feed *),
+                           int (*stop_feed)(struct dvb_demux_feed *),
+                           void *priv)
+{
+       dvbdemux->priv = priv;
+
+       dvbdemux->filternum = 256;
+       dvbdemux->feednum = 256;
+       dvbdemux->start_feed = start_feed;
+       dvbdemux->stop_feed = stop_feed;
+       dvbdemux->write_to_decoder = NULL;
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+                                     DMX_SECTION_FILTERING |
+                                     DMX_MEMORY_BASED_FILTERING);
+       return dvb_dmx_init(dvbdemux);
+}
+
+int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
+                              struct dvb_demux *dvbdemux,
+                              struct dmx_frontend *hw_frontend,
+                              struct dmx_frontend *mem_frontend,
+                              struct dvb_adapter *dvb_adapter)
+{
+       int ret;
+
+       dmxdev->filternum = 256;
+       dmxdev->demux = &dvbdemux->dmx;
+       dmxdev->capabilities = 0;
+       ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
+       if (ret < 0)
+               return ret;
+
+       hw_frontend->source = DMX_FRONTEND_0;
+       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
+       mem_frontend->source = DMX_MEMORY_FE;
+       dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
+       return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
+}
diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c
new file mode 100644 (file)
index 0000000..d28554f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * ngene-i2c.c: nGene PCIe bridge driver i2c functions
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Modifications for new nGene firmware,
+ *                         support for EEPROM-copying,
+ *                         support for new dual DVB-S2 card prototype
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* FIXME - some of these can probably be removed */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/timer.h>
+#include <linux/byteorder/generic.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+
+#include "ngene.h"
+
+/* Firmware command for i2c operations */
+static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
+                          u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
+{
+       struct ngene_command com;
+
+       com.cmd.hdr.Opcode = CMD_I2C_READ;
+       com.cmd.hdr.Length = outlen + 3;
+       com.cmd.I2CRead.Device = adr << 1;
+       memcpy(com.cmd.I2CRead.Data, out, outlen);
+       com.cmd.I2CRead.Data[outlen] = inlen;
+       com.cmd.I2CRead.Data[outlen + 1] = 0;
+       com.in_len = outlen + 3;
+       com.out_len = inlen + 1;
+
+       if (ngene_command(dev, &com) < 0)
+               return -EIO;
+
+       if ((com.cmd.raw8[0] >> 1) != adr)
+               return -EIO;
+
+       if (flag)
+               memcpy(in, com.cmd.raw8, inlen + 1);
+       else
+               memcpy(in, com.cmd.raw8 + 1, inlen);
+       return 0;
+}
+
+static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
+                                  u8 *out, u8 outlen)
+{
+       struct ngene_command com;
+
+
+       com.cmd.hdr.Opcode = CMD_I2C_WRITE;
+       com.cmd.hdr.Length = outlen + 1;
+       com.cmd.I2CRead.Device = adr << 1;
+       memcpy(com.cmd.I2CRead.Data, out, outlen);
+       com.in_len = outlen + 1;
+       com.out_len = 1;
+
+       if (ngene_command(dev, &com) < 0)
+               return -EIO;
+
+       if (com.cmd.raw8[0] == 1)
+               return -EIO;
+
+       return 0;
+}
+
+static void ngene_i2c_set_bus(struct ngene *dev, int bus)
+{
+       if (!(dev->card_info->i2c_access & 2))
+               return;
+       if (dev->i2c_current_bus == bus)
+               return;
+
+       switch (bus) {
+       case 0:
+               ngene_command_gpio_set(dev, 3, 0);
+               ngene_command_gpio_set(dev, 2, 1);
+               break;
+
+       case 1:
+               ngene_command_gpio_set(dev, 2, 0);
+               ngene_command_gpio_set(dev, 3, 1);
+               break;
+       }
+       dev->i2c_current_bus = bus;
+}
+
+static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
+                                struct i2c_msg msg[], int num)
+{
+       struct ngene_channel *chan =
+               (struct ngene_channel *)i2c_get_adapdata(adapter);
+       struct ngene *dev = chan->dev;
+
+       down(&dev->i2c_switch_mutex);
+       ngene_i2c_set_bus(dev, chan->number);
+
+       if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
+               if (!ngene_command_i2c_read(dev, msg[0].addr,
+                                           msg[0].buf, msg[0].len,
+                                           msg[1].buf, msg[1].len, 0))
+                       goto done;
+
+       if (num == 1 && !(msg[0].flags & I2C_M_RD))
+               if (!ngene_command_i2c_write(dev, msg[0].addr,
+                                            msg[0].buf, msg[0].len))
+                       goto done;
+       if (num == 1 && (msg[0].flags & I2C_M_RD))
+               if (!ngene_command_i2c_read(dev, msg[0].addr, NULL, 0,
+                                           msg[0].buf, msg[0].len, 0))
+                       goto done;
+
+       up(&dev->i2c_switch_mutex);
+       return -EIO;
+
+done:
+       up(&dev->i2c_switch_mutex);
+       return num;
+}
+
+
+static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm ngene_i2c_algo = {
+       .master_xfer = ngene_i2c_master_xfer,
+       .functionality = ngene_i2c_functionality,
+};
+
+int ngene_i2c_init(struct ngene *dev, int dev_nr)
+{
+       struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
+
+       i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
+
+       strcpy(adap->name, "nGene");
+
+       adap->algo = &ngene_i2c_algo;
+       adap->algo_data = (void *)&(dev->channel[dev_nr]);
+       adap->dev.parent = &dev->pci_dev->dev;
+
+       return i2c_add_adapter(adap);
+}
+
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
new file mode 100644 (file)
index 0000000..5443dc0
--- /dev/null
@@ -0,0 +1,921 @@
+/*
+ * ngene.h: nGene PCIe bridge driver
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _NGENE_H_
+#define _NGENE_H_
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <asm/dma.h>
+#include <linux/scatterlist.h>
+
+#include <linux/dvb/frontend.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_ca_en50221.h"
+#include "dvb_frontend.h"
+#include "dvb_ringbuffer.h"
+#include "dvb_net.h"
+#include "cxd2099.h"
+
+#define DEVICE_NAME "ngene"
+
+#define NGENE_VID       0x18c3
+#define NGENE_PID       0x0720
+
+#ifndef VIDEO_CAP_VC1
+#define VIDEO_CAP_AVC   128
+#define VIDEO_CAP_H264  128
+#define VIDEO_CAP_VC1   256
+#define VIDEO_CAP_WMV9  256
+#define VIDEO_CAP_MPEG4 512
+#endif
+
+enum STREAM {
+       STREAM_VIDEOIN1 = 0,        /* ITU656 or TS Input */
+       STREAM_VIDEOIN2,
+       STREAM_AUDIOIN1,            /* I2S or SPI Input */
+       STREAM_AUDIOIN2,
+       STREAM_AUDIOOUT,
+       MAX_STREAM
+};
+
+enum SMODE_BITS {
+       SMODE_AUDIO_SPDIF = 0x20,
+       SMODE_AVSYNC = 0x10,
+       SMODE_TRANSPORT_STREAM = 0x08,
+       SMODE_AUDIO_CAPTURE = 0x04,
+       SMODE_VBI_CAPTURE = 0x02,
+       SMODE_VIDEO_CAPTURE = 0x01
+};
+
+enum STREAM_FLAG_BITS {
+       SFLAG_CHROMA_FORMAT_2COMP  = 0x01, /* Chroma Format : 2's complement */
+       SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */
+       SFLAG_ORDER_LUMA_CHROMA    = 0x02, /* Byte order: Y,Cb,Y,Cr */
+       SFLAG_ORDER_CHROMA_LUMA    = 0x00, /* Byte order: Cb,Y,Cr,Y */
+       SFLAG_COLORBAR             = 0x04, /* Select colorbar */
+};
+
+#define PROGRAM_ROM     0x0000
+#define PROGRAM_SRAM    0x1000
+#define PERIPHERALS0    0x8000
+#define PERIPHERALS1    0x9000
+#define SHARED_BUFFER   0xC000
+
+#define HOST_TO_NGENE    (SHARED_BUFFER+0x0000)
+#define NGENE_TO_HOST    (SHARED_BUFFER+0x0100)
+#define NGENE_COMMAND    (SHARED_BUFFER+0x0200)
+#define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204)
+#define NGENE_STATUS     (SHARED_BUFFER+0x0208)
+#define NGENE_STATUS_HI  (SHARED_BUFFER+0x020C)
+#define NGENE_EVENT      (SHARED_BUFFER+0x0210)
+#define NGENE_EVENT_HI   (SHARED_BUFFER+0x0214)
+#define VARIABLES        (SHARED_BUFFER+0x0210)
+
+#define NGENE_INT_COUNTS       (SHARED_BUFFER+0x0260)
+#define NGENE_INT_ENABLE       (SHARED_BUFFER+0x0264)
+#define NGENE_VBI_LINE_COUNT   (SHARED_BUFFER+0x0268)
+
+#define BUFFER_GP_XMIT  (SHARED_BUFFER+0x0800)
+#define BUFFER_GP_RECV  (SHARED_BUFFER+0x0900)
+#define EEPROM_AREA     (SHARED_BUFFER+0x0A00)
+
+#define SG_V_IN_1       (SHARED_BUFFER+0x0A80)
+#define SG_VBI_1        (SHARED_BUFFER+0x0B00)
+#define SG_A_IN_1       (SHARED_BUFFER+0x0B80)
+#define SG_V_IN_2       (SHARED_BUFFER+0x0C00)
+#define SG_VBI_2        (SHARED_BUFFER+0x0C80)
+#define SG_A_IN_2       (SHARED_BUFFER+0x0D00)
+#define SG_V_OUT        (SHARED_BUFFER+0x0D80)
+#define SG_A_OUT2       (SHARED_BUFFER+0x0E00)
+
+#define DATA_A_IN_1     (SHARED_BUFFER+0x0E80)
+#define DATA_A_IN_2     (SHARED_BUFFER+0x0F00)
+#define DATA_A_OUT      (SHARED_BUFFER+0x0F80)
+#define DATA_V_IN_1     (SHARED_BUFFER+0x1000)
+#define DATA_V_IN_2     (SHARED_BUFFER+0x2000)
+#define DATA_V_OUT      (SHARED_BUFFER+0x3000)
+
+#define DATA_FIFO_AREA  (SHARED_BUFFER+0x1000)
+
+#define TIMESTAMPS      0xA000
+#define SCRATCHPAD      0xA080
+#define FORCE_INT       0xA088
+#define FORCE_NMI       0xA090
+#define INT_STATUS      0xA0A0
+
+#define DEV_VER         0x9004
+
+#define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF)
+
+struct SG_ADDR {
+       u64 start;
+       u64 curr;
+       u16 curr_ptr;
+       u16 elements;
+       u32 pad[3];
+} __attribute__ ((__packed__));
+
+struct SHARED_MEMORY {
+       /* C000 */
+       u32 HostToNgene[64];
+
+       /* C100 */
+       u32 NgeneToHost[64];
+
+       /* C200 */
+       u64 NgeneCommand;
+       u64 NgeneStatus;
+       u64 NgeneEvent;
+
+       /* C210 */
+       u8 pad1[0xc260 - 0xc218];
+
+       /* C260 */
+       u32 IntCounts;
+       u32 IntEnable;
+
+       /* C268 */
+       u8 pad2[0xd000 - 0xc268];
+
+} __attribute__ ((__packed__));
+
+struct BUFFER_STREAM_RESULTS {
+       u32 Clock;           /* Stream time in 100ns units */
+       u16 RemainingLines;  /* Remaining lines in this field.
+                               0 for complete field */
+       u8  FieldCount;      /* Video field number */
+       u8  Flags;           /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow,
+                               Bit 0 = FieldID */
+       u16 BlockCount;      /* Audio block count (unused) */
+       u8  Reserved[2];
+       u32 DTOUpdate;
+} __attribute__ ((__packed__));
+
+struct HW_SCATTER_GATHER_ELEMENT {
+       u64 Address;
+       u32 Length;
+       u32 Reserved;
+} __attribute__ ((__packed__));
+
+struct BUFFER_HEADER {
+       u64    Next;
+       struct BUFFER_STREAM_RESULTS SR;
+
+       u32    Number_of_entries_1;
+       u32    Reserved5;
+       u64    Address_of_first_entry_1;
+
+       u32    Number_of_entries_2;
+       u32    Reserved7;
+       u64    Address_of_first_entry_2;
+} __attribute__ ((__packed__));
+
+struct EVENT_BUFFER {
+       u32    TimeStamp;
+       u8     GPIOStatus;
+       u8     UARTStatus;
+       u8     RXCharacter;
+       u8     EventStatus;
+       u32    Reserved[2];
+} __attribute__ ((__packed__));
+
+/* Firmware commands. */
+
+enum OPCODES {
+       CMD_NOP = 0,
+       CMD_FWLOAD_PREPARE  = 0x01,
+       CMD_FWLOAD_FINISH   = 0x02,
+       CMD_I2C_READ        = 0x03,
+       CMD_I2C_WRITE       = 0x04,
+
+       CMD_I2C_WRITE_NOSTOP = 0x05,
+       CMD_I2C_CONTINUE_WRITE = 0x06,
+       CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07,
+
+       CMD_DEBUG_OUTPUT    = 0x09,
+
+       CMD_CONTROL         = 0x10,
+       CMD_CONFIGURE_BUFFER = 0x11,
+       CMD_CONFIGURE_FREE_BUFFER = 0x12,
+
+       CMD_SPI_READ        = 0x13,
+       CMD_SPI_WRITE       = 0x14,
+
+       CMD_MEM_READ        = 0x20,
+       CMD_MEM_WRITE       = 0x21,
+       CMD_SFR_READ        = 0x22,
+       CMD_SFR_WRITE       = 0x23,
+       CMD_IRAM_READ       = 0x24,
+       CMD_IRAM_WRITE      = 0x25,
+       CMD_SET_GPIO_PIN    = 0x26,
+       CMD_SET_GPIO_INT    = 0x27,
+       CMD_CONFIGURE_UART  = 0x28,
+       CMD_WRITE_UART      = 0x29,
+       MAX_CMD
+};
+
+enum RESPONSES {
+       OK = 0,
+       ERROR = 1
+};
+
+struct FW_HEADER {
+       u8 Opcode;
+       u8 Length;
+} __attribute__ ((__packed__));
+
+struct FW_I2C_WRITE {
+       struct FW_HEADER hdr;
+       u8 Device;
+       u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_I2C_CONTINUE_WRITE {
+       struct FW_HEADER hdr;
+       u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_I2C_READ {
+       struct FW_HEADER hdr;
+       u8 Device;
+       u8 Data[252];    /* followed by two bytes of read data count */
+} __attribute__ ((__packed__));
+
+struct FW_SPI_WRITE {
+       struct FW_HEADER hdr;
+       u8 ModeSelect;
+       u8 Data[250];
+} __attribute__ ((__packed__));
+
+struct FW_SPI_READ {
+       struct FW_HEADER hdr;
+       u8 ModeSelect;
+       u8 Data[252];    /* followed by two bytes of read data count */
+} __attribute__ ((__packed__));
+
+struct FW_FWLOAD_PREPARE {
+       struct FW_HEADER hdr;
+} __attribute__ ((__packed__));
+
+struct FW_FWLOAD_FINISH {
+       struct FW_HEADER hdr;
+       u16 Address;     /* address of final block */
+       u16 Length;
+} __attribute__ ((__packed__));
+
+/*
+ * Meaning of FW_STREAM_CONTROL::Mode bits:
+ *  Bit 7: Loopback PEXin to PEXout using TVOut channel
+ *  Bit 6: AVLOOP
+ *  Bit 5: Audio select; 0=I2S, 1=SPDIF
+ *  Bit 4: AVSYNC
+ *  Bit 3: Enable transport stream
+ *  Bit 2: Enable audio capture
+ *  Bit 1: Enable ITU-Video VBI capture
+ *  Bit 0: Enable ITU-Video capture
+ *
+ * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL)
+ *  Bit 7: continuous capture
+ *  Bit 6: capture one field
+ *  Bit 5: capture one frame
+ *  Bit 4: unused
+ *  Bit 3: starting field; 0=odd, 1=even
+ *  Bit 2: sample size; 0=8-bit, 1=10-bit
+ *  Bit 1: data format; 0=UYVY, 1=YUY2
+ *  Bit 0: resets buffer pointers
+*/
+
+enum FSC_MODE_BITS {
+       SMODE_LOOPBACK          = 0x80,
+       SMODE_AVLOOP            = 0x40,
+       _SMODE_AUDIO_SPDIF      = 0x20,
+       _SMODE_AVSYNC           = 0x10,
+       _SMODE_TRANSPORT_STREAM = 0x08,
+       _SMODE_AUDIO_CAPTURE    = 0x04,
+       _SMODE_VBI_CAPTURE      = 0x02,
+       _SMODE_VIDEO_CAPTURE    = 0x01
+};
+
+
+/* Meaning of FW_STREAM_CONTROL::Stream bits:
+ * Bit 3: Audio sample count:  0 = relative, 1 = absolute
+ * Bit 2: color bar select; 1=color bars, 0=CV3 decoder
+ * Bits 1-0: stream select, UVI1, UVI2, TVOUT
+ */
+
+struct FW_STREAM_CONTROL {
+       struct FW_HEADER hdr;
+       u8     Stream;             /* Stream number (UVI1, UVI2, TVOUT) */
+       u8     Control;            /* Value written to UVI1_CTL */
+       u8     Mode;               /* Controls clock source */
+       u8     SetupDataLen;       /* Length of setup data, MSB=1 write
+                                     backwards */
+       u16    CaptureBlockCount;  /* Blocks (a 256 Bytes) to capture per buffer
+                                     for TS and Audio */
+       u64    Buffer_Address;     /* Address of first buffer header */
+       u16    BytesPerVideoLine;
+       u16    MaxLinesPerField;
+       u16    MinLinesPerField;
+       u16    Reserved_1;
+       u16    BytesPerVBILine;
+       u16    MaxVBILinesPerField;
+       u16    MinVBILinesPerField;
+       u16    SetupDataAddr;      /* ngene relative address of setup data */
+       u8     SetupData[32];      /* setup data */
+} __attribute__((__packed__));
+
+#define AUDIO_BLOCK_SIZE    256
+#define TS_BLOCK_SIZE       256
+
+struct FW_MEM_READ {
+       struct FW_HEADER hdr;
+       u16   address;
+} __attribute__ ((__packed__));
+
+struct FW_MEM_WRITE {
+       struct FW_HEADER hdr;
+       u16   address;
+       u8    data;
+} __attribute__ ((__packed__));
+
+struct FW_SFR_IRAM_READ {
+       struct FW_HEADER hdr;
+       u8    address;
+} __attribute__ ((__packed__));
+
+struct FW_SFR_IRAM_WRITE {
+       struct FW_HEADER hdr;
+       u8    address;
+       u8    data;
+} __attribute__ ((__packed__));
+
+struct FW_SET_GPIO_PIN {
+       struct FW_HEADER hdr;
+       u8    select;
+} __attribute__ ((__packed__));
+
+struct FW_SET_GPIO_INT {
+       struct FW_HEADER hdr;
+       u8    select;
+} __attribute__ ((__packed__));
+
+struct FW_SET_DEBUGMODE {
+       struct FW_HEADER hdr;
+       u8   debug_flags;
+} __attribute__ ((__packed__));
+
+struct FW_CONFIGURE_BUFFERS {
+       struct FW_HEADER hdr;
+       u8   config;
+} __attribute__ ((__packed__));
+
+enum _BUFFER_CONFIGS {
+       /* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2  (standard usage) */
+       BUFFER_CONFIG_4422 = 0,
+       /* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2  (4x TS input usage) */
+       BUFFER_CONFIG_3333 = 1,
+       /* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut  (HDTV decoder usage) */
+       BUFFER_CONFIG_8022 = 2,
+       BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */
+};
+
+struct FW_CONFIGURE_FREE_BUFFERS {
+       struct FW_HEADER hdr;
+       u8   UVI1_BufferLength;
+       u8   UVI2_BufferLength;
+       u8   TVO_BufferLength;
+       u8   AUD1_BufferLength;
+       u8   AUD2_BufferLength;
+       u8   TVA_BufferLength;
+} __attribute__ ((__packed__));
+
+struct FW_CONFIGURE_UART {
+       struct FW_HEADER hdr;
+       u8 UartControl;
+} __attribute__ ((__packed__));
+
+enum _UART_CONFIG {
+       _UART_BAUDRATE_19200 = 0,
+       _UART_BAUDRATE_9600  = 1,
+       _UART_BAUDRATE_4800  = 2,
+       _UART_BAUDRATE_2400  = 3,
+       _UART_RX_ENABLE      = 0x40,
+       _UART_TX_ENABLE      = 0x80,
+};
+
+struct FW_WRITE_UART {
+       struct FW_HEADER hdr;
+       u8 Data[252];
+} __attribute__ ((__packed__));
+
+
+struct ngene_command {
+       u32 in_len;
+       u32 out_len;
+       union {
+               u32                              raw[64];
+               u8                               raw8[256];
+               struct FW_HEADER                 hdr;
+               struct FW_I2C_WRITE              I2CWrite;
+               struct FW_I2C_CONTINUE_WRITE     I2CContinueWrite;
+               struct FW_I2C_READ               I2CRead;
+               struct FW_STREAM_CONTROL         StreamControl;
+               struct FW_FWLOAD_PREPARE         FWLoadPrepare;
+               struct FW_FWLOAD_FINISH          FWLoadFinish;
+               struct FW_MEM_READ               MemoryRead;
+               struct FW_MEM_WRITE              MemoryWrite;
+               struct FW_SFR_IRAM_READ          SfrIramRead;
+               struct FW_SFR_IRAM_WRITE         SfrIramWrite;
+               struct FW_SPI_WRITE              SPIWrite;
+               struct FW_SPI_READ               SPIRead;
+               struct FW_SET_GPIO_PIN           SetGpioPin;
+               struct FW_SET_GPIO_INT           SetGpioInt;
+               struct FW_SET_DEBUGMODE          SetDebugMode;
+               struct FW_CONFIGURE_BUFFERS      ConfigureBuffers;
+               struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers;
+               struct FW_CONFIGURE_UART         ConfigureUart;
+               struct FW_WRITE_UART             WriteUart;
+       } cmd;
+} __attribute__ ((__packed__));
+
+#define NGENE_INTERFACE_VERSION 0x103
+#define MAX_VIDEO_BUFFER_SIZE   (417792) /* 288*1440 rounded up to next page */
+#define MAX_AUDIO_BUFFER_SIZE     (8192) /* Gives room for about 23msec@48KHz */
+#define MAX_VBI_BUFFER_SIZE      (28672) /* 1144*18 rounded up to next page */
+#define MAX_TS_BUFFER_SIZE       (98304) /* 512*188 rounded up to next page */
+#define MAX_HDTV_BUFFER_SIZE   (2080768) /* 541*1920*2 rounded up to next page
+                                           Max: (1920x1080i60) */
+
+#define OVERFLOW_BUFFER_SIZE    (8192)
+
+#define RING_SIZE_VIDEO     4
+#define RING_SIZE_AUDIO     8
+#define RING_SIZE_TS        8
+
+#define NUM_SCATTER_GATHER_ENTRIES  8
+
+#define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \
+                       RING_SIZE_VIDEO * 2) + \
+                       (MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \
+                       (MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \
+                       (RING_SIZE_VIDEO * PAGE_SIZE * 2) + \
+                       (RING_SIZE_AUDIO * PAGE_SIZE * 2) + \
+                       (RING_SIZE_TS    * PAGE_SIZE * 4) + \
+                        8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE)
+
+#define EVENT_QUEUE_SIZE    16
+
+/* Gathers the current state of a single channel. */
+
+struct SBufferHeader {
+       struct BUFFER_HEADER   ngeneBuffer; /* Physical descriptor */
+       struct SBufferHeader  *Next;
+       void                  *Buffer1;
+       struct HW_SCATTER_GATHER_ELEMENT *scList1;
+       void                  *Buffer2;
+       struct HW_SCATTER_GATHER_ELEMENT *scList2;
+};
+
+/* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */
+#define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63)
+
+enum HWSTATE {
+       HWSTATE_STOP,
+       HWSTATE_STARTUP,
+       HWSTATE_RUN,
+       HWSTATE_PAUSE,
+};
+
+enum KSSTATE {
+       KSSTATE_STOP,
+       KSSTATE_ACQUIRE,
+       KSSTATE_PAUSE,
+       KSSTATE_RUN,
+};
+
+struct SRingBufferDescriptor {
+       struct SBufferHeader *Head; /* Points to first buffer in ring buffer
+                                      structure*/
+       u64   PAHead;         /* Physical address of first buffer */
+       u32   MemSize;        /* Memory size of allocated ring buffers
+                                (needed for freeing) */
+       u32   NumBuffers;     /* Number of buffers in the ring */
+       u32   Buffer1Length;  /* Allocated length of Buffer 1 */
+       u32   Buffer2Length;  /* Allocated length of Buffer 2 */
+       void *SCListMem;      /* Memory to hold scatter gather lists for this
+                                ring */
+       u64   PASCListMem;    /* Physical address  .. */
+       u32   SCListMemSize;  /* Size of this memory */
+};
+
+enum STREAMMODEFLAGS {
+       StreamMode_NONE   = 0, /* Stream not used */
+       StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */
+       StreamMode_TSIN   = 2, /* Transport stream input (all) */
+       StreamMode_HDTV   = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60
+                                 (only stream 0) */
+       StreamMode_TSOUT  = 8, /* Transport stream output (only stream 3) */
+};
+
+
+enum BufferExchangeFlags {
+       BEF_EVEN_FIELD   = 0x00000001,
+       BEF_CONTINUATION = 0x00000002,
+       BEF_MORE_DATA    = 0x00000004,
+       BEF_OVERFLOW     = 0x00000008,
+       DF_SWAP32        = 0x00010000,
+};
+
+typedef void *(IBufferExchange)(void *, void *, u32, u32, u32);
+
+struct MICI_STREAMINFO {
+       IBufferExchange    *pExchange;
+       IBufferExchange    *pExchangeVBI;     /* Secondary (VBI, ancillary) */
+       u8  Stream;
+       u8  Flags;
+       u8  Mode;
+       u8  Reserved;
+       u16 nLinesVideo;
+       u16 nBytesPerLineVideo;
+       u16 nLinesVBI;
+       u16 nBytesPerLineVBI;
+       u32 CaptureLength;    /* Used for audio and transport stream */
+};
+
+/****************************************************************************/
+/* STRUCTS ******************************************************************/
+/****************************************************************************/
+
+/* sound hardware definition */
+#define MIXER_ADDR_TVTUNER      0
+#define MIXER_ADDR_LAST         0
+
+struct ngene_channel;
+
+/*struct sound chip*/
+
+struct mychip {
+       struct ngene_channel *chan;
+       struct snd_card *card;
+       struct pci_dev *pci;
+       struct snd_pcm_substream *substream;
+       struct snd_pcm *pcm;
+       unsigned long port;
+       int irq;
+       spinlock_t mixer_lock;
+       spinlock_t lock;
+       int mixer_volume[MIXER_ADDR_LAST + 1][2];
+       int capture_source[MIXER_ADDR_LAST + 1][2];
+};
+
+#ifdef NGENE_V4L
+struct ngene_overlay {
+       int                    tvnorm;
+       struct v4l2_rect       w;
+       enum v4l2_field        field;
+       struct v4l2_clip       *clips;
+       int                    nclips;
+       int                    setup_ok;
+};
+
+struct ngene_tvnorm {
+       int   v4l2_id;
+       char  *name;
+       u16   swidth, sheight; /* scaled standard width, height */
+       int   tuner_norm;
+       int   soundstd;
+};
+
+struct ngene_vopen {
+       struct ngene_channel      *ch;
+       enum v4l2_priority         prio;
+       int                        width;
+       int                        height;
+       int                        depth;
+       struct videobuf_queue      vbuf_q;
+       struct videobuf_queue      vbi;
+       int                        fourcc;
+       int                        picxcount;
+       int                        resources;
+       enum v4l2_buf_type         type;
+       const struct ngene_format *fmt;
+
+       const struct ngene_format *ovfmt;
+       struct ngene_overlay       ov;
+};
+#endif
+
+struct ngene_channel {
+       struct device         device;
+       struct i2c_adapter    i2c_adapter;
+
+       struct ngene         *dev;
+       int                   number;
+       int                   type;
+       int                   mode;
+       bool                  has_adapter;
+       bool                  has_demux;
+       int                   demod_type;
+       int (*gate_ctrl)(struct dvb_frontend *, int);
+
+       struct dvb_frontend  *fe;
+       struct dvb_frontend  *fe2;
+       struct dmxdev         dmxdev;
+       struct dvb_demux      demux;
+       struct dvb_net        dvbnet;
+       struct dmx_frontend   hw_frontend;
+       struct dmx_frontend   mem_frontend;
+       int                   users;
+       struct video_device  *v4l_dev;
+       struct dvb_device    *ci_dev;
+       struct tasklet_struct demux_tasklet;
+
+       struct SBufferHeader *nextBuffer;
+       enum KSSTATE          State;
+       enum HWSTATE          HWState;
+       u8                    Stream;
+       u8                    Flags;
+       u8                    Mode;
+       IBufferExchange      *pBufferExchange;
+       IBufferExchange      *pBufferExchange2;
+
+       spinlock_t            state_lock;
+       u16                   nLines;
+       u16                   nBytesPerLine;
+       u16                   nVBILines;
+       u16                   nBytesPerVBILine;
+       u16                   itumode;
+       u32                   Capture1Length;
+       u32                   Capture2Length;
+       struct SRingBufferDescriptor RingBuffer;
+       struct SRingBufferDescriptor TSRingBuffer;
+       struct SRingBufferDescriptor TSIdleBuffer;
+
+       u32                   DataFormatFlags;
+
+       int                   AudioDTOUpdated;
+       u32                   AudioDTOValue;
+
+       int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t);
+       u8 lnbh;
+
+       /* stuff from analog driver */
+
+       int minor;
+       struct mychip        *mychip;
+       struct snd_card      *soundcard;
+       u8                   *evenbuffer;
+       u8                    dma_on;
+       int                   soundstreamon;
+       int                   audiomute;
+       int                   soundbuffisallocated;
+       int                   sndbuffflag;
+       int                   tun_rdy;
+       int                   dec_rdy;
+       int                   tun_dec_rdy;
+       int                   lastbufferflag;
+
+       struct ngene_tvnorm  *tvnorms;
+       int                   tvnorm_num;
+       int                   tvnorm;
+
+#ifdef NGENE_V4L
+       int                   videousers;
+       struct v4l2_prio_state prio;
+       struct ngene_vopen    init;
+       int                   resources;
+       struct v4l2_framebuffer fbuf;
+       struct ngene_buffer  *screen;     /* overlay             */
+       struct list_head      capture;    /* video capture queue */
+       spinlock_t s_lock;
+       struct semaphore reslock;
+#endif
+
+       int running;
+};
+
+
+struct ngene_ci {
+       struct device         device;
+       struct i2c_adapter    i2c_adapter;
+
+       struct ngene         *dev;
+       struct dvb_ca_en50221 *en;
+};
+
+struct ngene;
+
+typedef void (rx_cb_t)(struct ngene *, u32, u8);
+typedef void (tx_cb_t)(struct ngene *, u32);
+
+struct ngene {
+       int                   nr;
+       struct pci_dev       *pci_dev;
+       unsigned char        *iomem;
+
+       /*struct i2c_adapter  i2c_adapter;*/
+
+       u32                   device_version;
+       u32                   fw_interface_version;
+       u32                   icounts;
+       bool                  msi_enabled;
+       bool                  cmd_timeout_workaround;
+
+       u8                   *CmdDoneByte;
+       int                   BootFirmware;
+       void                 *OverflowBuffer;
+       dma_addr_t            PAOverflowBuffer;
+       void                 *FWInterfaceBuffer;
+       dma_addr_t            PAFWInterfaceBuffer;
+       u8                   *ngenetohost;
+       u8                   *hosttongene;
+
+       struct EVENT_BUFFER   EventQueue[EVENT_QUEUE_SIZE];
+       int                   EventQueueOverflowCount;
+       int                   EventQueueOverflowFlag;
+       struct tasklet_struct event_tasklet;
+       struct EVENT_BUFFER  *EventBuffer;
+       int                   EventQueueWriteIndex;
+       int                   EventQueueReadIndex;
+
+       wait_queue_head_t     cmd_wq;
+       int                   cmd_done;
+       struct semaphore      cmd_mutex;
+       struct semaphore      stream_mutex;
+       struct semaphore      pll_mutex;
+       struct semaphore      i2c_switch_mutex;
+       int                   i2c_current_channel;
+       int                   i2c_current_bus;
+       spinlock_t            cmd_lock;
+
+       struct dvb_adapter    adapter[MAX_STREAM];
+       struct dvb_adapter    *first_adapter; /* "one_adapter" modprobe opt */
+       struct ngene_channel  channel[MAX_STREAM];
+
+       struct ngene_info    *card_info;
+
+       tx_cb_t              *TxEventNotify;
+       rx_cb_t              *RxEventNotify;
+       int                   tx_busy;
+       wait_queue_head_t     tx_wq;
+       wait_queue_head_t     rx_wq;
+#define UART_RBUF_LEN 4096
+       u8                    uart_rbuf[UART_RBUF_LEN];
+       int                   uart_rp, uart_wp;
+
+#define TS_FILLER  0x6f
+
+       u8                   *tsout_buf;
+#define TSOUT_BUF_SIZE (512*188*8)
+       struct dvb_ringbuffer tsout_rbuf;
+
+       u8                   *tsin_buf;
+#define TSIN_BUF_SIZE (512*188*8)
+       struct dvb_ringbuffer tsin_rbuf;
+
+       u8                   *ain_buf;
+#define AIN_BUF_SIZE (128*1024)
+       struct dvb_ringbuffer ain_rbuf;
+
+
+       u8                   *vin_buf;
+#define VIN_BUF_SIZE (4*1920*1080)
+       struct dvb_ringbuffer vin_rbuf;
+
+       unsigned long         exp_val;
+       int prev_cmd;
+
+       struct ngene_ci       ci;
+};
+
+struct ngene_info {
+       int   type;
+#define NGENE_APP        0
+#define NGENE_TERRATEC   1
+#define NGENE_SIDEWINDER 2
+#define NGENE_RACER      3
+#define NGENE_VIPER      4
+#define NGENE_PYTHON     5
+#define NGENE_VBOX_V1   6
+#define NGENE_VBOX_V2   7
+
+       int   fw_version;
+       bool  msi_supported;
+       char *name;
+
+       int   io_type[MAX_STREAM];
+#define NGENE_IO_NONE    0
+#define NGENE_IO_TV      1
+#define NGENE_IO_HDTV    2
+#define NGENE_IO_TSIN    4
+#define NGENE_IO_TSOUT   8
+#define NGENE_IO_AIN     16
+
+       void *fe_config[4];
+       void *tuner_config[4];
+
+       int (*demod_attach[4])(struct ngene_channel *);
+       int (*tuner_attach[4])(struct ngene_channel *);
+
+       u8    avf[4];
+       u8    msp[4];
+       u8    demoda[4];
+       u8    lnb[4];
+       int   i2c_access;
+       u8    ntsc;
+       u8    tsf[4];
+       u8    i2s[4];
+
+       int (*gate_ctrl)(struct dvb_frontend *, int);
+       int (*switch_ctrl)(struct ngene_channel *, int, int);
+};
+
+#ifdef NGENE_V4L
+struct ngene_format {
+       char *name;
+       int   fourcc;          /* video4linux 2      */
+       int   btformat;        /* BT848_COLOR_FMT_*  */
+       int   format;
+       int   btswap;          /* BT848_COLOR_CTL_*  */
+       int   depth;           /* bit/pixel          */
+       int   flags;
+       int   hshift, vshift;  /* for planar modes   */
+       int   palette;
+};
+
+#define RESOURCE_OVERLAY       1
+#define RESOURCE_VIDEO         2
+#define RESOURCE_VBI           4
+
+struct ngene_buffer {
+       /* common v4l buffer stuff -- must be first */
+       struct videobuf_buffer     vb;
+
+       /* ngene specific */
+       const struct ngene_format *fmt;
+       int                        tvnorm;
+       int                        btformat;
+       int                        btswap;
+};
+#endif
+
+
+/* Provided by ngene-core.c */
+int __devinit ngene_probe(struct pci_dev *pci_dev,
+                         const struct pci_device_id *id);
+void __devexit ngene_remove(struct pci_dev *pdev);
+void ngene_shutdown(struct pci_dev *pdev);
+int ngene_command(struct ngene *dev, struct ngene_command *com);
+int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level);
+void set_transfer(struct ngene_channel *chan, int state);
+void FillTSBuffer(void *Buffer, int Length, u32 Flags);
+
+/* Provided by ngene-i2c.c */
+int ngene_i2c_init(struct ngene *dev, int dev_nr);
+
+/* Provided by ngene-dvb.c */
+extern struct dvb_device ngene_dvbdev_ci;
+void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
+void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
+int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed);
+int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
+int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
+                           int (*start_feed)(struct dvb_demux_feed *),
+                           int (*stop_feed)(struct dvb_demux_feed *),
+                           void *priv);
+int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
+                              struct dvb_demux *dvbdemux,
+                              struct dmx_frontend *hw_frontend,
+                              struct dmx_frontend *mem_frontend,
+                              struct dvb_adapter *dvb_adapter);
+
+#endif
+
+/*  LocalWords:  Endif
+ */
diff --git a/drivers/media/pci/pluto2/Kconfig b/drivers/media/pci/pluto2/Kconfig
new file mode 100644 (file)
index 0000000..7d8e6e8
--- /dev/null
@@ -0,0 +1,15 @@
+config DVB_PLUTO2
+       tristate "Pluto2 cards"
+       depends on DVB_CORE && PCI && I2C
+       select I2C_ALGOBIT
+       select DVB_TDA1004X
+       help
+         Support for PCI cards based on the Pluto2 FPGA like the Satelco
+         Easywatch Mobile Terrestrial DVB-T Receiver.
+
+         Since these cards have no MPEG decoder onboard, they transmit
+         only compressed MPEG data over the PCI bus, so you need
+         an external software decoder to watch TV on your computer.
+
+         Say Y or M if you own such a device and want to use it.
+
diff --git a/drivers/media/pci/pluto2/Makefile b/drivers/media/pci/pluto2/Makefile
new file mode 100644 (file)
index 0000000..524bf84
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
new file mode 100644 (file)
index 0000000..f148b19
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+ * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
+ *
+ * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
+ *
+ * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
+ *     by Dany Salman <salmandany@yahoo.fr>
+ *     Copyright (c) 2004 TDF
+ *
+ * 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/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "demux.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include "dvbdev.h"
+#include "tda1004x.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define DRIVER_NAME            "pluto2"
+
+#define REG_PIDn(n)            ((n) << 2)      /* PID n pattern registers */
+#define REG_PCAR               0x0020          /* PC address register */
+#define REG_TSCR               0x0024          /* TS ctrl & status */
+#define REG_MISC               0x0028          /* miscellaneous */
+#define REG_MMAC               0x002c          /* MSB MAC address */
+#define REG_IMAC               0x0030          /* ISB MAC address */
+#define REG_LMAC               0x0034          /* LSB MAC address */
+#define REG_SPID               0x0038          /* SPI data */
+#define REG_SLCS               0x003c          /* serial links ctrl/status */
+
+#define PID0_NOFIL             (0x0001 << 16)
+#define PIDn_ENP               (0x0001 << 15)
+#define PID0_END               (0x0001 << 14)
+#define PID0_AFIL              (0x0001 << 13)
+#define PIDn_PID               (0x1fff <<  0)
+
+#define TSCR_NBPACKETS         (0x00ff << 24)
+#define TSCR_DEM               (0x0001 << 17)
+#define TSCR_DE                        (0x0001 << 16)
+#define TSCR_RSTN              (0x0001 << 15)
+#define TSCR_MSKO              (0x0001 << 14)
+#define TSCR_MSKA              (0x0001 << 13)
+#define TSCR_MSKL              (0x0001 << 12)
+#define TSCR_OVR               (0x0001 << 11)
+#define TSCR_AFUL              (0x0001 << 10)
+#define TSCR_LOCK              (0x0001 <<  9)
+#define TSCR_IACK              (0x0001 <<  8)
+#define TSCR_ADEF              (0x007f <<  0)
+
+#define MISC_DVR               (0x0fff <<  4)
+#define MISC_ALED              (0x0001 <<  3)
+#define MISC_FRST              (0x0001 <<  2)
+#define MISC_LED1              (0x0001 <<  1)
+#define MISC_LED0              (0x0001 <<  0)
+
+#define SPID_SPIDR             (0x00ff <<  0)
+
+#define SLCS_SCL               (0x0001 <<  7)
+#define SLCS_SDA               (0x0001 <<  6)
+#define SLCS_CSN               (0x0001 <<  2)
+#define SLCS_OVR               (0x0001 <<  1)
+#define SLCS_SWC               (0x0001 <<  0)
+
+#define TS_DMA_PACKETS         (8)
+#define TS_DMA_BYTES           (188 * TS_DMA_PACKETS)
+
+#define I2C_ADDR_TDA10046      0x10
+#define I2C_ADDR_TUA6034       0xc2
+#define NHWFILTERS             8
+
+struct pluto {
+       /* pci */
+       struct pci_dev *pdev;
+       u8 __iomem *io_mem;
+
+       /* dvb */
+       struct dmx_frontend hw_frontend;
+       struct dmx_frontend mem_frontend;
+       struct dmxdev dmxdev;
+       struct dvb_adapter dvb_adapter;
+       struct dvb_demux demux;
+       struct dvb_frontend *fe;
+       struct dvb_net dvbnet;
+       unsigned int full_ts_users;
+       unsigned int users;
+
+       /* i2c */
+       struct i2c_algo_bit_data i2c_bit;
+       struct i2c_adapter i2c_adap;
+       unsigned int i2cbug;
+
+       /* irq */
+       unsigned int overflow;
+       unsigned int dead;
+
+       /* dma */
+       dma_addr_t dma_addr;
+       u8 dma_buf[TS_DMA_BYTES];
+       u8 dummy[4096];
+};
+
+static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
+{
+       return container_of(feed->demux, struct pluto, demux);
+}
+
+static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
+{
+       return container_of(fe->dvb, struct pluto, dvb_adapter);
+}
+
+static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
+{
+       return readl(&pluto->io_mem[reg]);
+}
+
+static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
+{
+       writel(val, &pluto->io_mem[reg]);
+}
+
+static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
+{
+       u32 val = readl(&pluto->io_mem[reg]);
+       val &= ~mask;
+       val |= bits;
+       writel(val, &pluto->io_mem[reg]);
+}
+
+static void pluto_write_tscr(struct pluto *pluto, u32 val)
+{
+       /* set the number of packets */
+       val &= ~TSCR_ADEF;
+       val |= TS_DMA_PACKETS / 2;
+
+       pluto_writereg(pluto, REG_TSCR, val);
+}
+
+static void pluto_setsda(void *data, int state)
+{
+       struct pluto *pluto = data;
+
+       if (state)
+               pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
+       else
+               pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
+}
+
+static void pluto_setscl(void *data, int state)
+{
+       struct pluto *pluto = data;
+
+       if (state)
+               pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
+       else
+               pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
+
+       /* try to detect i2c_inb() to workaround hardware bug:
+        * reset SDA to high after SCL has been set to low */
+       if ((state) && (pluto->i2cbug == 0)) {
+               pluto->i2cbug = 1;
+       } else {
+               if ((!state) && (pluto->i2cbug == 1))
+                       pluto_setsda(pluto, 1);
+               pluto->i2cbug = 0;
+       }
+}
+
+static int pluto_getsda(void *data)
+{
+       struct pluto *pluto = data;
+
+       return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
+}
+
+static int pluto_getscl(void *data)
+{
+       struct pluto *pluto = data;
+
+       return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
+}
+
+static void pluto_reset_frontend(struct pluto *pluto, int reenable)
+{
+       u32 val = pluto_readreg(pluto, REG_MISC);
+
+       if (val & MISC_FRST) {
+               val &= ~MISC_FRST;
+               pluto_writereg(pluto, REG_MISC, val);
+       }
+       if (reenable) {
+               val |= MISC_FRST;
+               pluto_writereg(pluto, REG_MISC, val);
+       }
+}
+
+static void pluto_reset_ts(struct pluto *pluto, int reenable)
+{
+       u32 val = pluto_readreg(pluto, REG_TSCR);
+
+       if (val & TSCR_RSTN) {
+               val &= ~TSCR_RSTN;
+               pluto_write_tscr(pluto, val);
+       }
+       if (reenable) {
+               val |= TSCR_RSTN;
+               pluto_write_tscr(pluto, val);
+       }
+}
+
+static void pluto_set_dma_addr(struct pluto *pluto)
+{
+       pluto_writereg(pluto, REG_PCAR, pluto->dma_addr);
+}
+
+static int __devinit pluto_dma_map(struct pluto *pluto)
+{
+       pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
+                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+       return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr);
+}
+
+static void pluto_dma_unmap(struct pluto *pluto)
+{
+       pci_unmap_single(pluto->pdev, pluto->dma_addr,
+                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static int pluto_start_feed(struct dvb_demux_feed *f)
+{
+       struct pluto *pluto = feed_to_pluto(f);
+
+       /* enable PID filtering */
+       if (pluto->users++ == 0)
+               pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
+
+       if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+               pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
+       else if (pluto->full_ts_users++ == 0)
+               pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
+
+       return 0;
+}
+
+static int pluto_stop_feed(struct dvb_demux_feed *f)
+{
+       struct pluto *pluto = feed_to_pluto(f);
+
+       /* disable PID filtering */
+       if (--pluto->users == 0)
+               pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
+
+       if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+               pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
+       else if (--pluto->full_ts_users == 0)
+               pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
+
+       return 0;
+}
+
+static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
+{
+       /* synchronize the DMA transfer with the CPU
+        * first so that we see updated contents. */
+       pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
+                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+       /* Workaround for broken hardware:
+        * [1] On startup NBPACKETS seems to contain an uninitialized value,
+        *     but no packets have been transferred.
+        * [2] Sometimes (actually very often) NBPACKETS stays at zero
+        *     although one packet has been transferred.
+        * [3] Sometimes (actually rarely), the card gets into an erroneous
+        *     mode where it continuously generates interrupts, claiming it
+        *     has received nbpackets>TS_DMA_PACKETS packets, but no packet
+        *     has been transferred. Only a reset seems to solve this
+        */
+       if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
+               unsigned int i = 0;
+               while (pluto->dma_buf[i] == 0x47)
+                       i += 188;
+               nbpackets = i / 188;
+               if (i == 0) {
+                       pluto_reset_ts(pluto, 1);
+                       dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+               }
+       }
+
+       dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
+
+       /* clear the dma buffer. this is needed to be able to identify
+        * new valid ts packets above */
+       memset(pluto->dma_buf, 0, nbpackets * 188);
+
+       /* reset the dma address */
+       pluto_set_dma_addr(pluto);
+
+       /* sync the buffer and give it back to the card */
+       pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
+                       TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static irqreturn_t pluto_irq(int irq, void *dev_id)
+{
+       struct pluto *pluto = dev_id;
+       u32 tscr;
+
+       /* check whether an interrupt occurred on this device */
+       tscr = pluto_readreg(pluto, REG_TSCR);
+       if (!(tscr & (TSCR_DE | TSCR_OVR)))
+               return IRQ_NONE;
+
+       if (tscr == 0xffffffff) {
+               if (pluto->dead == 0)
+                       dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+               /* It's dead Jim */
+               pluto->dead = 1;
+               return IRQ_HANDLED;
+       }
+
+       /* dma end interrupt */
+       if (tscr & TSCR_DE) {
+               pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
+               /* overflow interrupt */
+               if (tscr & TSCR_OVR)
+                       pluto->overflow++;
+               if (pluto->overflow) {
+                       dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
+                                       pluto->overflow);
+                       pluto_reset_ts(pluto, 1);
+                       pluto->overflow = 0;
+               }
+       } else if (tscr & TSCR_OVR) {
+               pluto->overflow++;
+       }
+
+       /* ACK the interrupt */
+       pluto_write_tscr(pluto, tscr | TSCR_IACK);
+
+       return IRQ_HANDLED;
+}
+
+static void __devinit pluto_enable_irqs(struct pluto *pluto)
+{
+       u32 val = pluto_readreg(pluto, REG_TSCR);
+
+       /* disable AFUL and LOCK interrupts */
+       val |= (TSCR_MSKA | TSCR_MSKL);
+       /* enable DMA and OVERFLOW interrupts */
+       val &= ~(TSCR_DEM | TSCR_MSKO);
+       /* clear pending interrupts */
+       val |= TSCR_IACK;
+
+       pluto_write_tscr(pluto, val);
+}
+
+static void pluto_disable_irqs(struct pluto *pluto)
+{
+       u32 val = pluto_readreg(pluto, REG_TSCR);
+
+       /* disable all interrupts */
+       val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
+       /* clear pending interrupts */
+       val |= TSCR_IACK;
+
+       pluto_write_tscr(pluto, val);
+}
+
+static int __devinit pluto_hw_init(struct pluto *pluto)
+{
+       pluto_reset_frontend(pluto, 1);
+
+       /* set automatic LED control by FPGA */
+       pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
+
+       /* set data endianess */
+#ifdef __LITTLE_ENDIAN
+       pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
+#else
+       pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
+#endif
+       /* map DMA and set address */
+       pluto_dma_map(pluto);
+       pluto_set_dma_addr(pluto);
+
+       /* enable interrupts */
+       pluto_enable_irqs(pluto);
+
+       /* reset TS logic */
+       pluto_reset_ts(pluto, 1);
+
+       return 0;
+}
+
+static void pluto_hw_exit(struct pluto *pluto)
+{
+       /* disable interrupts */
+       pluto_disable_irqs(pluto);
+
+       pluto_reset_ts(pluto, 0);
+
+       /* LED: disable automatic control, enable yellow, disable green */
+       pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
+
+       /* unmap DMA */
+       pluto_dma_unmap(pluto);
+
+       pluto_reset_frontend(pluto, 0);
+}
+
+static inline u32 divide(u32 numerator, u32 denominator)
+{
+       if (denominator == 0)
+               return ~0;
+
+       return DIV_ROUND_CLOSEST(numerator, denominator);
+}
+
+/* LG Innotek TDTE-E001P (Infineon TUA6034) */
+static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct pluto *pluto = frontend_to_pluto(fe);
+       struct i2c_msg msg;
+       int ret;
+       u8 buf[4];
+       u32 div;
+
+       // Fref = 166.667 Hz
+       // Fref * 3 = 500.000 Hz
+       // IF = 36166667
+       // IF / Fref = 217
+       //div = divide(p->frequency + 36166667, 166667);
+       div = divide(p->frequency * 3, 500000) + 217;
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = (div >> 0) & 0xff;
+
+       if (p->frequency < 611000000)
+               buf[2] = 0xb4;
+       else if (p->frequency < 811000000)
+               buf[2] = 0xbc;
+       else
+               buf[2] = 0xf4;
+
+       // VHF: 174-230 MHz
+       // center: 350 MHz
+       // UHF: 470-862 MHz
+       if (p->frequency < 350000000)
+               buf[3] = 0x02;
+       else
+               buf[3] = 0x04;
+
+       if (p->bandwidth_hz == 8000000)
+               buf[3] |= 0x08;
+
+       msg.addr = I2C_ADDR_TUA6034 >> 1;
+       msg.flags = 0;
+       msg.buf = buf;
+       msg.len = sizeof(buf);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
+       if (ret < 0)
+               return ret;
+       else if (ret == 0)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int pluto2_request_firmware(struct dvb_frontend *fe,
+                                  const struct firmware **fw, char *name)
+{
+       struct pluto *pluto = frontend_to_pluto(fe);
+
+       return request_firmware(fw, name, &pluto->pdev->dev);
+}
+
+static struct tda1004x_config pluto2_fe_config __devinitdata = {
+       .demod_address = I2C_ADDR_TDA10046 >> 1,
+       .invert = 1,
+       .invert_oclk = 0,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .agc_config = TDA10046_AGC_DEFAULT,
+       .if_freq = TDA10046_FREQ_3617,
+       .request_firmware = pluto2_request_firmware,
+};
+
+static int __devinit frontend_init(struct pluto *pluto)
+{
+       int ret;
+
+       pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
+       if (!pluto->fe) {
+               dev_err(&pluto->pdev->dev, "could not attach frontend\n");
+               return -ENODEV;
+       }
+       pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params;
+
+       ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
+       if (ret < 0) {
+               if (pluto->fe->ops.release)
+                       pluto->fe->ops.release(pluto->fe);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void __devinit pluto_read_rev(struct pluto *pluto)
+{
+       u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
+       dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
+                       (val >> 12) & 0x0f, (val >> 4) & 0xff);
+}
+
+static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
+{
+       u32 val = pluto_readreg(pluto, REG_MMAC);
+       mac[0] = (val >> 8) & 0xff;
+       mac[1] = (val >> 0) & 0xff;
+
+       val = pluto_readreg(pluto, REG_IMAC);
+       mac[2] = (val >> 8) & 0xff;
+       mac[3] = (val >> 0) & 0xff;
+
+       val = pluto_readreg(pluto, REG_LMAC);
+       mac[4] = (val >> 8) & 0xff;
+       mac[5] = (val >> 0) & 0xff;
+
+       dev_info(&pluto->pdev->dev, "MAC %pM\n", mac);
+}
+
+static int __devinit pluto_read_serial(struct pluto *pluto)
+{
+       struct pci_dev *pdev = pluto->pdev;
+       unsigned int i, j;
+       u8 __iomem *cis;
+
+       cis = pci_iomap(pdev, 1, 0);
+       if (!cis)
+               return -EIO;
+
+       dev_info(&pdev->dev, "S/N ");
+
+       for (i = 0xe0; i < 0x100; i += 4) {
+               u32 val = readl(&cis[i]);
+               for (j = 0; j < 32; j += 8) {
+                       if ((val & 0xff) == 0xff)
+                               goto out;
+                       printk("%c", val & 0xff);
+                       val >>= 8;
+               }
+       }
+out:
+       printk("\n");
+       pci_iounmap(pdev, cis);
+
+       return 0;
+}
+
+static int __devinit pluto2_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+       struct pluto *pluto;
+       struct dvb_adapter *dvb_adapter;
+       struct dvb_demux *dvbdemux;
+       struct dmx_demux *dmx;
+       int ret = -ENOMEM;
+
+       pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL);
+       if (!pluto)
+               goto out;
+
+       pluto->pdev = pdev;
+
+       ret = pci_enable_device(pdev);
+       if (ret < 0)
+               goto err_kfree;
+
+       /* enable interrupts */
+       pci_write_config_dword(pdev, 0x6c, 0x8000);
+
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       pci_set_master(pdev);
+
+       ret = pci_request_regions(pdev, DRIVER_NAME);
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       pluto->io_mem = pci_iomap(pdev, 0, 0x40);
+       if (!pluto->io_mem) {
+               ret = -EIO;
+               goto err_pci_release_regions;
+       }
+
+       pci_set_drvdata(pdev, pluto);
+
+       ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto);
+       if (ret < 0)
+               goto err_pci_iounmap;
+
+       ret = pluto_hw_init(pluto);
+       if (ret < 0)
+               goto err_free_irq;
+
+       /* i2c */
+       i2c_set_adapdata(&pluto->i2c_adap, pluto);
+       strcpy(pluto->i2c_adap.name, DRIVER_NAME);
+       pluto->i2c_adap.owner = THIS_MODULE;
+       pluto->i2c_adap.dev.parent = &pdev->dev;
+       pluto->i2c_adap.algo_data = &pluto->i2c_bit;
+       pluto->i2c_bit.data = pluto;
+       pluto->i2c_bit.setsda = pluto_setsda;
+       pluto->i2c_bit.setscl = pluto_setscl;
+       pluto->i2c_bit.getsda = pluto_getsda;
+       pluto->i2c_bit.getscl = pluto_getscl;
+       pluto->i2c_bit.udelay = 10;
+       pluto->i2c_bit.timeout = 10;
+
+       /* Raise SCL and SDA */
+       pluto_setsda(pluto, 1);
+       pluto_setscl(pluto, 1);
+
+       ret = i2c_bit_add_bus(&pluto->i2c_adap);
+       if (ret < 0)
+               goto err_pluto_hw_exit;
+
+       /* dvb */
+       ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME,
+                                  THIS_MODULE, &pdev->dev, adapter_nr);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       dvb_adapter = &pluto->dvb_adapter;
+
+       pluto_read_rev(pluto);
+       pluto_read_serial(pluto);
+       pluto_read_mac(pluto, dvb_adapter->proposed_mac);
+
+       dvbdemux = &pluto->demux;
+       dvbdemux->filternum = 256;
+       dvbdemux->feednum = 256;
+       dvbdemux->start_feed = pluto_start_feed;
+       dvbdemux->stop_feed = pluto_stop_feed;
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+                       DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+       ret = dvb_dmx_init(dvbdemux);
+       if (ret < 0)
+               goto err_dvb_unregister_adapter;
+
+       dmx = &dvbdemux->dmx;
+
+       pluto->hw_frontend.source = DMX_FRONTEND_0;
+       pluto->mem_frontend.source = DMX_MEMORY_FE;
+       pluto->dmxdev.filternum = NHWFILTERS;
+       pluto->dmxdev.demux = dmx;
+
+       ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
+       if (ret < 0)
+               goto err_dvb_dmx_release;
+
+       ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
+       if (ret < 0)
+               goto err_dvb_dmxdev_release;
+
+       ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
+       if (ret < 0)
+               goto err_remove_hw_frontend;
+
+       ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
+       if (ret < 0)
+               goto err_remove_mem_frontend;
+
+       ret = frontend_init(pluto);
+       if (ret < 0)
+               goto err_disconnect_frontend;
+
+       dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
+out:
+       return ret;
+
+err_disconnect_frontend:
+       dmx->disconnect_frontend(dmx);
+err_remove_mem_frontend:
+       dmx->remove_frontend(dmx, &pluto->mem_frontend);
+err_remove_hw_frontend:
+       dmx->remove_frontend(dmx, &pluto->hw_frontend);
+err_dvb_dmxdev_release:
+       dvb_dmxdev_release(&pluto->dmxdev);
+err_dvb_dmx_release:
+       dvb_dmx_release(dvbdemux);
+err_dvb_unregister_adapter:
+       dvb_unregister_adapter(dvb_adapter);
+err_i2c_del_adapter:
+       i2c_del_adapter(&pluto->i2c_adap);
+err_pluto_hw_exit:
+       pluto_hw_exit(pluto);
+err_free_irq:
+       free_irq(pdev->irq, pluto);
+err_pci_iounmap:
+       pci_iounmap(pdev, pluto->io_mem);
+err_pci_release_regions:
+       pci_release_regions(pdev);
+err_pci_disable_device:
+       pci_disable_device(pdev);
+err_kfree:
+       pci_set_drvdata(pdev, NULL);
+       kfree(pluto);
+       goto out;
+}
+
+static void __devexit pluto2_remove(struct pci_dev *pdev)
+{
+       struct pluto *pluto = pci_get_drvdata(pdev);
+       struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
+       struct dvb_demux *dvbdemux = &pluto->demux;
+       struct dmx_demux *dmx = &dvbdemux->dmx;
+
+       dmx->close(dmx);
+       dvb_net_release(&pluto->dvbnet);
+       if (pluto->fe)
+               dvb_unregister_frontend(pluto->fe);
+
+       dmx->disconnect_frontend(dmx);
+       dmx->remove_frontend(dmx, &pluto->mem_frontend);
+       dmx->remove_frontend(dmx, &pluto->hw_frontend);
+       dvb_dmxdev_release(&pluto->dmxdev);
+       dvb_dmx_release(dvbdemux);
+       dvb_unregister_adapter(dvb_adapter);
+       i2c_del_adapter(&pluto->i2c_adap);
+       pluto_hw_exit(pluto);
+       free_irq(pdev->irq, pluto);
+       pci_iounmap(pdev, pluto->io_mem);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+       kfree(pluto);
+}
+
+#ifndef PCI_VENDOR_ID_SCM
+#define PCI_VENDOR_ID_SCM      0x0432
+#endif
+#ifndef PCI_DEVICE_ID_PLUTO2
+#define PCI_DEVICE_ID_PLUTO2   0x0001
+#endif
+
+static struct pci_device_id pluto2_id_table[] __devinitdata = {
+       {
+               .vendor = PCI_VENDOR_ID_SCM,
+               .device = PCI_DEVICE_ID_PLUTO2,
+               .subvendor = PCI_ANY_ID,
+               .subdevice = PCI_ANY_ID,
+       }, {
+               /* empty */
+       },
+};
+
+MODULE_DEVICE_TABLE(pci, pluto2_id_table);
+
+static struct pci_driver pluto2_driver = {
+       .name = DRIVER_NAME,
+       .id_table = pluto2_id_table,
+       .probe = pluto2_probe,
+       .remove = __devexit_p(pluto2_remove),
+};
+
+static int __init pluto2_init(void)
+{
+       return pci_register_driver(&pluto2_driver);
+}
+
+static void __exit pluto2_exit(void)
+{
+       pci_unregister_driver(&pluto2_driver);
+}
+
+module_init(pluto2_init);
+module_exit(pluto2_exit);
+
+MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_DESCRIPTION("Pluto2 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/pt1/Kconfig b/drivers/media/pci/pt1/Kconfig
new file mode 100644 (file)
index 0000000..24501d5
--- /dev/null
@@ -0,0 +1,12 @@
+config DVB_PT1
+       tristate "PT1 cards"
+       depends on DVB_CORE && PCI && I2C
+       help
+         Support for Earthsoft PT1 PCI cards.
+
+         Since these cards have no MPEG decoder onboard, they transmit
+         only compressed MPEG data over the PCI bus, so you need
+         an external software decoder to watch TV on your computer.
+
+         Say Y or M if you own such a device and want to use it.
+
diff --git a/drivers/media/pci/pt1/Makefile b/drivers/media/pci/pt1/Makefile
new file mode 100644 (file)
index 0000000..98e3912
--- /dev/null
@@ -0,0 +1,5 @@
+earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
+
+obj-$(CONFIG_DVB_PT1) += earth-pt1.o
+
+ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
new file mode 100644 (file)
index 0000000..15b35c4
--- /dev/null
@@ -0,0 +1,1246 @@
+/*
+ * driver for Earthsoft PT1/PT2
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/pci.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/ratelimit.h>
+
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_net.h"
+#include "dvb_frontend.h"
+
+#include "va1j5jf8007t.h"
+#include "va1j5jf8007s.h"
+
+#define DRIVER_NAME "earth-pt1"
+
+#define PT1_PAGE_SHIFT 12
+#define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT)
+#define PT1_NR_UPACKETS 1024
+#define PT1_NR_BUFS 511
+
+struct pt1_buffer_page {
+       __le32 upackets[PT1_NR_UPACKETS];
+};
+
+struct pt1_table_page {
+       __le32 next_pfn;
+       __le32 buf_pfns[PT1_NR_BUFS];
+};
+
+struct pt1_buffer {
+       struct pt1_buffer_page *page;
+       dma_addr_t addr;
+};
+
+struct pt1_table {
+       struct pt1_table_page *page;
+       dma_addr_t addr;
+       struct pt1_buffer bufs[PT1_NR_BUFS];
+};
+
+#define PT1_NR_ADAPS 4
+
+struct pt1_adapter;
+
+struct pt1 {
+       struct pci_dev *pdev;
+       void __iomem *regs;
+       struct i2c_adapter i2c_adap;
+       int i2c_running;
+       struct pt1_adapter *adaps[PT1_NR_ADAPS];
+       struct pt1_table *tables;
+       struct task_struct *kthread;
+       int table_index;
+       int buf_index;
+
+       struct mutex lock;
+       int power;
+       int reset;
+};
+
+struct pt1_adapter {
+       struct pt1 *pt1;
+       int index;
+
+       u8 *buf;
+       int upacket_count;
+       int packet_count;
+       int st_count;
+
+       struct dvb_adapter adap;
+       struct dvb_demux demux;
+       int users;
+       struct dmxdev dmxdev;
+       struct dvb_frontend *fe;
+       int (*orig_set_voltage)(struct dvb_frontend *fe,
+                               fe_sec_voltage_t voltage);
+       int (*orig_sleep)(struct dvb_frontend *fe);
+       int (*orig_init)(struct dvb_frontend *fe);
+
+       fe_sec_voltage_t voltage;
+       int sleep;
+};
+
+#define pt1_printk(level, pt1, format, arg...) \
+       dev_printk(level, &(pt1)->pdev->dev, format, ##arg)
+
+static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
+{
+       writel(data, pt1->regs + reg * 4);
+}
+
+static u32 pt1_read_reg(struct pt1 *pt1, int reg)
+{
+       return readl(pt1->regs + reg * 4);
+}
+
+static int pt1_nr_tables = 8;
+module_param_named(nr_tables, pt1_nr_tables, int, 0);
+
+static void pt1_increment_table_count(struct pt1 *pt1)
+{
+       pt1_write_reg(pt1, 0, 0x00000020);
+}
+
+static void pt1_init_table_count(struct pt1 *pt1)
+{
+       pt1_write_reg(pt1, 0, 0x00000010);
+}
+
+static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn)
+{
+       pt1_write_reg(pt1, 5, first_pfn);
+       pt1_write_reg(pt1, 0, 0x0c000040);
+}
+
+static void pt1_unregister_tables(struct pt1 *pt1)
+{
+       pt1_write_reg(pt1, 0, 0x08080000);
+}
+
+static int pt1_sync(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < 57; i++) {
+               if (pt1_read_reg(pt1, 0) & 0x20000000)
+                       return 0;
+               pt1_write_reg(pt1, 0, 0x00000008);
+       }
+       pt1_printk(KERN_ERR, pt1, "could not sync\n");
+       return -EIO;
+}
+
+static u64 pt1_identify(struct pt1 *pt1)
+{
+       int i;
+       u64 id;
+       id = 0;
+       for (i = 0; i < 57; i++) {
+               id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i;
+               pt1_write_reg(pt1, 0, 0x00000008);
+       }
+       return id;
+}
+
+static int pt1_unlock(struct pt1 *pt1)
+{
+       int i;
+       pt1_write_reg(pt1, 0, 0x00000008);
+       for (i = 0; i < 3; i++) {
+               if (pt1_read_reg(pt1, 0) & 0x80000000)
+                       return 0;
+               schedule_timeout_uninterruptible((HZ + 999) / 1000);
+       }
+       pt1_printk(KERN_ERR, pt1, "could not unlock\n");
+       return -EIO;
+}
+
+static int pt1_reset_pci(struct pt1 *pt1)
+{
+       int i;
+       pt1_write_reg(pt1, 0, 0x01010000);
+       pt1_write_reg(pt1, 0, 0x01000000);
+       for (i = 0; i < 10; i++) {
+               if (pt1_read_reg(pt1, 0) & 0x00000001)
+                       return 0;
+               schedule_timeout_uninterruptible((HZ + 999) / 1000);
+       }
+       pt1_printk(KERN_ERR, pt1, "could not reset PCI\n");
+       return -EIO;
+}
+
+static int pt1_reset_ram(struct pt1 *pt1)
+{
+       int i;
+       pt1_write_reg(pt1, 0, 0x02020000);
+       pt1_write_reg(pt1, 0, 0x02000000);
+       for (i = 0; i < 10; i++) {
+               if (pt1_read_reg(pt1, 0) & 0x00000002)
+                       return 0;
+               schedule_timeout_uninterruptible((HZ + 999) / 1000);
+       }
+       pt1_printk(KERN_ERR, pt1, "could not reset RAM\n");
+       return -EIO;
+}
+
+static int pt1_do_enable_ram(struct pt1 *pt1)
+{
+       int i, j;
+       u32 status;
+       status = pt1_read_reg(pt1, 0) & 0x00000004;
+       pt1_write_reg(pt1, 0, 0x00000002);
+       for (i = 0; i < 10; i++) {
+               for (j = 0; j < 1024; j++) {
+                       if ((pt1_read_reg(pt1, 0) & 0x00000004) != status)
+                               return 0;
+               }
+               schedule_timeout_uninterruptible((HZ + 999) / 1000);
+       }
+       pt1_printk(KERN_ERR, pt1, "could not enable RAM\n");
+       return -EIO;
+}
+
+static int pt1_enable_ram(struct pt1 *pt1)
+{
+       int i, ret;
+       int phase;
+       schedule_timeout_uninterruptible((HZ + 999) / 1000);
+       phase = pt1->pdev->device == 0x211a ? 128 : 166;
+       for (i = 0; i < phase; i++) {
+               ret = pt1_do_enable_ram(pt1);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
+
+static void pt1_disable_ram(struct pt1 *pt1)
+{
+       pt1_write_reg(pt1, 0, 0x0b0b0000);
+}
+
+static void pt1_set_stream(struct pt1 *pt1, int index, int enabled)
+{
+       pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index);
+}
+
+static void pt1_init_streams(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < PT1_NR_ADAPS; i++)
+               pt1_set_stream(pt1, i, 0);
+}
+
+static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
+{
+       u32 upacket;
+       int i;
+       int index;
+       struct pt1_adapter *adap;
+       int offset;
+       u8 *buf;
+       int sc;
+
+       if (!page->upackets[PT1_NR_UPACKETS - 1])
+               return 0;
+
+       for (i = 0; i < PT1_NR_UPACKETS; i++) {
+               upacket = le32_to_cpu(page->upackets[i]);
+               index = (upacket >> 29) - 1;
+               if (index < 0 || index >=  PT1_NR_ADAPS)
+                       continue;
+
+               adap = pt1->adaps[index];
+               if (upacket >> 25 & 1)
+                       adap->upacket_count = 0;
+               else if (!adap->upacket_count)
+                       continue;
+
+               if (upacket >> 24 & 1)
+                       printk_ratelimited(KERN_INFO "earth-pt1: device "
+                               "buffer overflowing. table[%d] buf[%d]\n",
+                               pt1->table_index, pt1->buf_index);
+               sc = upacket >> 26 & 0x7;
+               if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7))
+                       printk_ratelimited(KERN_INFO "earth-pt1: data loss"
+                               " in streamID(adapter)[%d]\n", index);
+               adap->st_count = sc;
+
+               buf = adap->buf;
+               offset = adap->packet_count * 188 + adap->upacket_count * 3;
+               buf[offset] = upacket >> 16;
+               buf[offset + 1] = upacket >> 8;
+               if (adap->upacket_count != 62)
+                       buf[offset + 2] = upacket;
+
+               if (++adap->upacket_count >= 63) {
+                       adap->upacket_count = 0;
+                       if (++adap->packet_count >= 21) {
+                               dvb_dmx_swfilter_packets(&adap->demux, buf, 21);
+                               adap->packet_count = 0;
+                       }
+               }
+       }
+
+       page->upackets[PT1_NR_UPACKETS - 1] = 0;
+       return 1;
+}
+
+static int pt1_thread(void *data)
+{
+       struct pt1 *pt1;
+       struct pt1_buffer_page *page;
+
+       pt1 = data;
+       set_freezable();
+
+       while (!kthread_should_stop()) {
+               try_to_freeze();
+
+               page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
+               if (!pt1_filter(pt1, page)) {
+                       schedule_timeout_interruptible((HZ + 999) / 1000);
+                       continue;
+               }
+
+               if (++pt1->buf_index >= PT1_NR_BUFS) {
+                       pt1_increment_table_count(pt1);
+                       pt1->buf_index = 0;
+                       if (++pt1->table_index >= pt1_nr_tables)
+                               pt1->table_index = 0;
+               }
+       }
+
+       return 0;
+}
+
+static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr)
+{
+       dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr);
+}
+
+static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp)
+{
+       void *page;
+       dma_addr_t addr;
+
+       page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr,
+                                 GFP_KERNEL);
+       if (page == NULL)
+               return NULL;
+
+       BUG_ON(addr & (PT1_PAGE_SIZE - 1));
+       BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1);
+
+       *addrp = addr;
+       *pfnp = addr >> PT1_PAGE_SHIFT;
+       return page;
+}
+
+static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf)
+{
+       pt1_free_page(pt1, buf->page, buf->addr);
+}
+
+static int
+pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf,  u32 *pfnp)
+{
+       struct pt1_buffer_page *page;
+       dma_addr_t addr;
+
+       page = pt1_alloc_page(pt1, &addr, pfnp);
+       if (page == NULL)
+               return -ENOMEM;
+
+       page->upackets[PT1_NR_UPACKETS - 1] = 0;
+
+       buf->page = page;
+       buf->addr = addr;
+       return 0;
+}
+
+static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table)
+{
+       int i;
+
+       for (i = 0; i < PT1_NR_BUFS; i++)
+               pt1_cleanup_buffer(pt1, &table->bufs[i]);
+
+       pt1_free_page(pt1, table->page, table->addr);
+}
+
+static int
+pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp)
+{
+       struct pt1_table_page *page;
+       dma_addr_t addr;
+       int i, ret;
+       u32 buf_pfn;
+
+       page = pt1_alloc_page(pt1, &addr, pfnp);
+       if (page == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < PT1_NR_BUFS; i++) {
+               ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn);
+               if (ret < 0)
+                       goto err;
+
+               page->buf_pfns[i] = cpu_to_le32(buf_pfn);
+       }
+
+       pt1_increment_table_count(pt1);
+       table->page = page;
+       table->addr = addr;
+       return 0;
+
+err:
+       while (i--)
+               pt1_cleanup_buffer(pt1, &table->bufs[i]);
+
+       pt1_free_page(pt1, page, addr);
+       return ret;
+}
+
+static void pt1_cleanup_tables(struct pt1 *pt1)
+{
+       struct pt1_table *tables;
+       int i;
+
+       tables = pt1->tables;
+       pt1_unregister_tables(pt1);
+
+       for (i = 0; i < pt1_nr_tables; i++)
+               pt1_cleanup_table(pt1, &tables[i]);
+
+       vfree(tables);
+}
+
+static int pt1_init_tables(struct pt1 *pt1)
+{
+       struct pt1_table *tables;
+       int i, ret;
+       u32 first_pfn, pfn;
+
+       tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
+       if (tables == NULL)
+               return -ENOMEM;
+
+       pt1_init_table_count(pt1);
+
+       i = 0;
+       if (pt1_nr_tables) {
+               ret = pt1_init_table(pt1, &tables[0], &first_pfn);
+               if (ret)
+                       goto err;
+               i++;
+       }
+
+       while (i < pt1_nr_tables) {
+               ret = pt1_init_table(pt1, &tables[i], &pfn);
+               if (ret)
+                       goto err;
+               tables[i - 1].page->next_pfn = cpu_to_le32(pfn);
+               i++;
+       }
+
+       tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn);
+
+       pt1_register_tables(pt1, first_pfn);
+       pt1->tables = tables;
+       return 0;
+
+err:
+       while (i--)
+               pt1_cleanup_table(pt1, &tables[i]);
+
+       vfree(tables);
+       return ret;
+}
+
+static int pt1_start_polling(struct pt1 *pt1)
+{
+       int ret = 0;
+
+       mutex_lock(&pt1->lock);
+       if (!pt1->kthread) {
+               pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1");
+               if (IS_ERR(pt1->kthread)) {
+                       ret = PTR_ERR(pt1->kthread);
+                       pt1->kthread = NULL;
+               }
+       }
+       mutex_unlock(&pt1->lock);
+       return ret;
+}
+
+static int pt1_start_feed(struct dvb_demux_feed *feed)
+{
+       struct pt1_adapter *adap;
+       adap = container_of(feed->demux, struct pt1_adapter, demux);
+       if (!adap->users++) {
+               int ret;
+
+               ret = pt1_start_polling(adap->pt1);
+               if (ret)
+                       return ret;
+               pt1_set_stream(adap->pt1, adap->index, 1);
+       }
+       return 0;
+}
+
+static void pt1_stop_polling(struct pt1 *pt1)
+{
+       int i, count;
+
+       mutex_lock(&pt1->lock);
+       for (i = 0, count = 0; i < PT1_NR_ADAPS; i++)
+               count += pt1->adaps[i]->users;
+
+       if (count == 0 && pt1->kthread) {
+               kthread_stop(pt1->kthread);
+               pt1->kthread = NULL;
+       }
+       mutex_unlock(&pt1->lock);
+}
+
+static int pt1_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct pt1_adapter *adap;
+       adap = container_of(feed->demux, struct pt1_adapter, demux);
+       if (!--adap->users) {
+               pt1_set_stream(adap->pt1, adap->index, 0);
+               pt1_stop_polling(adap->pt1);
+       }
+       return 0;
+}
+
+static void
+pt1_update_power(struct pt1 *pt1)
+{
+       int bits;
+       int i;
+       struct pt1_adapter *adap;
+       static const int sleep_bits[] = {
+               1 << 4,
+               1 << 6 | 1 << 7,
+               1 << 5,
+               1 << 6 | 1 << 8,
+       };
+
+       bits = pt1->power | !pt1->reset << 3;
+       mutex_lock(&pt1->lock);
+       for (i = 0; i < PT1_NR_ADAPS; i++) {
+               adap = pt1->adaps[i];
+               switch (adap->voltage) {
+               case SEC_VOLTAGE_13: /* actually 11V */
+                       bits |= 1 << 1;
+                       break;
+               case SEC_VOLTAGE_18: /* actually 15V */
+                       bits |= 1 << 1 | 1 << 2;
+                       break;
+               default:
+                       break;
+               }
+
+               /* XXX: The bits should be changed depending on adap->sleep. */
+               bits |= sleep_bits[i];
+       }
+       pt1_write_reg(pt1, 1, bits);
+       mutex_unlock(&pt1->lock);
+}
+
+static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct pt1_adapter *adap;
+
+       adap = container_of(fe->dvb, struct pt1_adapter, adap);
+       adap->voltage = voltage;
+       pt1_update_power(adap->pt1);
+
+       if (adap->orig_set_voltage)
+               return adap->orig_set_voltage(fe, voltage);
+       else
+               return 0;
+}
+
+static int pt1_sleep(struct dvb_frontend *fe)
+{
+       struct pt1_adapter *adap;
+
+       adap = container_of(fe->dvb, struct pt1_adapter, adap);
+       adap->sleep = 1;
+       pt1_update_power(adap->pt1);
+
+       if (adap->orig_sleep)
+               return adap->orig_sleep(fe);
+       else
+               return 0;
+}
+
+static int pt1_wakeup(struct dvb_frontend *fe)
+{
+       struct pt1_adapter *adap;
+
+       adap = container_of(fe->dvb, struct pt1_adapter, adap);
+       adap->sleep = 0;
+       pt1_update_power(adap->pt1);
+       schedule_timeout_uninterruptible((HZ + 999) / 1000);
+
+       if (adap->orig_init)
+               return adap->orig_init(fe);
+       else
+               return 0;
+}
+
+static void pt1_free_adapter(struct pt1_adapter *adap)
+{
+       adap->demux.dmx.close(&adap->demux.dmx);
+       dvb_dmxdev_release(&adap->dmxdev);
+       dvb_dmx_release(&adap->demux);
+       dvb_unregister_adapter(&adap->adap);
+       free_page((unsigned long)adap->buf);
+       kfree(adap);
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct pt1_adapter *
+pt1_alloc_adapter(struct pt1 *pt1)
+{
+       struct pt1_adapter *adap;
+       void *buf;
+       struct dvb_adapter *dvb_adap;
+       struct dvb_demux *demux;
+       struct dmxdev *dmxdev;
+       int ret;
+
+       adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL);
+       if (!adap) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       adap->pt1 = pt1;
+
+       adap->voltage = SEC_VOLTAGE_OFF;
+       adap->sleep = 1;
+
+       buf = (u8 *)__get_free_page(GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto err_kfree;
+       }
+
+       adap->buf = buf;
+       adap->upacket_count = 0;
+       adap->packet_count = 0;
+       adap->st_count = -1;
+
+       dvb_adap = &adap->adap;
+       dvb_adap->priv = adap;
+       ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE,
+                                  &pt1->pdev->dev, adapter_nr);
+       if (ret < 0)
+               goto err_free_page;
+
+       demux = &adap->demux;
+       demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       demux->priv = adap;
+       demux->feednum = 256;
+       demux->filternum = 256;
+       demux->start_feed = pt1_start_feed;
+       demux->stop_feed = pt1_stop_feed;
+       demux->write_to_decoder = NULL;
+       ret = dvb_dmx_init(demux);
+       if (ret < 0)
+               goto err_unregister_adapter;
+
+       dmxdev = &adap->dmxdev;
+       dmxdev->filternum = 256;
+       dmxdev->demux = &demux->dmx;
+       dmxdev->capabilities = 0;
+       ret = dvb_dmxdev_init(dmxdev, dvb_adap);
+       if (ret < 0)
+               goto err_dmx_release;
+
+       return adap;
+
+err_dmx_release:
+       dvb_dmx_release(demux);
+err_unregister_adapter:
+       dvb_unregister_adapter(dvb_adap);
+err_free_page:
+       free_page((unsigned long)buf);
+err_kfree:
+       kfree(adap);
+err:
+       return ERR_PTR(ret);
+}
+
+static void pt1_cleanup_adapters(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < PT1_NR_ADAPS; i++)
+               pt1_free_adapter(pt1->adaps[i]);
+}
+
+static int pt1_init_adapters(struct pt1 *pt1)
+{
+       int i;
+       struct pt1_adapter *adap;
+       int ret;
+
+       for (i = 0; i < PT1_NR_ADAPS; i++) {
+               adap = pt1_alloc_adapter(pt1);
+               if (IS_ERR(adap)) {
+                       ret = PTR_ERR(adap);
+                       goto err;
+               }
+
+               adap->index = i;
+               pt1->adaps[i] = adap;
+       }
+       return 0;
+
+err:
+       while (i--)
+               pt1_free_adapter(pt1->adaps[i]);
+
+       return ret;
+}
+
+static void pt1_cleanup_frontend(struct pt1_adapter *adap)
+{
+       dvb_unregister_frontend(adap->fe);
+}
+
+static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe)
+{
+       int ret;
+
+       adap->orig_set_voltage = fe->ops.set_voltage;
+       adap->orig_sleep = fe->ops.sleep;
+       adap->orig_init = fe->ops.init;
+       fe->ops.set_voltage = pt1_set_voltage;
+       fe->ops.sleep = pt1_sleep;
+       fe->ops.init = pt1_wakeup;
+
+       ret = dvb_register_frontend(&adap->adap, fe);
+       if (ret < 0)
+               return ret;
+
+       adap->fe = fe;
+       return 0;
+}
+
+static void pt1_cleanup_frontends(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < PT1_NR_ADAPS; i++)
+               pt1_cleanup_frontend(pt1->adaps[i]);
+}
+
+struct pt1_config {
+       struct va1j5jf8007s_config va1j5jf8007s_config;
+       struct va1j5jf8007t_config va1j5jf8007t_config;
+};
+
+static const struct pt1_config pt1_configs[2] = {
+       {
+               {
+                       .demod_address = 0x1b,
+                       .frequency = VA1J5JF8007S_20MHZ,
+               },
+               {
+                       .demod_address = 0x1a,
+                       .frequency = VA1J5JF8007T_20MHZ,
+               },
+       }, {
+               {
+                       .demod_address = 0x19,
+                       .frequency = VA1J5JF8007S_20MHZ,
+               },
+               {
+                       .demod_address = 0x18,
+                       .frequency = VA1J5JF8007T_20MHZ,
+               },
+       },
+};
+
+static const struct pt1_config pt2_configs[2] = {
+       {
+               {
+                       .demod_address = 0x1b,
+                       .frequency = VA1J5JF8007S_25MHZ,
+               },
+               {
+                       .demod_address = 0x1a,
+                       .frequency = VA1J5JF8007T_25MHZ,
+               },
+       }, {
+               {
+                       .demod_address = 0x19,
+                       .frequency = VA1J5JF8007S_25MHZ,
+               },
+               {
+                       .demod_address = 0x18,
+                       .frequency = VA1J5JF8007T_25MHZ,
+               },
+       },
+};
+
+static int pt1_init_frontends(struct pt1 *pt1)
+{
+       int i, j;
+       struct i2c_adapter *i2c_adap;
+       const struct pt1_config *configs, *config;
+       struct dvb_frontend *fe[4];
+       int ret;
+
+       i = 0;
+       j = 0;
+
+       i2c_adap = &pt1->i2c_adap;
+       configs = pt1->pdev->device == 0x211a ? pt1_configs : pt2_configs;
+       do {
+               config = &configs[i / 2];
+
+               fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
+                                           i2c_adap);
+               if (!fe[i]) {
+                       ret = -ENODEV; /* This does not sound nice... */
+                       goto err;
+               }
+               i++;
+
+               fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config,
+                                           i2c_adap);
+               if (!fe[i]) {
+                       ret = -ENODEV;
+                       goto err;
+               }
+               i++;
+
+               ret = va1j5jf8007s_prepare(fe[i - 2]);
+               if (ret < 0)
+                       goto err;
+
+               ret = va1j5jf8007t_prepare(fe[i - 1]);
+               if (ret < 0)
+                       goto err;
+
+       } while (i < 4);
+
+       do {
+               ret = pt1_init_frontend(pt1->adaps[j], fe[j]);
+               if (ret < 0)
+                       goto err;
+       } while (++j < 4);
+
+       return 0;
+
+err:
+       while (i-- > j)
+               fe[i]->ops.release(fe[i]);
+
+       while (j--)
+               dvb_unregister_frontend(fe[j]);
+
+       return ret;
+}
+
+static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable,
+                        int clock, int data, int next_addr)
+{
+       pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 |
+                     !clock << 11 | !data << 10 | next_addr);
+}
+
+static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data)
+{
+       pt1_i2c_emit(pt1, addr,     1, 0, 0, data, addr + 1);
+       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2);
+       pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3);
+       *addrp = addr + 3;
+}
+
+static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp)
+{
+       pt1_i2c_emit(pt1, addr,     1, 0, 0, 1, addr + 1);
+       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2);
+       pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3);
+       pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4);
+       *addrp = addr + 4;
+}
+
+static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data)
+{
+       int i;
+       for (i = 0; i < 8; i++)
+               pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1);
+       pt1_i2c_write_bit(pt1, addr, &addr, 1);
+       *addrp = addr;
+}
+
+static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last)
+{
+       int i;
+       for (i = 0; i < 8; i++)
+               pt1_i2c_read_bit(pt1, addr, &addr);
+       pt1_i2c_write_bit(pt1, addr, &addr, last);
+       *addrp = addr;
+}
+
+static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp)
+{
+       pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
+       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+       pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3);
+       *addrp = addr + 3;
+}
+
+static void
+pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
+{
+       int i;
+       pt1_i2c_prepare(pt1, addr, &addr);
+       pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1);
+       for (i = 0; i < msg->len; i++)
+               pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]);
+       *addrp = addr;
+}
+
+static void
+pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
+{
+       int i;
+       pt1_i2c_prepare(pt1, addr, &addr);
+       pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1);
+       for (i = 0; i < msg->len; i++)
+               pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1);
+       *addrp = addr;
+}
+
+static int pt1_i2c_end(struct pt1 *pt1, int addr)
+{
+       pt1_i2c_emit(pt1, addr,     1, 0, 0, 0, addr + 1);
+       pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+       pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0);
+
+       pt1_write_reg(pt1, 0, 0x00000004);
+       do {
+               if (signal_pending(current))
+                       return -EINTR;
+               schedule_timeout_interruptible((HZ + 999) / 1000);
+       } while (pt1_read_reg(pt1, 0) & 0x00000080);
+       return 0;
+}
+
+static void pt1_i2c_begin(struct pt1 *pt1, int *addrp)
+{
+       int addr;
+       addr = 0;
+
+       pt1_i2c_emit(pt1, addr,     0, 0, 1, 1, addr /* itself */);
+       addr = addr + 1;
+
+       if (!pt1->i2c_running) {
+               pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
+               pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+               addr = addr + 2;
+               pt1->i2c_running = 1;
+       }
+       *addrp = addr;
+}
+
+static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       struct pt1 *pt1;
+       int i;
+       struct i2c_msg *msg, *next_msg;
+       int addr, ret;
+       u16 len;
+       u32 word;
+
+       pt1 = i2c_get_adapdata(adap);
+
+       for (i = 0; i < num; i++) {
+               msg = &msgs[i];
+               if (msg->flags & I2C_M_RD)
+                       return -ENOTSUPP;
+
+               if (i + 1 < num)
+                       next_msg = &msgs[i + 1];
+               else
+                       next_msg = NULL;
+
+               if (next_msg && next_msg->flags & I2C_M_RD) {
+                       i++;
+
+                       len = next_msg->len;
+                       if (len > 4)
+                               return -ENOTSUPP;
+
+                       pt1_i2c_begin(pt1, &addr);
+                       pt1_i2c_write_msg(pt1, addr, &addr, msg);
+                       pt1_i2c_read_msg(pt1, addr, &addr, next_msg);
+                       ret = pt1_i2c_end(pt1, addr);
+                       if (ret < 0)
+                               return ret;
+
+                       word = pt1_read_reg(pt1, 2);
+                       while (len--) {
+                               next_msg->buf[len] = word;
+                               word >>= 8;
+                       }
+               } else {
+                       pt1_i2c_begin(pt1, &addr);
+                       pt1_i2c_write_msg(pt1, addr, &addr, msg);
+                       ret = pt1_i2c_end(pt1, addr);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return num;
+}
+
+static u32 pt1_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm pt1_i2c_algo = {
+       .master_xfer = pt1_i2c_xfer,
+       .functionality = pt1_i2c_func,
+};
+
+static void pt1_i2c_wait(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < 128; i++)
+               pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0);
+}
+
+static void pt1_i2c_init(struct pt1 *pt1)
+{
+       int i;
+       for (i = 0; i < 1024; i++)
+               pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
+}
+
+static void __devexit pt1_remove(struct pci_dev *pdev)
+{
+       struct pt1 *pt1;
+       void __iomem *regs;
+
+       pt1 = pci_get_drvdata(pdev);
+       regs = pt1->regs;
+
+       if (pt1->kthread)
+               kthread_stop(pt1->kthread);
+       pt1_cleanup_tables(pt1);
+       pt1_cleanup_frontends(pt1);
+       pt1_disable_ram(pt1);
+       pt1->power = 0;
+       pt1->reset = 1;
+       pt1_update_power(pt1);
+       pt1_cleanup_adapters(pt1);
+       i2c_del_adapter(&pt1->i2c_adap);
+       pci_set_drvdata(pdev, NULL);
+       kfree(pt1);
+       pci_iounmap(pdev, regs);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static int __devinit
+pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       int ret;
+       void __iomem *regs;
+       struct pt1 *pt1;
+       struct i2c_adapter *i2c_adap;
+
+       ret = pci_enable_device(pdev);
+       if (ret < 0)
+               goto err;
+
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       pci_set_master(pdev);
+
+       ret = pci_request_regions(pdev, DRIVER_NAME);
+       if (ret < 0)
+               goto err_pci_disable_device;
+
+       regs = pci_iomap(pdev, 0, 0);
+       if (!regs) {
+               ret = -EIO;
+               goto err_pci_release_regions;
+       }
+
+       pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL);
+       if (!pt1) {
+               ret = -ENOMEM;
+               goto err_pci_iounmap;
+       }
+
+       mutex_init(&pt1->lock);
+       pt1->pdev = pdev;
+       pt1->regs = regs;
+       pci_set_drvdata(pdev, pt1);
+
+       ret = pt1_init_adapters(pt1);
+       if (ret < 0)
+               goto err_kfree;
+
+       mutex_init(&pt1->lock);
+
+       pt1->power = 0;
+       pt1->reset = 1;
+       pt1_update_power(pt1);
+
+       i2c_adap = &pt1->i2c_adap;
+       i2c_adap->algo = &pt1_i2c_algo;
+       i2c_adap->algo_data = NULL;
+       i2c_adap->dev.parent = &pdev->dev;
+       strcpy(i2c_adap->name, DRIVER_NAME);
+       i2c_set_adapdata(i2c_adap, pt1);
+       ret = i2c_add_adapter(i2c_adap);
+       if (ret < 0)
+               goto err_pt1_cleanup_adapters;
+
+       pt1_i2c_init(pt1);
+       pt1_i2c_wait(pt1);
+
+       ret = pt1_sync(pt1);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       pt1_identify(pt1);
+
+       ret = pt1_unlock(pt1);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       ret = pt1_reset_pci(pt1);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       ret = pt1_reset_ram(pt1);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       ret = pt1_enable_ram(pt1);
+       if (ret < 0)
+               goto err_i2c_del_adapter;
+
+       pt1_init_streams(pt1);
+
+       pt1->power = 1;
+       pt1_update_power(pt1);
+       schedule_timeout_uninterruptible((HZ + 49) / 50);
+
+       pt1->reset = 0;
+       pt1_update_power(pt1);
+       schedule_timeout_uninterruptible((HZ + 999) / 1000);
+
+       ret = pt1_init_frontends(pt1);
+       if (ret < 0)
+               goto err_pt1_disable_ram;
+
+       ret = pt1_init_tables(pt1);
+       if (ret < 0)
+               goto err_pt1_cleanup_frontends;
+
+       return 0;
+
+err_pt1_cleanup_frontends:
+       pt1_cleanup_frontends(pt1);
+err_pt1_disable_ram:
+       pt1_disable_ram(pt1);
+       pt1->power = 0;
+       pt1->reset = 1;
+       pt1_update_power(pt1);
+err_i2c_del_adapter:
+       i2c_del_adapter(i2c_adap);
+err_pt1_cleanup_adapters:
+       pt1_cleanup_adapters(pt1);
+err_kfree:
+       pci_set_drvdata(pdev, NULL);
+       kfree(pt1);
+err_pci_iounmap:
+       pci_iounmap(pdev, regs);
+err_pci_release_regions:
+       pci_release_regions(pdev);
+err_pci_disable_device:
+       pci_disable_device(pdev);
+err:
+       return ret;
+
+}
+
+static struct pci_device_id pt1_id_table[] = {
+       { PCI_DEVICE(0x10ee, 0x211a) },
+       { PCI_DEVICE(0x10ee, 0x222a) },
+       { },
+};
+MODULE_DEVICE_TABLE(pci, pt1_id_table);
+
+static struct pci_driver pt1_driver = {
+       .name           = DRIVER_NAME,
+       .probe          = pt1_probe,
+       .remove         = __devexit_p(pt1_remove),
+       .id_table       = pt1_id_table,
+};
+
+
+static int __init pt1_init(void)
+{
+       return pci_register_driver(&pt1_driver);
+}
+
+
+static void __exit pt1_cleanup(void)
+{
+       pci_unregister_driver(&pt1_driver);
+}
+
+module_init(pt1_init);
+module_exit(pt1_cleanup);
+
+MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
+MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c
new file mode 100644 (file)
index 0000000..d980dfb
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "va1j5jf8007s.h"
+
+enum va1j5jf8007s_tune_state {
+       VA1J5JF8007S_IDLE,
+       VA1J5JF8007S_SET_FREQUENCY_1,
+       VA1J5JF8007S_SET_FREQUENCY_2,
+       VA1J5JF8007S_SET_FREQUENCY_3,
+       VA1J5JF8007S_CHECK_FREQUENCY,
+       VA1J5JF8007S_SET_MODULATION,
+       VA1J5JF8007S_CHECK_MODULATION,
+       VA1J5JF8007S_SET_TS_ID,
+       VA1J5JF8007S_CHECK_TS_ID,
+       VA1J5JF8007S_TRACK,
+};
+
+struct va1j5jf8007s_state {
+       const struct va1j5jf8007s_config *config;
+       struct i2c_adapter *adap;
+       struct dvb_frontend fe;
+       enum va1j5jf8007s_tune_state tune_state;
+};
+
+static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct va1j5jf8007s_state *state;
+       u8 addr;
+       int i;
+       u8 write_buf[1], read_buf[1];
+       struct i2c_msg msgs[2];
+       s32 word, x1, x2, x3, x4, x5, y;
+
+       state = fe->demodulator_priv;
+       addr = state->config->demod_address;
+
+       word = 0;
+       for (i = 0; i < 2; i++) {
+               write_buf[0] = 0xbc + i;
+
+               msgs[0].addr = addr;
+               msgs[0].flags = 0;
+               msgs[0].len = sizeof(write_buf);
+               msgs[0].buf = write_buf;
+
+               msgs[1].addr = addr;
+               msgs[1].flags = I2C_M_RD;
+               msgs[1].len = sizeof(read_buf);
+               msgs[1].buf = read_buf;
+
+               if (i2c_transfer(state->adap, msgs, 2) != 2)
+                       return -EREMOTEIO;
+
+               word <<= 8;
+               word |= read_buf[0];
+       }
+
+       word -= 3000;
+       if (word < 0)
+               word = 0;
+
+       x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
+       x2 = (s64)x1 * x1 >> 31;
+       x3 = (s64)x2 * x1 >> 31;
+       x4 = (s64)x2 * x2 >> 31;
+       x5 = (s64)x4 * x1 >> 31;
+
+       y = (58857ll << 23) / 1000;
+       y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
+       y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
+       y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
+       y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
+       y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
+
+       *snr = y < 0 ? 0 : y >> 15;
+       return 0;
+}
+
+static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_HW;
+}
+
+static int
+va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct va1j5jf8007s_state *state;
+
+       state = fe->demodulator_priv;
+
+       switch (state->tune_state) {
+       case VA1J5JF8007S_IDLE:
+       case VA1J5JF8007S_SET_FREQUENCY_1:
+       case VA1J5JF8007S_SET_FREQUENCY_2:
+       case VA1J5JF8007S_SET_FREQUENCY_3:
+       case VA1J5JF8007S_CHECK_FREQUENCY:
+               *status = 0;
+               return 0;
+
+
+       case VA1J5JF8007S_SET_MODULATION:
+       case VA1J5JF8007S_CHECK_MODULATION:
+               *status |= FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007S_SET_TS_ID:
+       case VA1J5JF8007S_CHECK_TS_ID:
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+               return 0;
+
+       case VA1J5JF8007S_TRACK:
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+               return 0;
+       }
+
+       BUG();
+}
+
+struct va1j5jf8007s_cb_map {
+       u32 frequency;
+       u8 cb;
+};
+
+static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
+       {  986000, 0xb2 },
+       { 1072000, 0xd2 },
+       { 1154000, 0xe2 },
+       { 1291000, 0x20 },
+       { 1447000, 0x40 },
+       { 1615000, 0x60 },
+       { 1791000, 0x80 },
+       { 1972000, 0xa0 },
+};
+
+static u8 va1j5jf8007s_lookup_cb(u32 frequency)
+{
+       int i;
+       const struct va1j5jf8007s_cb_map *map;
+
+       for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
+               map = &va1j5jf8007s_cb_maps[i];
+               if (frequency < map->frequency)
+                       return map->cb;
+       }
+       return 0xc0;
+}
+
+static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
+{
+       u32 frequency;
+       u16 word;
+       u8 buf[6];
+       struct i2c_msg msg;
+
+       frequency = state->fe.dtv_property_cache.frequency;
+
+       word = (frequency + 500) / 1000;
+       if (frequency < 1072000)
+               word = (word << 1 & ~0x1f) | (word & 0x0f);
+
+       buf[0] = 0xfe;
+       buf[1] = 0xc0;
+       buf[2] = 0x40 | word >> 8;
+       buf[3] = word;
+       buf[4] = 0xe0;
+       buf[5] = va1j5jf8007s_lookup_cb(frequency);
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
+{
+       u8 buf[3];
+       struct i2c_msg msg;
+
+       buf[0] = 0xfe;
+       buf[1] = 0xc0;
+       buf[2] = 0xe4;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
+{
+       u32 frequency;
+       u8 buf[4];
+       struct i2c_msg msg;
+
+       frequency = state->fe.dtv_property_cache.frequency;
+
+       buf[0] = 0xfe;
+       buf[1] = 0xc0;
+       buf[2] = 0xf4;
+       buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int
+va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
+{
+       u8 addr;
+       u8 write_buf[2], read_buf[1];
+       struct i2c_msg msgs[2];
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0xfe;
+       write_buf[1] = 0xc1;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       *lock = read_buf[0] & 0x40;
+       return 0;
+}
+
+static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
+{
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       buf[0] = 0x03;
+       buf[1] = 0x01;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int
+va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
+{
+       u8 addr;
+       u8 write_buf[1], read_buf[1];
+       struct i2c_msg msgs[2];
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0xc3;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       *lock = !(read_buf[0] & 0x10);
+       return 0;
+}
+
+static int
+va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
+{
+       u32 ts_id;
+       u8 buf[3];
+       struct i2c_msg msg;
+
+       ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
+       if (!ts_id)
+               return 0;
+
+       buf[0] = 0x8f;
+       buf[1] = ts_id >> 8;
+       buf[2] = ts_id;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int
+va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
+{
+       u8 addr;
+       u8 write_buf[1], read_buf[2];
+       struct i2c_msg msgs[2];
+       u32 ts_id;
+
+       ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
+       if (!ts_id) {
+               *lock = 1;
+               return 0;
+       }
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0xe6;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
+       return 0;
+}
+
+static int
+va1j5jf8007s_tune(struct dvb_frontend *fe,
+                 bool re_tune,
+                 unsigned int mode_flags,  unsigned int *delay,
+                 fe_status_t *status)
+{
+       struct va1j5jf8007s_state *state;
+       int ret;
+       int lock = 0;
+
+       state = fe->demodulator_priv;
+
+       if (re_tune)
+               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
+
+       switch (state->tune_state) {
+       case VA1J5JF8007S_IDLE:
+               *delay = 3 * HZ;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007S_SET_FREQUENCY_1:
+               ret = va1j5jf8007s_set_frequency_1(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
+               *delay = 0;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007S_SET_FREQUENCY_2:
+               ret = va1j5jf8007s_set_frequency_2(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
+               *delay = (HZ + 99) / 100;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007S_SET_FREQUENCY_3:
+               ret = va1j5jf8007s_set_frequency_3(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
+               *delay = 0;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007S_CHECK_FREQUENCY:
+               ret = va1j5jf8007s_check_frequency(state, &lock);
+               if (ret < 0)
+                       return ret;
+
+               if (!lock)  {
+                       *delay = (HZ + 999) / 1000;
+                       *status = 0;
+                       return 0;
+               }
+
+               state->tune_state = VA1J5JF8007S_SET_MODULATION;
+               *delay = 0;
+               *status = FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007S_SET_MODULATION:
+               ret = va1j5jf8007s_set_modulation(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
+               *delay = 0;
+               *status = FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007S_CHECK_MODULATION:
+               ret = va1j5jf8007s_check_modulation(state, &lock);
+               if (ret < 0)
+                       return ret;
+
+               if (!lock)  {
+                       *delay = (HZ + 49) / 50;
+                       *status = FE_HAS_SIGNAL;
+                       return 0;
+               }
+
+               state->tune_state = VA1J5JF8007S_SET_TS_ID;
+               *delay = 0;
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+               return 0;
+
+       case VA1J5JF8007S_SET_TS_ID:
+               ret = va1j5jf8007s_set_ts_id(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
+               return 0;
+
+       case VA1J5JF8007S_CHECK_TS_ID:
+               ret = va1j5jf8007s_check_ts_id(state, &lock);
+               if (ret < 0)
+                       return ret;
+
+               if (!lock)  {
+                       *delay = (HZ + 99) / 100;
+                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+                       return 0;
+               }
+
+               state->tune_state = VA1J5JF8007S_TRACK;
+               /* fall through */
+
+       case VA1J5JF8007S_TRACK:
+               *delay = 3 * HZ;
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+               return 0;
+       }
+
+       BUG();
+}
+
+static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
+{
+       u8 buf[4];
+       struct i2c_msg msg;
+
+       buf[0] = 0xfe;
+       buf[1] = 0xc0;
+       buf[2] = 0xf0;
+       buf[3] = 0x04;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
+{
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       buf[0] = 0x17;
+       buf[1] = sleep ? 0x01 : 0x00;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007s_state *state;
+       int ret;
+
+       state = fe->demodulator_priv;
+
+       ret = va1j5jf8007s_init_frequency(state);
+       if (ret < 0)
+               return ret;
+
+       return va1j5jf8007s_set_sleep(state, 1);
+}
+
+static int va1j5jf8007s_init(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007s_state *state;
+
+       state = fe->demodulator_priv;
+       state->tune_state = VA1J5JF8007S_IDLE;
+
+       return va1j5jf8007s_set_sleep(state, 0);
+}
+
+static void va1j5jf8007s_release(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007s_state *state;
+       state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops va1j5jf8007s_ops = {
+       .delsys = { SYS_ISDBS },
+       .info = {
+               .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1000,
+               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .read_snr = va1j5jf8007s_read_snr,
+       .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
+       .read_status = va1j5jf8007s_read_status,
+       .tune = va1j5jf8007s_tune,
+       .sleep = va1j5jf8007s_sleep,
+       .init = va1j5jf8007s_init,
+       .release = va1j5jf8007s_release,
+};
+
+static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
+{
+       u8 addr;
+       u8 write_buf[1], read_buf[1];
+       struct i2c_msg msgs[2];
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0x07;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       if (read_buf[0] != 0x41)
+               return -EIO;
+
+       return 0;
+}
+
+static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = {
+       {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
+       {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
+       {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
+       {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
+};
+
+static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = {
+       {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
+       {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
+       {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
+       {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
+};
+
+static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
+{
+       const u8 (*bufs)[2];
+       int size;
+       u8 addr;
+       u8 buf[2];
+       struct i2c_msg msg;
+       int i;
+
+       switch (state->config->frequency) {
+       case VA1J5JF8007S_20MHZ:
+               bufs = va1j5jf8007s_20mhz_prepare_bufs;
+               size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs);
+               break;
+       case VA1J5JF8007S_25MHZ:
+               bufs = va1j5jf8007s_25mhz_prepare_bufs;
+               size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       addr = state->config->demod_address;
+
+       msg.addr = addr;
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = buf;
+       for (i = 0; i < size; i++) {
+               memcpy(buf, bufs[i], sizeof(buf));
+               if (i2c_transfer(state->adap, &msg, 1) != 1)
+                       return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+/* must be called after va1j5jf8007t_attach */
+int va1j5jf8007s_prepare(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007s_state *state;
+       int ret;
+
+       state = fe->demodulator_priv;
+
+       ret = va1j5jf8007s_prepare_1(state);
+       if (ret < 0)
+               return ret;
+
+       ret = va1j5jf8007s_prepare_2(state);
+       if (ret < 0)
+               return ret;
+
+       return va1j5jf8007s_init_frequency(state);
+}
+
+struct dvb_frontend *
+va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
+                   struct i2c_adapter *adap)
+{
+       struct va1j5jf8007s_state *state;
+       struct dvb_frontend *fe;
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       state->config = config;
+       state->adap = adap;
+
+       fe = &state->fe;
+       memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
+       fe->demodulator_priv = state;
+
+       buf[0] = 0x01;
+       buf[1] = 0x80;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1) {
+               kfree(state);
+               return NULL;
+       }
+
+       return fe;
+}
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.h b/drivers/media/pci/pt1/va1j5jf8007s.h
new file mode 100644 (file)
index 0000000..b7d6f05
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * 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 VA1J5JF8007S_H
+#define VA1J5JF8007S_H
+
+enum va1j5jf8007s_frequency {
+       VA1J5JF8007S_20MHZ,
+       VA1J5JF8007S_25MHZ,
+};
+
+struct va1j5jf8007s_config {
+       u8 demod_address;
+       enum va1j5jf8007s_frequency frequency;
+};
+
+struct i2c_adapter;
+
+struct dvb_frontend *
+va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
+                   struct i2c_adapter *adap);
+
+/* must be called after va1j5jf8007t_attach */
+int va1j5jf8007s_prepare(struct dvb_frontend *fe);
+
+#endif
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c
new file mode 100644 (file)
index 0000000..2db1515
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "va1j5jf8007t.h"
+
+enum va1j5jf8007t_tune_state {
+       VA1J5JF8007T_IDLE,
+       VA1J5JF8007T_SET_FREQUENCY,
+       VA1J5JF8007T_CHECK_FREQUENCY,
+       VA1J5JF8007T_SET_MODULATION,
+       VA1J5JF8007T_CHECK_MODULATION,
+       VA1J5JF8007T_TRACK,
+       VA1J5JF8007T_ABORT,
+};
+
+struct va1j5jf8007t_state {
+       const struct va1j5jf8007t_config *config;
+       struct i2c_adapter *adap;
+       struct dvb_frontend fe;
+       enum va1j5jf8007t_tune_state tune_state;
+};
+
+static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct va1j5jf8007t_state *state;
+       u8 addr;
+       int i;
+       u8 write_buf[1], read_buf[1];
+       struct i2c_msg msgs[2];
+       s32 word, x, y;
+
+       state = fe->demodulator_priv;
+       addr = state->config->demod_address;
+
+       word = 0;
+       for (i = 0; i < 3; i++) {
+               write_buf[0] = 0x8b + i;
+
+               msgs[0].addr = addr;
+               msgs[0].flags = 0;
+               msgs[0].len = sizeof(write_buf);
+               msgs[0].buf = write_buf;
+
+               msgs[1].addr = addr;
+               msgs[1].flags = I2C_M_RD;
+               msgs[1].len = sizeof(read_buf);
+               msgs[1].buf = read_buf;
+
+               if (i2c_transfer(state->adap, msgs, 2) != 2)
+                       return -EREMOTEIO;
+
+               word <<= 8;
+               word |= read_buf[0];
+       }
+
+       if (!word)
+               return -EIO;
+
+       x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
+       y = (24ll << 46) / 1000000;
+       y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
+       y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
+       y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
+       y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
+       *snr = y >> 15;
+       return 0;
+}
+
+static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_HW;
+}
+
+static int
+va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct va1j5jf8007t_state *state;
+
+       state = fe->demodulator_priv;
+
+       switch (state->tune_state) {
+       case VA1J5JF8007T_IDLE:
+       case VA1J5JF8007T_SET_FREQUENCY:
+       case VA1J5JF8007T_CHECK_FREQUENCY:
+               *status = 0;
+               return 0;
+
+
+       case VA1J5JF8007T_SET_MODULATION:
+       case VA1J5JF8007T_CHECK_MODULATION:
+       case VA1J5JF8007T_ABORT:
+               *status |= FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007T_TRACK:
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+               return 0;
+       }
+
+       BUG();
+}
+
+struct va1j5jf8007t_cb_map {
+       u32 frequency;
+       u8 cb;
+};
+
+static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
+       {  90000000, 0x80 },
+       { 140000000, 0x81 },
+       { 170000000, 0xa1 },
+       { 220000000, 0x62 },
+       { 330000000, 0xa2 },
+       { 402000000, 0xe2 },
+       { 450000000, 0x64 },
+       { 550000000, 0x84 },
+       { 600000000, 0xa4 },
+       { 700000000, 0xc4 },
+};
+
+static u8 va1j5jf8007t_lookup_cb(u32 frequency)
+{
+       int i;
+       const struct va1j5jf8007t_cb_map *map;
+
+       for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
+               map = &va1j5jf8007t_cb_maps[i];
+               if (frequency < map->frequency)
+                       return map->cb;
+       }
+       return 0xe4;
+}
+
+static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
+{
+       u32 frequency;
+       u16 word;
+       u8 buf[6];
+       struct i2c_msg msg;
+
+       frequency = state->fe.dtv_property_cache.frequency;
+
+       word = (frequency + 71428) / 142857 + 399;
+       buf[0] = 0xfe;
+       buf[1] = 0xc2;
+       buf[2] = word >> 8;
+       buf[3] = word;
+       buf[4] = 0x80;
+       buf[5] = va1j5jf8007t_lookup_cb(frequency);
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int
+va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
+{
+       u8 addr;
+       u8 write_buf[2], read_buf[1];
+       struct i2c_msg msgs[2];
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0xfe;
+       write_buf[1] = 0xc3;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       *lock = read_buf[0] & 0x40;
+       return 0;
+}
+
+static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
+{
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       buf[0] = 0x01;
+       buf[1] = 0x40;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
+                                        int *lock, int *retry)
+{
+       u8 addr;
+       u8 write_buf[1], read_buf[1];
+       struct i2c_msg msgs[2];
+
+       addr = state->config->demod_address;
+
+       write_buf[0] = 0x80;
+
+       msgs[0].addr = addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(write_buf);
+       msgs[0].buf = write_buf;
+
+       msgs[1].addr = addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = sizeof(read_buf);
+       msgs[1].buf = read_buf;
+
+       if (i2c_transfer(state->adap, msgs, 2) != 2)
+               return -EREMOTEIO;
+
+       *lock = !(read_buf[0] & 0x10);
+       *retry = read_buf[0] & 0x80;
+       return 0;
+}
+
+static int
+va1j5jf8007t_tune(struct dvb_frontend *fe,
+                 bool re_tune,
+                 unsigned int mode_flags,  unsigned int *delay,
+                 fe_status_t *status)
+{
+       struct va1j5jf8007t_state *state;
+       int ret;
+       int lock = 0, retry = 0;
+
+       state = fe->demodulator_priv;
+
+       if (re_tune)
+               state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
+
+       switch (state->tune_state) {
+       case VA1J5JF8007T_IDLE:
+               *delay = 3 * HZ;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007T_SET_FREQUENCY:
+               ret = va1j5jf8007t_set_frequency(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
+               *delay = 0;
+               *status = 0;
+               return 0;
+
+       case VA1J5JF8007T_CHECK_FREQUENCY:
+               ret = va1j5jf8007t_check_frequency(state, &lock);
+               if (ret < 0)
+                       return ret;
+
+               if (!lock)  {
+                       *delay = (HZ + 999) / 1000;
+                       *status = 0;
+                       return 0;
+               }
+
+               state->tune_state = VA1J5JF8007T_SET_MODULATION;
+               *delay = 0;
+               *status = FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007T_SET_MODULATION:
+               ret = va1j5jf8007t_set_modulation(state);
+               if (ret < 0)
+                       return ret;
+
+               state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
+               *delay = 0;
+               *status = FE_HAS_SIGNAL;
+               return 0;
+
+       case VA1J5JF8007T_CHECK_MODULATION:
+               ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
+               if (ret < 0)
+                       return ret;
+
+               if (!lock)  {
+                       if (!retry)  {
+                               state->tune_state = VA1J5JF8007T_ABORT;
+                               *delay = 3 * HZ;
+                               *status = FE_HAS_SIGNAL;
+                               return 0;
+                       }
+                       *delay = (HZ + 999) / 1000;
+                       *status = FE_HAS_SIGNAL;
+                       return 0;
+               }
+
+               state->tune_state = VA1J5JF8007T_TRACK;
+               /* fall through */
+
+       case VA1J5JF8007T_TRACK:
+               *delay = 3 * HZ;
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+               return 0;
+
+       case VA1J5JF8007T_ABORT:
+               *delay = 3 * HZ;
+               *status = FE_HAS_SIGNAL;
+               return 0;
+       }
+
+       BUG();
+}
+
+static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
+{
+       u8 buf[7];
+       struct i2c_msg msg;
+
+       buf[0] = 0xfe;
+       buf[1] = 0xc2;
+       buf[2] = 0x01;
+       buf[3] = 0x8f;
+       buf[4] = 0xc1;
+       buf[5] = 0x80;
+       buf[6] = 0x80;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
+{
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       buf[0] = 0x03;
+       buf[1] = sleep ? 0x90 : 0x80;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007t_state *state;
+       int ret;
+
+       state = fe->demodulator_priv;
+
+       ret = va1j5jf8007t_init_frequency(state);
+       if (ret < 0)
+               return ret;
+
+       return va1j5jf8007t_set_sleep(state, 1);
+}
+
+static int va1j5jf8007t_init(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007t_state *state;
+
+       state = fe->demodulator_priv;
+       state->tune_state = VA1J5JF8007T_IDLE;
+
+       return va1j5jf8007t_set_sleep(state, 0);
+}
+
+static void va1j5jf8007t_release(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007t_state *state;
+       state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops va1j5jf8007t_ops = {
+       .delsys = { SYS_ISDBT },
+       .info = {
+               .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T",
+               .frequency_min = 90000000,
+               .frequency_max = 770000000,
+               .frequency_stepsize = 142857,
+               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .read_snr = va1j5jf8007t_read_snr,
+       .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
+       .read_status = va1j5jf8007t_read_status,
+       .tune = va1j5jf8007t_tune,
+       .sleep = va1j5jf8007t_sleep,
+       .init = va1j5jf8007t_init,
+       .release = va1j5jf8007t_release,
+};
+
+static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = {
+       {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
+       {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
+       {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
+       {0xef, 0x01}
+};
+
+static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = {
+       {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
+       {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
+       {0x77, 0x03}, {0xef, 0x01}
+};
+
+int va1j5jf8007t_prepare(struct dvb_frontend *fe)
+{
+       struct va1j5jf8007t_state *state;
+       const u8 (*bufs)[2];
+       int size;
+       u8 buf[2];
+       struct i2c_msg msg;
+       int i;
+
+       state = fe->demodulator_priv;
+
+       switch (state->config->frequency) {
+       case VA1J5JF8007T_20MHZ:
+               bufs = va1j5jf8007t_20mhz_prepare_bufs;
+               size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs);
+               break;
+       case VA1J5JF8007T_25MHZ:
+               bufs = va1j5jf8007t_25mhz_prepare_bufs;
+               size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       for (i = 0; i < size; i++) {
+               memcpy(buf, bufs[i], sizeof(buf));
+               if (i2c_transfer(state->adap, &msg, 1) != 1)
+                       return -EREMOTEIO;
+       }
+
+       return va1j5jf8007t_init_frequency(state);
+}
+
+struct dvb_frontend *
+va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
+                   struct i2c_adapter *adap)
+{
+       struct va1j5jf8007t_state *state;
+       struct dvb_frontend *fe;
+       u8 buf[2];
+       struct i2c_msg msg;
+
+       state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       state->config = config;
+       state->adap = adap;
+
+       fe = &state->fe;
+       memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
+       fe->demodulator_priv = state;
+
+       buf[0] = 0x01;
+       buf[1] = 0x80;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.len = sizeof(buf);
+       msg.buf = buf;
+
+       if (i2c_transfer(state->adap, &msg, 1) != 1) {
+               kfree(state);
+               return NULL;
+       }
+
+       return fe;
+}
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.h b/drivers/media/pci/pt1/va1j5jf8007t.h
new file mode 100644 (file)
index 0000000..2903be5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ *     by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * 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 VA1J5JF8007T_H
+#define VA1J5JF8007T_H
+
+enum va1j5jf8007t_frequency {
+       VA1J5JF8007T_20MHZ,
+       VA1J5JF8007T_25MHZ,
+};
+
+struct va1j5jf8007t_config {
+       u8 demod_address;
+       enum va1j5jf8007t_frequency frequency;
+};
+
+struct i2c_adapter;
+
+struct dvb_frontend *
+va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
+                   struct i2c_adapter *adap);
+
+/* must be called after va1j5jf8007s_attach */
+int va1j5jf8007t_prepare(struct dvb_frontend *fe);
+
+#endif
diff --git a/drivers/media/pci/ttpci/Kconfig b/drivers/media/pci/ttpci/Kconfig
new file mode 100644 (file)
index 0000000..9d83ced
--- /dev/null
@@ -0,0 +1,159 @@
+config TTPCI_EEPROM
+       tristate
+       depends on I2C
+       default n
+
+config DVB_AV7110
+       tristate "AV7110 cards"
+       depends on DVB_CORE && PCI && I2C
+       select TTPCI_EEPROM
+       select VIDEO_SAA7146_VV
+       depends on VIDEO_DEV    # dependencies of VIDEO_SAA7146_VV
+       select DVB_VES1820 if !DVB_FE_CUSTOMISE
+       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+       select DVB_SP8870 if !DVB_FE_CUSTOMISE
+       select DVB_STV0297 if !DVB_FE_CUSTOMISE
+       select DVB_L64781 if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       help
+         Support for SAA7146 and AV7110 based DVB cards as produced
+         by Fujitsu-Siemens, Technotrend, Hauppauge and others.
+
+         This driver only supports the fullfeatured cards with
+         onboard MPEG2 decoder.
+
+         This driver needs an external firmware. Please use the script
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
+         download/extract it, and then copy it to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+         Alternatively, you can download the file and use the kernel's
+         EXTRA_FIRMWARE configuration option to build it into your
+         kernel image by adding the filename to the EXTRA_FIRMWARE
+         configuration option string.
+
+         Say Y if you own such a card and want to use it.
+
+config DVB_AV7110_OSD
+       bool "AV7110 OSD support"
+       depends on DVB_AV7110
+       default y if DVB_AV7110=y || DVB_AV7110=m
+       help
+         The AV7110 firmware provides some code to generate an OnScreenDisplay
+         on the video output. This is kind of nonstandard and not guaranteed to
+         be maintained.
+
+         Anyway, some popular DVB software like VDR uses this OSD to render
+         its menus, so say Y if you want to use this software.
+
+         All other people say N.
+
+config DVB_BUDGET_CORE
+       tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)"
+       depends on DVB_CORE && PCI && I2C
+       select VIDEO_SAA7146
+       select TTPCI_EEPROM
+       help
+         Support for simple SAA7146 based DVB cards
+         (so called Budget- or Nova-PCI cards) without onboard
+         MPEG2 decoder.
+
+config DVB_BUDGET
+       tristate "Budget cards"
+       depends on DVB_BUDGET_CORE && I2C
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+       select DVB_VES1820 if !DVB_FE_CUSTOMISE
+       select DVB_L64781 if !DVB_FE_CUSTOMISE
+       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+       select DVB_S5H1420 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+       select DVB_TDA826X if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
+       select DVB_STV090x if !DVB_FE_CUSTOMISE
+       select DVB_STV6110x if !DVB_FE_CUSTOMISE
+       help
+         Support for simple SAA7146 based DVB cards (so called Budget-
+         or Nova-PCI cards) without onboard MPEG2 decoder, and without
+         analog inputs or an onboard Common Interface connector.
+
+         Say Y if you own such a card and want to use it.
+
+         To compile this driver as a module, choose M here: the
+         module will be called budget.
+
+config DVB_BUDGET_CI
+       tristate "Budget cards with onboard CI connector"
+       depends on DVB_BUDGET_CORE && I2C
+       select DVB_STV0297 if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+       select DVB_STB0899 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_STV0288 if !DVB_FE_CUSTOMISE
+       select DVB_STB6000 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+       depends on RC_CORE
+       help
+         Support for simple SAA7146 based DVB cards
+         (so called Budget- or Nova-PCI cards) without onboard
+         MPEG2 decoder, but with onboard Common Interface connector.
+
+         Note: The Common Interface is not yet supported by this driver
+         due to lack of information from the vendor.
+
+         Say Y if you own such a card and want to use it.
+
+         To compile this driver as a module, choose M here: the
+         module will be called budget-ci.
+
+config DVB_BUDGET_AV
+       tristate "Budget cards with analog video inputs"
+       depends on DVB_BUDGET_CORE && I2C
+       select VIDEO_SAA7146_VV
+       depends on VIDEO_DEV    # dependencies of VIDEO_SAA7146_VV
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+       select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+       select DVB_STB0899 if !DVB_FE_CUSTOMISE
+       select DVB_TDA8261 if !DVB_FE_CUSTOMISE
+       select DVB_TUA6100 if !DVB_FE_CUSTOMISE
+       help
+         Support for simple SAA7146 based DVB cards
+         (so called Budget- or Nova-PCI cards) without onboard
+         MPEG2 decoder, but with one or more analog video inputs.
+
+         Say Y if you own such a card and want to use it.
+
+         To compile this driver as a module, choose M here: the
+         module will be called budget-av.
+
+config DVB_BUDGET_PATCH
+       tristate "AV7110 cards with Budget Patch"
+       depends on DVB_BUDGET_CORE && I2C
+       depends on DVB_AV7110
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_VES1X93 if !DVB_FE_CUSTOMISE
+       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+       help
+         Support for Budget Patch (full TS) modification on
+         SAA7146+AV7110 based cards (DVB-S cards). This
+         driver doesn't use onboard MPEG2 decoder. The
+         card is driven in Budget-only mode. Card is
+         required to have loaded firmware to tune properly.
+         Firmware can be loaded by insertion and removal of
+         standard AV7110 driver prior to loading this
+         driver.
+
+         Say Y if you own such a card and want to use it.
+
+         To compile this driver as a module, choose M here: the
+         module will be called budget-patch.
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
new file mode 100644 (file)
index 0000000..22a235f
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Makefile for the kernel SAA7146 FULL TS DVB device driver
+# and the AV7110 DVB device driver
+#
+
+dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o
+
+ifdef CONFIG_INPUT_EVDEV
+dvb-ttpci-objs += av7110_ir.o
+endif
+
+obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o
+obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o
+obj-$(CONFIG_DVB_BUDGET) += budget.o
+obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o
+obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
+obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
+obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
new file mode 100644 (file)
index 0000000..4bd8bd5
--- /dev/null
@@ -0,0 +1,2939 @@
+/*
+ * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
+ * av7110.c: initialization and demux stuff
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * originally based on code by:
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
+#include <linux/i2c.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+
+
+#include <linux/dvb/frontend.h>
+
+#include "dvb_frontend.h"
+
+#include "ttpci-eeprom.h"
+#include "av7110.h"
+#include "av7110_hw.h"
+#include "av7110_av.h"
+#include "av7110_ca.h"
+#include "av7110_ipack.h"
+
+#include "bsbe1.h"
+#include "lnbp21.h"
+#include "bsru6.h"
+
+#define TS_WIDTH  376
+#define TS_HEIGHT 512
+#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
+
+
+int av7110_debug;
+
+static int vidmode = CVBS_RGB_OUT;
+static int pids_off;
+static int adac = DVB_ADAC_TI;
+static int hw_sections;
+static int rgb_on;
+static int volume = 255;
+static int budgetpatch;
+static int wss_cfg_4_3 = 0x4008;
+static int wss_cfg_16_9 = 0x0007;
+static int tv_standard;
+static int full_ts;
+
+module_param_named(debug, av7110_debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
+module_param(vidmode, int, 0444);
+MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
+module_param(pids_off, int, 0444);
+MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
+module_param(adac, int, 0444);
+MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
+module_param(hw_sections, int, 0444);
+MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
+module_param(rgb_on, int, 0444);
+MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
+               " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
+module_param(volume, int, 0444);
+MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
+module_param(budgetpatch, int, 0444);
+MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
+module_param(full_ts, int, 0444);
+MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable");
+module_param(wss_cfg_4_3, int, 0444);
+MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
+module_param(wss_cfg_16_9, int, 0444);
+MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data");
+module_param(tv_standard, int, 0444);
+MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static void restart_feeds(struct av7110 *av7110);
+static int budget_start_feed(struct dvb_demux_feed *feed);
+static int budget_stop_feed(struct dvb_demux_feed *feed);
+
+static int av7110_num;
+
+#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
+{\
+       if (fe_func != NULL) { \
+               av7110_copy = fe_func; \
+               fe_func = av7110_func; \
+       } \
+}
+
+
+static void init_av7110_av(struct av7110 *av7110)
+{
+       int ret;
+       struct saa7146_dev *dev = av7110->dev;
+
+       /* set internal volume control to maximum */
+       av7110->adac_type = DVB_ADAC_TI;
+       ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+       if (ret < 0)
+               printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
+
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
+                           1, (u16) av7110->display_ar);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to set aspect ratio\n");
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
+                           1, av7110->display_panscan);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to set pan scan\n");
+
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to configure 4:3 wss\n");
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to configure 16:9 wss\n");
+
+       ret = av7710_set_video_mode(av7110, vidmode);
+       if (ret < 0)
+               printk("dvb-ttpci:cannot set video mode:%d\n",ret);
+
+       /* handle different card types */
+       /* remaining inits according to card and frontend type */
+       av7110->analog_tuner_flags = 0;
+       av7110->current_input = 0;
+       if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a)
+               av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
+       if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
+               printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
+                       av7110->dvb_adapter.num);
+               av7110->adac_type = DVB_ADAC_CRYSTAL;
+               i2c_writereg(av7110, 0x20, 0x01, 0xd2);
+               i2c_writereg(av7110, 0x20, 0x02, 0x49);
+               i2c_writereg(av7110, 0x20, 0x03, 0x00);
+               i2c_writereg(av7110, 0x20, 0x04, 0x00);
+
+               /**
+                * some special handling for the Siemens DVB-C cards...
+                */
+       } else if (0 == av7110_init_analog_module(av7110)) {
+               /* done. */
+       }
+       else if (dev->pci->subsystem_vendor == 0x110a) {
+               printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
+                       av7110->dvb_adapter.num);
+               av7110->adac_type = DVB_ADAC_NONE;
+       }
+       else {
+               av7110->adac_type = adac;
+               printk("dvb-ttpci: adac type set to %d @ card %d\n",
+                       av7110->adac_type, av7110->dvb_adapter.num);
+       }
+
+       if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
+               // switch DVB SCART on
+               ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
+               if (ret < 0)
+                       printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
+               ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+               if (ret < 0)
+                       printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
+               if (rgb_on &&
+                   ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
+                    (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
+                    (av7110->dev->pci->subsystem_device == 0x0000)) {
+                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
+                       //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
+               }
+       }
+
+       if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
+               av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
+
+       ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+       if (ret < 0)
+               printk("dvb-ttpci:cannot set volume :%d\n",ret);
+}
+
+static void recover_arm(struct av7110 *av7110)
+{
+       dprintk(4, "%p\n",av7110);
+
+       av7110_bootarm(av7110);
+       msleep(100);
+
+       init_av7110_av(av7110);
+
+       /* card-specific recovery */
+       if (av7110->recover)
+               av7110->recover(av7110);
+
+       restart_feeds(av7110);
+
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+       av7110_check_ir_config(av7110, true);
+#endif
+}
+
+static void av7110_arm_sync(struct av7110 *av7110)
+{
+       if (av7110->arm_thread)
+               kthread_stop(av7110->arm_thread);
+
+       av7110->arm_thread = NULL;
+}
+
+static int arm_thread(void *data)
+{
+       struct av7110 *av7110 = data;
+       u16 newloops = 0;
+       int timeout;
+
+       dprintk(4, "%p\n",av7110);
+
+       for (;;) {
+               timeout = wait_event_interruptible_timeout(av7110->arm_wait,
+                       kthread_should_stop(), 5 * HZ);
+
+               if (-ERESTARTSYS == timeout || kthread_should_stop()) {
+                       /* got signal or told to quit*/
+                       break;
+               }
+
+               if (!av7110->arm_ready)
+                       continue;
+
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+               av7110_check_ir_config(av7110, false);
+#endif
+
+               if (mutex_lock_interruptible(&av7110->dcomlock))
+                       break;
+               newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
+               mutex_unlock(&av7110->dcomlock);
+
+               if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
+                       printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
+                              av7110->dvb_adapter.num);
+
+                       recover_arm(av7110);
+
+                       if (mutex_lock_interruptible(&av7110->dcomlock))
+                               break;
+                       newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
+                       mutex_unlock(&av7110->dcomlock);
+               }
+               av7110->arm_loops = newloops;
+               av7110->arm_errors = 0;
+       }
+
+       return 0;
+}
+
+
+/****************************************************************************
+ * IRQ handling
+ ****************************************************************************/
+
+static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
+                               u8 *buffer2, size_t buffer2_len,
+                               struct dvb_demux_filter *dvbdmxfilter,
+                               enum dmx_success success,
+                               struct av7110 *av7110)
+{
+       if (!dvbdmxfilter->feed->demux->dmx.frontend)
+               return 0;
+       if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
+               return 0;
+
+       switch (dvbdmxfilter->type) {
+       case DMX_TYPE_SEC:
+               if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
+                       return 0;
+               if (dvbdmxfilter->doneq) {
+                       struct dmx_section_filter *filter = &dvbdmxfilter->filter;
+                       int i;
+                       u8 xor, neq = 0;
+
+                       for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
+                               xor = filter->filter_value[i] ^ buffer1[i];
+                               neq |= dvbdmxfilter->maskandnotmode[i] & xor;
+                       }
+                       if (!neq)
+                               return 0;
+               }
+               return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
+                                                 buffer2, buffer2_len,
+                                                 &dvbdmxfilter->filter,
+                                                 DMX_OK);
+       case DMX_TYPE_TS:
+               if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
+                       return 0;
+               if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
+                       return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
+                                                        buffer2, buffer2_len,
+                                                        &dvbdmxfilter->feed->feed.ts,
+                                                        DMX_OK);
+               else
+                       av7110_p2t_write(buffer1, buffer1_len,
+                                        dvbdmxfilter->feed->pid,
+                                        &av7110->p2t_filter[dvbdmxfilter->index]);
+       default:
+               return 0;
+       }
+}
+
+
+//#define DEBUG_TIMING
+static inline void print_time(char *s)
+{
+#ifdef DEBUG_TIMING
+       struct timeval tv;
+       do_gettimeofday(&tv);
+       printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
+#endif
+}
+
+#define DEBI_READ 0
+#define DEBI_WRITE 1
+static inline void start_debi_dma(struct av7110 *av7110, int dir,
+                                 unsigned long addr, unsigned int len)
+{
+       dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
+       if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+               printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
+               return;
+       }
+
+       SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
+       SAA7146_IER_ENABLE(av7110->dev, MASK_19);
+       if (len < 5)
+               len = 5; /* we want a real DEBI DMA */
+       if (dir == DEBI_WRITE)
+               iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
+       else
+               irdebi(av7110, DEBISWAB, addr, 0, len);
+}
+
+static void debiirq(unsigned long cookie)
+{
+       struct av7110 *av7110 = (struct av7110 *)cookie;
+       int type = av7110->debitype;
+       int handle = (type >> 8) & 0x1f;
+       unsigned int xfer = 0;
+
+       print_time("debi");
+       dprintk(4, "type 0x%04x\n", type);
+
+       if (type == -1) {
+               printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
+                      jiffies, saa7146_read(av7110->dev, PSR),
+                      saa7146_read(av7110->dev, SSR));
+               goto debi_done;
+       }
+       av7110->debitype = -1;
+
+       switch (type & 0xff) {
+
+       case DATA_TS_RECORD:
+               dvb_dmx_swfilter_packets(&av7110->demux,
+                                        (const u8 *) av7110->debi_virt,
+                                        av7110->debilen / 188);
+               xfer = RX_BUFF;
+               break;
+
+       case DATA_PES_RECORD:
+               if (av7110->demux.recording)
+                       av7110_record_cb(&av7110->p2t[handle],
+                                        (u8 *) av7110->debi_virt,
+                                        av7110->debilen);
+               xfer = RX_BUFF;
+               break;
+
+       case DATA_IPMPE:
+       case DATA_FSECTION:
+       case DATA_PIPING:
+               if (av7110->handle2filter[handle])
+                       DvbDmxFilterCallback((u8 *)av7110->debi_virt,
+                                            av7110->debilen, NULL, 0,
+                                            av7110->handle2filter[handle],
+                                            DMX_OK, av7110);
+               xfer = RX_BUFF;
+               break;
+
+       case DATA_CI_GET:
+       {
+               u8 *data = av7110->debi_virt;
+
+               if ((data[0] < 2) && data[2] == 0xff) {
+                       int flags = 0;
+                       if (data[5] > 0)
+                               flags |= CA_CI_MODULE_PRESENT;
+                       if (data[5] > 5)
+                               flags |= CA_CI_MODULE_READY;
+                       av7110->ci_slot[data[0]].flags = flags;
+               } else
+                       ci_get_data(&av7110->ci_rbuffer,
+                                   av7110->debi_virt,
+                                   av7110->debilen);
+               xfer = RX_BUFF;
+               break;
+       }
+
+       case DATA_COMMON_INTERFACE:
+               CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
+#if 0
+       {
+               int i;
+
+               printk("av7110%d: ", av7110->num);
+               printk("%02x ", *(u8 *)av7110->debi_virt);
+               printk("%02x ", *(1+(u8 *)av7110->debi_virt));
+               for (i = 2; i < av7110->debilen; i++)
+                       printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
+               for (i = 2; i < av7110->debilen; i++)
+                       printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
+
+               printk("\n");
+       }
+#endif
+               xfer = RX_BUFF;
+               break;
+
+       case DATA_DEBUG_MESSAGE:
+               ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
+               printk("%s\n", (s8 *) av7110->debi_virt);
+               xfer = RX_BUFF;
+               break;
+
+       case DATA_CI_PUT:
+               dprintk(4, "debi DATA_CI_PUT\n");
+       case DATA_MPEG_PLAY:
+               dprintk(4, "debi DATA_MPEG_PLAY\n");
+       case DATA_BMP_LOAD:
+               dprintk(4, "debi DATA_BMP_LOAD\n");
+               xfer = TX_BUFF;
+               break;
+       default:
+               break;
+       }
+debi_done:
+       spin_lock(&av7110->debilock);
+       if (xfer)
+               iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
+       ARM_ClearMailBox(av7110);
+       spin_unlock(&av7110->debilock);
+}
+
+/* irq from av7110 firmware writing the mailbox register in the DPRAM */
+static void gpioirq(unsigned long cookie)
+{
+       struct av7110 *av7110 = (struct av7110 *)cookie;
+       u32 rxbuf, txbuf;
+       int len;
+
+       if (av7110->debitype != -1)
+               /* we shouldn't get any irq while a debi xfer is running */
+               printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
+                      jiffies, saa7146_read(av7110->dev, PSR),
+                      saa7146_read(av7110->dev, SSR));
+
+       if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+               printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
+               BUG(); /* maybe we should try resetting the debi? */
+       }
+
+       spin_lock(&av7110->debilock);
+       ARM_ClearIrq(av7110);
+
+       /* see what the av7110 wants */
+       av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
+       av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+       rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+       txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+       len = (av7110->debilen + 3) & ~3;
+
+       print_time("gpio");
+       dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
+
+       switch (av7110->debitype & 0xff) {
+
+       case DATA_TS_PLAY:
+       case DATA_PES_PLAY:
+               break;
+
+       case DATA_MPEG_VIDEO_EVENT:
+       {
+               u32 h_ar;
+               struct video_event event;
+
+               av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
+               h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
+
+               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+               iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+
+               av7110->video_size.h = h_ar & 0xfff;
+
+               event.type = VIDEO_EVENT_SIZE_CHANGED;
+               event.u.size.w = av7110->video_size.w;
+               event.u.size.h = av7110->video_size.h;
+               switch ((h_ar >> 12) & 0xf)
+               {
+               case 3:
+                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
+                       event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
+                       av7110->videostate.video_format = VIDEO_FORMAT_16_9;
+                       break;
+               case 4:
+                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
+                       event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
+                       av7110->videostate.video_format = VIDEO_FORMAT_221_1;
+                       break;
+               default:
+                       av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
+                       event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
+                       av7110->videostate.video_format = VIDEO_FORMAT_4_3;
+               }
+
+               dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
+                       av7110->video_size.w, av7110->video_size.h,
+                       av7110->video_size.aspect_ratio);
+
+               dvb_video_add_event(av7110, &event);
+               break;
+       }
+
+       case DATA_CI_PUT:
+       {
+               int avail;
+               struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
+
+               avail = dvb_ringbuffer_avail(cibuf);
+               if (avail <= 2) {
+                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+                       break;
+               }
+               len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
+               len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
+               if (avail < len + 2) {
+                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+                       break;
+               }
+               DVB_RINGBUFFER_SKIP(cibuf, 2);
+
+               dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
+
+               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
+               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
+               dprintk(8, "DMA: CI\n");
+               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
+               spin_unlock(&av7110->debilock);
+               wake_up(&cibuf->queue);
+               return;
+       }
+
+       case DATA_MPEG_PLAY:
+               if (!av7110->playing) {
+                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+                       break;
+               }
+               len = 0;
+               if (av7110->debitype & 0x100) {
+                       spin_lock(&av7110->aout.lock);
+                       len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
+                       spin_unlock(&av7110->aout.lock);
+               }
+               if (len <= 0 && (av7110->debitype & 0x200)
+                   &&av7110->videostate.play_state != VIDEO_FREEZED) {
+                       spin_lock(&av7110->avout.lock);
+                       len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
+                       spin_unlock(&av7110->avout.lock);
+               }
+               if (len <= 0) {
+                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+                       break;
+               }
+               dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
+               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
+               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
+               dprintk(8, "DMA: MPEG_PLAY\n");
+               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
+               spin_unlock(&av7110->debilock);
+               return;
+
+       case DATA_BMP_LOAD:
+               len = av7110->debilen;
+               dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
+               if (!len) {
+                       av7110->bmp_state = BMP_LOADED;
+                       iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
+                       iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+                       wake_up(&av7110->bmpq);
+                       dprintk(8, "gpio DATA_BMP_LOAD done\n");
+                       break;
+               }
+               if (len > av7110->bmplen)
+                       len = av7110->bmplen;
+               if (len > 2 * 1024)
+                       len = 2 * 1024;
+               iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
+               iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
+               memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
+               av7110->bmpp += len;
+               av7110->bmplen -= len;
+               dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
+               start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
+               spin_unlock(&av7110->debilock);
+               return;
+
+       case DATA_CI_GET:
+       case DATA_COMMON_INTERFACE:
+       case DATA_FSECTION:
+       case DATA_IPMPE:
+       case DATA_PIPING:
+               if (!len || len > 4 * 1024) {
+                       iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+                       break;
+               }
+               /* fall through */
+
+       case DATA_TS_RECORD:
+       case DATA_PES_RECORD:
+               dprintk(8, "DMA: TS_REC etc.\n");
+               start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
+               spin_unlock(&av7110->debilock);
+               return;
+
+       case DATA_DEBUG_MESSAGE:
+               if (!len || len > 0xff) {
+                       iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+                       break;
+               }
+               start_debi_dma(av7110, DEBI_READ, Reserved, len);
+               spin_unlock(&av7110->debilock);
+               return;
+
+       case DATA_IRCOMMAND:
+               if (av7110->ir.ir_handler)
+                       av7110->ir.ir_handler(av7110,
+                               swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
+               iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
+               break;
+
+       default:
+               printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
+                      av7110->debitype, av7110->debilen);
+               break;
+       }
+       av7110->debitype = -1;
+       ARM_ClearMailBox(av7110);
+       spin_unlock(&av7110->debilock);
+}
+
+
+#ifdef CONFIG_DVB_AV7110_OSD
+static int dvb_osd_ioctl(struct file *file,
+                        unsigned int cmd, void *parg)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (cmd == OSD_SEND_CMD)
+               return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
+       if (cmd == OSD_GET_CAPABILITY)
+               return av7110_osd_capability(av7110, (osd_cap_t *) parg);
+
+       return -EINVAL;
+}
+
+
+static const struct file_operations dvb_osd_fops = {
+       .owner          = THIS_MODULE,
+       .unlocked_ioctl = dvb_generic_ioctl,
+       .open           = dvb_generic_open,
+       .release        = dvb_generic_release,
+       .llseek         = noop_llseek,
+};
+
+static struct dvb_device dvbdev_osd = {
+       .priv           = NULL,
+       .users          = 1,
+       .writers        = 1,
+       .fops           = &dvb_osd_fops,
+       .kernel_ioctl   = dvb_osd_ioctl,
+};
+#endif /* CONFIG_DVB_AV7110_OSD */
+
+
+static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+                         u16 subpid, u16 pcrpid)
+{
+       u16 aflags = 0;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (vpid == 0x1fff || apid == 0x1fff ||
+           ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
+               vpid = apid = ttpid = subpid = pcrpid = 0;
+               av7110->pids[DMX_PES_VIDEO] = 0;
+               av7110->pids[DMX_PES_AUDIO] = 0;
+               av7110->pids[DMX_PES_TELETEXT] = 0;
+               av7110->pids[DMX_PES_PCR] = 0;
+       }
+
+       if (av7110->audiostate.bypass_mode)
+               aflags |= 0x8000;
+
+       return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
+                            pcrpid, vpid, apid, ttpid, subpid, aflags);
+}
+
+int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+               u16 subpid, u16 pcrpid)
+{
+       int ret = 0;
+       dprintk(4, "%p\n", av7110);
+
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
+               return -ERESTARTSYS;
+
+       if (!(vpid & 0x8000))
+               av7110->pids[DMX_PES_VIDEO] = vpid;
+       if (!(apid & 0x8000))
+               av7110->pids[DMX_PES_AUDIO] = apid;
+       if (!(ttpid & 0x8000))
+               av7110->pids[DMX_PES_TELETEXT] = ttpid;
+       if (!(pcrpid & 0x8000))
+               av7110->pids[DMX_PES_PCR] = pcrpid;
+
+       av7110->pids[DMX_PES_SUBTITLE] = 0;
+
+       if (av7110->fe_synced) {
+               pcrpid = av7110->pids[DMX_PES_PCR];
+               ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
+       }
+
+       mutex_unlock(&av7110->pid_mutex);
+       return ret;
+}
+
+
+/******************************************************************************
+ * hardware filter functions
+ ******************************************************************************/
+
+static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
+{
+       struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
+       struct av7110 *av7110 = dvbdmxfeed->demux->priv;
+       u16 buf[20];
+       int ret, i;
+       u16 handle;
+//     u16 mode = 0x0320;
+       u16 mode = 0xb96a;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (av7110->full_ts)
+               return 0;
+
+       if (dvbdmxfilter->type == DMX_TYPE_SEC) {
+               if (hw_sections) {
+                       buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
+                               dvbdmxfilter->maskandmode[0];
+                       for (i = 3; i < 18; i++)
+                               buf[i + 4 - 2] =
+                                       (dvbdmxfilter->filter.filter_value[i] << 8) |
+                                       dvbdmxfilter->maskandmode[i];
+                       mode = 4;
+               }
+       } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
+                  !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
+               av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
+       }
+
+       buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
+       buf[1] = 16;
+       buf[2] = dvbdmxfeed->pid;
+       buf[3] = mode;
+
+       ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
+       if (ret != 0 || handle >= 32) {
+               printk("dvb-ttpci: %s error  buf %04x %04x %04x %04x  "
+                               "ret %d  handle %04x\n",
+                               __func__, buf[0], buf[1], buf[2], buf[3],
+                               ret, handle);
+               dvbdmxfilter->hw_handle = 0xffff;
+               if (!ret)
+                       ret = -1;
+               return ret;
+       }
+
+       av7110->handle2filter[handle] = dvbdmxfilter;
+       dvbdmxfilter->hw_handle = handle;
+
+       return ret;
+}
+
+static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
+{
+       struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv;
+       u16 buf[3];
+       u16 answ[2];
+       int ret;
+       u16 handle;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (av7110->full_ts)
+               return 0;
+
+       handle = dvbdmxfilter->hw_handle;
+       if (handle >= 32) {
+               printk("%s tried to stop invalid filter %04x, filter type = %x\n",
+                               __func__, handle, dvbdmxfilter->type);
+               return -EINVAL;
+       }
+
+       av7110->handle2filter[handle] = NULL;
+
+       buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
+       buf[1] = 1;
+       buf[2] = handle;
+       ret = av7110_fw_request(av7110, buf, 3, answ, 2);
+       if (ret != 0 || answ[1] != handle) {
+               printk("dvb-ttpci: %s error  cmd %04x %04x %04x  ret %x  "
+                               "resp %04x %04x  pid %d\n",
+                               __func__, buf[0], buf[1], buf[2], ret,
+                               answ[0], answ[1], dvbdmxfilter->feed->pid);
+               if (!ret)
+                       ret = -1;
+       }
+       return ret;
+}
+
+
+static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct av7110 *av7110 = dvbdmx->priv;
+       u16 *pid = dvbdmx->pids, npids[5];
+       int i;
+       int ret = 0;
+
+       dprintk(4, "%p\n", av7110);
+
+       npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
+       i = dvbdmxfeed->pes_type;
+       npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
+       if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
+               npids[i] = 0;
+               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+               if (!ret)
+                       ret = StartHWFilter(dvbdmxfeed->filter);
+               return ret;
+       }
+       if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
+               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+               if (ret)
+                       return ret;
+       }
+
+       if (dvbdmxfeed->pes_type < 2 && npids[0])
+               if (av7110->fe_synced)
+               {
+                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+                       if (ret)
+                               return ret;
+               }
+
+       if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) {
+               if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
+                       ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
+               if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
+                       ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
+       }
+       return ret;
+}
+
+static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct av7110 *av7110 = dvbdmx->priv;
+       u16 *pid = dvbdmx->pids, npids[5];
+       int i;
+
+       int ret = 0;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (dvbdmxfeed->pes_type <= 1) {
+               ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ?  RP_VIDEO : RP_AUDIO);
+               if (ret)
+                       return ret;
+               if (!av7110->rec_mode)
+                       dvbdmx->recording = 0;
+               if (!av7110->playing)
+                       dvbdmx->playing = 0;
+       }
+       npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
+       i = dvbdmxfeed->pes_type;
+       switch (i) {
+       case 2: //teletext
+               if (dvbdmxfeed->ts_type & TS_PACKET)
+                       ret = StopHWFilter(dvbdmxfeed->filter);
+               npids[2] = 0;
+               break;
+       case 0:
+       case 1:
+       case 4:
+               if (!pids_off)
+                       return 0;
+               npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
+               break;
+       }
+       if (!ret)
+               ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+       return ret;
+}
+
+static int av7110_start_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct av7110 *av7110 = demux->priv;
+       int ret = 0;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (!demux->dmx.frontend)
+               return -EINVAL;
+
+       if (!av7110->full_ts && feed->pid > 0x1fff)
+               return -EINVAL;
+
+       if (feed->type == DMX_TYPE_TS) {
+               if ((feed->ts_type & TS_DECODER) &&
+                   (feed->pes_type <= DMX_TS_PES_PCR)) {
+                       switch (demux->dmx.frontend->source) {
+                       case DMX_MEMORY_FE:
+                               if (feed->ts_type & TS_DECODER)
+                                      if (feed->pes_type < 2 &&
+                                          !(demux->pids[0] & 0x8000) &&
+                                          !(demux->pids[1] & 0x8000)) {
+                                              dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+                                              dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
+                                              ret = av7110_av_start_play(av7110,RP_AV);
+                                              if (!ret)
+                                                      demux->playing = 1;
+                                       }
+                               break;
+                       default:
+                               ret = dvb_feed_start_pid(feed);
+                               break;
+                       }
+               } else if ((feed->ts_type & TS_PACKET) &&
+                          (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
+                       ret = StartHWFilter(feed->filter);
+               }
+       }
+
+       if (av7110->full_ts) {
+               budget_start_feed(feed);
+               return ret;
+       }
+
+       if (feed->type == DMX_TYPE_SEC) {
+               int i;
+
+               for (i = 0; i < demux->filternum; i++) {
+                       if (demux->filter[i].state != DMX_STATE_READY)
+                               continue;
+                       if (demux->filter[i].type != DMX_TYPE_SEC)
+                               continue;
+                       if (demux->filter[i].filter.parent != &feed->feed.sec)
+                               continue;
+                       demux->filter[i].state = DMX_STATE_GO;
+                       if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+                               ret = StartHWFilter(&demux->filter[i]);
+                               if (ret)
+                                       break;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+
+static int av7110_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct av7110 *av7110 = demux->priv;
+       int i, rc, ret = 0;
+       dprintk(4, "%p\n", av7110);
+
+       if (feed->type == DMX_TYPE_TS) {
+               if (feed->ts_type & TS_DECODER) {
+                       if (feed->pes_type >= DMX_TS_PES_OTHER ||
+                           !demux->pesfilter[feed->pes_type])
+                               return -EINVAL;
+                       demux->pids[feed->pes_type] |= 0x8000;
+                       demux->pesfilter[feed->pes_type] = NULL;
+               }
+               if (feed->ts_type & TS_DECODER &&
+                   feed->pes_type < DMX_TS_PES_OTHER) {
+                       ret = dvb_feed_stop_pid(feed);
+               } else
+                       if ((feed->ts_type & TS_PACKET) &&
+                           (demux->dmx.frontend->source != DMX_MEMORY_FE))
+                               ret = StopHWFilter(feed->filter);
+       }
+
+       if (av7110->full_ts) {
+               budget_stop_feed(feed);
+               return ret;
+       }
+
+       if (feed->type == DMX_TYPE_SEC) {
+               for (i = 0; i<demux->filternum; i++) {
+                       if (demux->filter[i].state == DMX_STATE_GO &&
+                           demux->filter[i].filter.parent == &feed->feed.sec) {
+                               demux->filter[i].state = DMX_STATE_READY;
+                               if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+                                       rc = StopHWFilter(&demux->filter[i]);
+                                       if (!ret)
+                                               ret = rc;
+                                       /* keep going, stop as many filters as possible */
+                               }
+                       }
+               }
+       }
+
+       return ret;
+}
+
+
+static void restart_feeds(struct av7110 *av7110)
+{
+       struct dvb_demux *dvbdmx = &av7110->demux;
+       struct dvb_demux_feed *feed;
+       int mode;
+       int feeding;
+       int i, j;
+
+       dprintk(4, "%p\n", av7110);
+
+       mode = av7110->playing;
+       av7110->playing = 0;
+       av7110->rec_mode = 0;
+
+       feeding = av7110->feeding1; /* full_ts mod */
+
+       for (i = 0; i < dvbdmx->feednum; i++) {
+               feed = &dvbdmx->feed[i];
+               if (feed->state == DMX_STATE_GO) {
+                       if (feed->type == DMX_TYPE_SEC) {
+                               for (j = 0; j < dvbdmx->filternum; j++) {
+                                       if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
+                                               continue;
+                                       if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
+                                               continue;
+                                       if (dvbdmx->filter[j].state == DMX_STATE_GO)
+                                               dvbdmx->filter[j].state = DMX_STATE_READY;
+                               }
+                       }
+                       av7110_start_feed(feed);
+               }
+       }
+
+       av7110->feeding1 = feeding; /* full_ts mod */
+
+       if (mode)
+               av7110_av_start_play(av7110, mode);
+}
+
+static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
+                      uint64_t *stc, unsigned int *base)
+{
+       int ret;
+       u16 fwstc[4];
+       u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
+       struct dvb_demux *dvbdemux;
+       struct av7110 *av7110;
+
+       /* pointer casting paranoia... */
+       BUG_ON(!demux);
+       dvbdemux = demux->priv;
+       BUG_ON(!dvbdemux);
+       av7110 = dvbdemux->priv;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (num != 0)
+               return -EINVAL;
+
+       ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
+       if (ret) {
+               printk(KERN_ERR "%s: av7110_fw_request error\n", __func__);
+               return ret;
+       }
+       dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
+               fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
+
+       *stc =  (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
+               (((uint64_t)  fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
+       *base = 1;
+
+       dprintk(4, "stc = %lu\n", (unsigned long)*stc);
+
+       return 0;
+}
+
+
+/******************************************************************************
+ * SEC device file operations
+ ******************************************************************************/
+
+
+static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               return Set22K(av7110, 1);
+
+       case SEC_TONE_OFF:
+               return Set22K(av7110, 0);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
+                                        struct dvb_diseqc_master_cmd* cmd)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
+}
+
+static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
+                                   fe_sec_mini_cmd_t minicmd)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       return av7110_diseqc_send(av7110, 0, NULL, minicmd);
+}
+
+/* simplified code from budget-core.c */
+static int stop_ts_capture(struct av7110 *budget)
+{
+       dprintk(2, "budget: %p\n", budget);
+
+       if (--budget->feeding1)
+               return budget->feeding1;
+       saa7146_write(budget->dev, MC1, MASK_20);       /* DMA3 off */
+       SAA7146_IER_DISABLE(budget->dev, MASK_10);
+       SAA7146_ISR_CLEAR(budget->dev, MASK_10);
+       return 0;
+}
+
+static int start_ts_capture(struct av7110 *budget)
+{
+       dprintk(2, "budget: %p\n", budget);
+
+       if (budget->feeding1)
+               return ++budget->feeding1;
+       memset(budget->grabbing, 0x00, TS_BUFLEN);
+       budget->ttbp = 0;
+       SAA7146_ISR_CLEAR(budget->dev, MASK_10);  /* VPE */
+       SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
+       saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
+       return ++budget->feeding1;
+}
+
+static int budget_start_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct av7110 *budget = demux->priv;
+       int status;
+
+       dprintk(2, "av7110: %p\n", budget);
+
+       spin_lock(&budget->feedlock1);
+       feed->pusi_seen = 0; /* have a clean section start */
+       status = start_ts_capture(budget);
+       spin_unlock(&budget->feedlock1);
+       return status;
+}
+
+static int budget_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct av7110 *budget = demux->priv;
+       int status;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       spin_lock(&budget->feedlock1);
+       status = stop_ts_capture(budget);
+       spin_unlock(&budget->feedlock1);
+       return status;
+}
+
+static void vpeirq(unsigned long cookie)
+{
+       struct av7110 *budget = (struct av7110 *)cookie;
+       u8 *mem = (u8 *) (budget->grabbing);
+       u32 olddma = budget->ttbp;
+       u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
+       struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1;
+
+       /* nearest lower position divisible by 188 */
+       newdma -= newdma % 188;
+
+       if (newdma >= TS_BUFLEN)
+               return;
+
+       budget->ttbp = newdma;
+
+       if (!budget->feeding1 || (newdma == olddma))
+               return;
+
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
+#if 0
+       /* track rps1 activity */
+       printk("vpeirq: %02x Event Counter 1 0x%04x\n",
+              mem[olddma],
+              saa7146_read(budget->dev, EC1R) & 0x3fff);
+#endif
+
+       if (newdma > olddma)
+               /* no wraparound, dump olddma..newdma */
+               dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188);
+       else {
+               /* wraparound, dump olddma..buflen and 0..newdma */
+               dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
+               dvb_dmx_swfilter_packets(demux, mem, newdma / 188);
+       }
+}
+
+static int av7110_register(struct av7110 *av7110)
+{
+       int ret, i;
+       struct dvb_demux *dvbdemux = &av7110->demux;
+       struct dvb_demux *dvbdemux1 = &av7110->demux1;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (av7110->registered)
+               return -1;
+
+       av7110->registered = 1;
+
+       dvbdemux->priv = (void *) av7110;
+
+       for (i = 0; i < 32; i++)
+               av7110->handle2filter[i] = NULL;
+
+       dvbdemux->filternum = (av7110->full_ts) ? 256 : 32;
+       dvbdemux->feednum = (av7110->full_ts) ? 256 : 32;
+       dvbdemux->start_feed = av7110_start_feed;
+       dvbdemux->stop_feed = av7110_stop_feed;
+       dvbdemux->write_to_decoder = av7110_write_to_decoder;
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+                                     DMX_MEMORY_BASED_FILTERING);
+
+       dvb_dmx_init(&av7110->demux);
+       av7110->demux.dmx.get_stc = dvb_get_stc;
+
+       av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32;
+       av7110->dmxdev.demux = &dvbdemux->dmx;
+       av7110->dmxdev.capabilities = 0;
+
+       dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
+
+       av7110->hw_frontend.source = DMX_FRONTEND_0;
+
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
+
+       if (ret < 0)
+               return ret;
+
+       av7110->mem_frontend.source = DMX_MEMORY_FE;
+
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
+
+       if (ret < 0)
+               return ret;
+
+       ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
+                                            &av7110->hw_frontend);
+       if (ret < 0)
+               return ret;
+
+       av7110_av_register(av7110);
+       av7110_ca_register(av7110);
+
+#ifdef CONFIG_DVB_AV7110_OSD
+       dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
+                           &dvbdev_osd, av7110, DVB_DEVICE_OSD);
+#endif
+
+       dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
+
+       if (budgetpatch) {
+               /* initialize software demux1 without its own frontend
+                * demux1 hardware is connected to frontend0 of demux0
+                */
+               dvbdemux1->priv = (void *) av7110;
+
+               dvbdemux1->filternum = 256;
+               dvbdemux1->feednum = 256;
+               dvbdemux1->start_feed = budget_start_feed;
+               dvbdemux1->stop_feed = budget_stop_feed;
+               dvbdemux1->write_to_decoder = NULL;
+
+               dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+                                              DMX_MEMORY_BASED_FILTERING);
+
+               dvb_dmx_init(&av7110->demux1);
+
+               av7110->dmxdev1.filternum = 256;
+               av7110->dmxdev1.demux = &dvbdemux1->dmx;
+               av7110->dmxdev1.capabilities = 0;
+
+               dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
+
+               dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
+               printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
+       }
+       return 0;
+}
+
+
+static void dvb_unregister(struct av7110 *av7110)
+{
+       struct dvb_demux *dvbdemux = &av7110->demux;
+       struct dvb_demux *dvbdemux1 = &av7110->demux1;
+
+       dprintk(4, "%p\n", av7110);
+
+       if (!av7110->registered)
+               return;
+
+       if (budgetpatch) {
+               dvb_net_release(&av7110->dvb_net1);
+               dvbdemux->dmx.close(&dvbdemux1->dmx);
+               dvb_dmxdev_release(&av7110->dmxdev1);
+               dvb_dmx_release(&av7110->demux1);
+       }
+
+       dvb_net_release(&av7110->dvb_net);
+
+       dvbdemux->dmx.close(&dvbdemux->dmx);
+       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
+       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
+
+       dvb_dmxdev_release(&av7110->dmxdev);
+       dvb_dmx_release(&av7110->demux);
+
+       if (av7110->fe != NULL) {
+               dvb_unregister_frontend(av7110->fe);
+               dvb_frontend_detach(av7110->fe);
+       }
+       dvb_unregister_device(av7110->osd_dev);
+       av7110_av_unregister(av7110);
+       av7110_ca_unregister(av7110);
+}
+
+
+/****************************************************************************
+ * I2C client commands
+ ****************************************************************************/
+
+int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
+{
+       u8 msg[2] = { reg, val };
+       struct i2c_msg msgs;
+
+       msgs.flags = 0;
+       msgs.addr = id / 2;
+       msgs.len = 2;
+       msgs.buf = msg;
+       return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
+}
+
+u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
+{
+       u8 mm1[] = {0x00};
+       u8 mm2[] = {0x00};
+       struct i2c_msg msgs[2];
+
+       msgs[0].flags = 0;
+       msgs[1].flags = I2C_M_RD;
+       msgs[0].addr = msgs[1].addr = id / 2;
+       mm1[0] = reg;
+       msgs[0].len = 1; msgs[1].len = 1;
+       msgs[0].buf = mm1; msgs[1].buf = mm2;
+       i2c_transfer(&av7110->i2c_adap, msgs, 2);
+
+       return mm2[0];
+}
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+
+static int check_firmware(struct av7110* av7110)
+{
+       u32 crc = 0, len = 0;
+       unsigned char *ptr;
+
+       /* check for firmware magic */
+       ptr = av7110->bin_fw;
+       if (ptr[0] != 'A' || ptr[1] != 'V' ||
+           ptr[2] != 'F' || ptr[3] != 'W') {
+               printk("dvb-ttpci: this is not an av7110 firmware\n");
+               return -EINVAL;
+       }
+       ptr += 4;
+
+       /* check dpram file */
+       crc = get_unaligned_be32(ptr);
+       ptr += 4;
+       len = get_unaligned_be32(ptr);
+       ptr += 4;
+       if (len >= 512) {
+               printk("dvb-ttpci: dpram file is way too big.\n");
+               return -EINVAL;
+       }
+       if (crc != crc32_le(0, ptr, len)) {
+               printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+               return -EINVAL;
+       }
+       av7110->bin_dpram = ptr;
+       av7110->size_dpram = len;
+       ptr += len;
+
+       /* check root file */
+       crc = get_unaligned_be32(ptr);
+       ptr += 4;
+       len = get_unaligned_be32(ptr);
+       ptr += 4;
+
+       if (len <= 200000 || len >= 300000 ||
+           len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
+               printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
+               return -EINVAL;
+       }
+       if( crc != crc32_le(0, ptr, len)) {
+               printk("dvb-ttpci: crc32 of root file does not match.\n");
+               return -EINVAL;
+       }
+       av7110->bin_root = ptr;
+       av7110->size_root = len;
+       return 0;
+}
+
+static void put_firmware(struct av7110* av7110)
+{
+       vfree(av7110->bin_fw);
+}
+
+static int get_firmware(struct av7110* av7110)
+{
+       int ret;
+       const struct firmware *fw;
+
+       /* request the av7110 firmware, this will block until someone uploads it */
+       ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
+       if (ret) {
+               if (ret == -ENOENT) {
+                       printk(KERN_ERR "dvb-ttpci: could not load firmware,"
+                              " file not found: dvb-ttpci-01.fw\n");
+                       printk(KERN_ERR "dvb-ttpci: usually this should be in "
+                              "/usr/lib/hotplug/firmware or /lib/firmware\n");
+                       printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
+                              " http://www.linuxtv.org/download/dvb/firmware/\n");
+               } else
+                       printk(KERN_ERR "dvb-ttpci: cannot request firmware"
+                              " (error %i)\n", ret);
+               return -EINVAL;
+       }
+
+       if (fw->size <= 200000) {
+               printk("dvb-ttpci: this firmware is way too small.\n");
+               release_firmware(fw);
+               return -EINVAL;
+       }
+
+       /* check if the firmware is available */
+       av7110->bin_fw = vmalloc(fw->size);
+       if (NULL == av7110->bin_fw) {
+               dprintk(1, "out of memory\n");
+               release_firmware(fw);
+               return -ENOMEM;
+       }
+
+       memcpy(av7110->bin_fw, fw->data, fw->size);
+       av7110->size_fw = fw->size;
+       if ((ret = check_firmware(av7110)))
+               vfree(av7110->bin_fw);
+
+       release_firmware(fw);
+       return ret;
+}
+
+static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u8 pwr = 0;
+       u8 buf[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       u32 div = (p->frequency + 479500) / 125;
+
+       if (p->frequency > 2000000)
+               pwr = 3;
+       else if (p->frequency > 1800000)
+               pwr = 2;
+       else if (p->frequency > 1600000)
+               pwr = 1;
+       else if (p->frequency > 1200000)
+               pwr = 0;
+       else if (p->frequency >= 1100000)
+               pwr = 1;
+       else
+               pwr = 2;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = ((div & 0x18000) >> 10) | 0x95;
+       buf[3] = (pwr << 6) | 0x30;
+
+       // NOTE: since we're using a prescaler of 2, we set the
+       // divisor frequency to 62.5kHz and divide by 125 above
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct ves1x93_config alps_bsrv2_config = {
+       .demod_address = 0x08,
+       .xin = 90100000UL,
+       .invert_pwm = 0,
+};
+
+static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (p->frequency + 35937500 + 31250) / 62500;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x85 | ((div >> 10) & 0x60);
+       data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct ves1820_config alps_tdbe2_config = {
+       .demod_address = 0x09,
+       .xin = 57840000UL,
+       .invert = 1,
+       .selagc = VES1820_SELAGC_SIGNAMPERR,
+};
+
+
+
+
+static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = p->frequency / 125;
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x8e;
+       data[3] = 0x00;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct tda8083_config grundig_29504_451_config = {
+       .demod_address = 0x68,
+};
+
+
+
+static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div;
+       u32 f = p->frequency;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (f + 36125000 + 31250) / 62500;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x8e;
+       data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct ves1820_config philips_cd1516_config = {
+       .demod_address = 0x09,
+       .xin = 57840000UL,
+       .invert = 1,
+       .selagc = VES1820_SELAGC_SIGNAMPERR,
+};
+
+
+
+static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div, pwr;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (p->frequency + 36200000) / 166666;
+
+       if (p->frequency <= 782000000)
+               pwr = 1;
+       else
+               pwr = 2;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x85;
+       data[3] = pwr << 6;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
+       struct av7110* av7110 = fe->dvb->priv;
+
+       return request_firmware(fw, name, &av7110->dev->pci->dev);
+#else
+       return -EINVAL;
+#endif
+}
+
+static struct sp8870_config alps_tdlb7_config = {
+
+       .demod_address = 0x71,
+       .request_firmware = alps_tdlb7_request_firmware,
+};
+
+
+static u8 nexusca_stv0297_inittab[] = {
+       0x80, 0x01,
+       0x80, 0x00,
+       0x81, 0x01,
+       0x81, 0x00,
+       0x00, 0x09,
+       0x01, 0x69,
+       0x03, 0x00,
+       0x04, 0x00,
+       0x07, 0x00,
+       0x08, 0x00,
+       0x20, 0x00,
+       0x21, 0x40,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x24, 0x40,
+       0x25, 0x88,
+       0x30, 0xff,
+       0x31, 0x00,
+       0x32, 0xff,
+       0x33, 0x00,
+       0x34, 0x50,
+       0x35, 0x7f,
+       0x36, 0x00,
+       0x37, 0x20,
+       0x38, 0x00,
+       0x40, 0x1c,
+       0x41, 0xff,
+       0x42, 0x29,
+       0x43, 0x00,
+       0x44, 0xff,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x49, 0x04,
+       0x4a, 0x00,
+       0x4b, 0x7b,
+       0x52, 0x30,
+       0x55, 0xae,
+       0x56, 0x47,
+       0x57, 0xe1,
+       0x58, 0x3a,
+       0x5a, 0x1e,
+       0x5b, 0x34,
+       0x60, 0x00,
+       0x63, 0x00,
+       0x64, 0x00,
+       0x65, 0x00,
+       0x66, 0x00,
+       0x67, 0x00,
+       0x68, 0x00,
+       0x69, 0x00,
+       0x6a, 0x02,
+       0x6b, 0x00,
+       0x70, 0xff,
+       0x71, 0x00,
+       0x72, 0x00,
+       0x73, 0x00,
+       0x74, 0x0c,
+       0x80, 0x00,
+       0x81, 0x00,
+       0x82, 0x00,
+       0x83, 0x00,
+       0x84, 0x04,
+       0x85, 0x80,
+       0x86, 0x24,
+       0x87, 0x78,
+       0x88, 0x10,
+       0x89, 0x00,
+       0x90, 0x01,
+       0x91, 0x01,
+       0xa0, 0x04,
+       0xa1, 0x00,
+       0xa2, 0x00,
+       0xb0, 0x91,
+       0xb1, 0x0b,
+       0xc0, 0x53,
+       0xc1, 0x70,
+       0xc2, 0x12,
+       0xd0, 0x00,
+       0xd1, 0x00,
+       0xd2, 0x00,
+       0xd3, 0x00,
+       0xd4, 0x00,
+       0xd5, 0x00,
+       0xde, 0x00,
+       0xdf, 0x00,
+       0x61, 0x49,
+       0x62, 0x0b,
+       0x53, 0x08,
+       0x59, 0x08,
+       0xff, 0xff,
+};
+
+static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
+       struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
+       int i;
+
+       div = (p->frequency + 36150000 + 31250) / 62500;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0xce;
+
+       if (p->frequency < 45000000)
+               return -EINVAL;
+       else if (p->frequency < 137000000)
+               data[3] = 0x01;
+       else if (p->frequency < 403000000)
+               data[3] = 0x02;
+       else if (p->frequency < 860000000)
+               data[3] = 0x04;
+       else
+               return -EINVAL;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
+               printk("nexusca: pll transfer failed!\n");
+               return -EIO;
+       }
+
+       // wait for PLL lock
+       for(i = 0; i < 20; i++) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
+                       if (data[0] & 0x40) break;
+               msleep(10);
+       }
+
+       return 0;
+}
+
+static struct stv0297_config nexusca_stv0297_config = {
+
+       .demod_address = 0x1C,
+       .inittab = nexusca_stv0297_inittab,
+       .invert = 1,
+       .stop_during_read = 1,
+};
+
+
+
+static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct av7110* av7110 = fe->dvb->priv;
+       u32 div;
+       u8 cfg, cpump, band_select;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (36125000 + p->frequency) / 166666;
+
+       cfg = 0x88;
+
+       if (p->frequency < 175000000)
+               cpump = 2;
+       else if (p->frequency < 390000000)
+               cpump = 1;
+       else if (p->frequency < 470000000)
+               cpump = 2;
+       else if (p->frequency < 750000000)
+               cpump = 1;
+       else
+               cpump = 3;
+
+       if (p->frequency < 175000000)
+               band_select = 0x0e;
+       else if (p->frequency < 470000000)
+               band_select = 0x05;
+       else
+               band_select = 0x03;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = ((div >> 10) & 0x60) | cfg;
+       data[3] = (cpump << 6) | band_select;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct l64781_config grundig_29504_401_config = {
+       .demod_address = 0x55,
+};
+
+
+
+static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
+{
+       int ret = 0;
+       int synced = (status & FE_HAS_LOCK) ? 1 : 0;
+
+       av7110->fe_status = status;
+
+       if (av7110->fe_synced == synced)
+               return 0;
+
+       if (av7110->playing) {
+               av7110->fe_synced = synced;
+               return 0;
+       }
+
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
+               return -ERESTARTSYS;
+
+       if (synced) {
+               ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+                       av7110->pids[DMX_PES_AUDIO],
+                       av7110->pids[DMX_PES_TELETEXT], 0,
+                       av7110->pids[DMX_PES_PCR]);
+               if (!ret)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+       } else {
+               ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
+               if (!ret) {
+                       ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
+                       if (!ret)
+                               ret = av7110_wait_msgstate(av7110, GPMQBusy);
+               }
+       }
+
+       if (!ret)
+               av7110->fe_synced = synced;
+
+       mutex_unlock(&av7110->pid_mutex);
+       return ret;
+}
+
+static int av7110_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret)
+               ret = av7110->fe_set_frontend(fe);
+
+       return ret;
+}
+
+static int av7110_fe_init(struct dvb_frontend* fe)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret)
+               ret = av7110->fe_init(fe);
+       return ret;
+}
+
+static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       /* call the real implementation */
+       int ret = av7110->fe_read_status(fe, status);
+       if (!ret)
+               if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
+                       ret = av7110_fe_lock_fix(av7110, *status);
+       return ret;
+}
+
+static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret)
+               ret = av7110->fe_diseqc_reset_overload(fe);
+       return ret;
+}
+
+static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
+                                           struct dvb_diseqc_master_cmd* cmd)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret) {
+               av7110->saved_master_cmd = *cmd;
+               ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
+       }
+       return ret;
+}
+
+static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret) {
+               av7110->saved_minicmd = minicmd;
+               ret = av7110->fe_diseqc_send_burst(fe, minicmd);
+       }
+       return ret;
+}
+
+static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret) {
+               av7110->saved_tone = tone;
+               ret = av7110->fe_set_tone(fe, tone);
+       }
+       return ret;
+}
+
+static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret) {
+               av7110->saved_voltage = voltage;
+               ret = av7110->fe_set_voltage(fe, voltage);
+       }
+       return ret;
+}
+
+static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
+{
+       struct av7110* av7110 = fe->dvb->priv;
+
+       int ret = av7110_fe_lock_fix(av7110, 0);
+       if (!ret)
+               ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
+       return ret;
+}
+
+static void dvb_s_recover(struct av7110* av7110)
+{
+       av7110_fe_init(av7110->fe);
+
+       av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
+       if (av7110->saved_master_cmd.msg_len) {
+               msleep(20);
+               av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
+       }
+       msleep(20);
+       av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
+       msleep(20);
+       av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
+
+       av7110_fe_set_frontend(av7110->fe);
+}
+
+static u8 read_pwm(struct av7110* av7110)
+{
+       u8 b = 0xff;
+       u8 pwm;
+       struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
+                                { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
+
+       if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+static int frontend_init(struct av7110 *av7110)
+{
+       int ret;
+
+       if (av7110->dev->pci->subsystem_vendor == 0x110a) {
+               switch(av7110->dev->pci->subsystem_device) {
+               case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
+                       av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config,
+                                                   &av7110->i2c_adap, read_pwm(av7110));
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
+                       }
+                       break;
+               }
+
+       } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
+               switch(av7110->dev->pci->subsystem_device) {
+               case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
+               case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
+               case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
+
+                       // try the ALPS BSRV2 first of all
+                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
+                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops.set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                               break;
+                       }
+
+                       // try the ALPS BSRU6 now
+                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
+                               av7110->fe->tuner_priv = &av7110->i2c_adap;
+
+                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops.set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                               break;
+                       }
+
+                       // Try the grundig 29504-451
+                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
+                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops.set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                               break;
+                       }
+
+                       /* Try DVB-C cards */
+                       switch(av7110->dev->pci->subsystem_device) {
+                       case 0x0000:
+                               /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
+                               av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap,
+                                                       read_pwm(av7110));
+                               if (av7110->fe) {
+                                       av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
+                               }
+                               break;
+                       case 0x0003:
+                               /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
+                               av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap,
+                                                       read_pwm(av7110));
+                               if (av7110->fe) {
+                                       av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
+                               }
+                               break;
+                       }
+                       break;
+
+               case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
+                       // try ALPS TDLB7 first, then Grundig 29504-401
+                       av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params;
+                               break;
+                       }
+                       /* fall-thru */
+
+               case 0x0008: // Hauppauge/TT DVB-T
+                       // Grundig 29504-401
+                       av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap);
+                       if (av7110->fe)
+                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+                       break;
+
+               case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
+
+                       av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
+                       }
+                       break;
+
+               case 0x0004: // Galaxis DVB-S rev1.3
+                       /* ALPS BSRV2 */
+                       av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
+                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops.set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                       }
+                       break;
+
+               case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
+                       /* Grundig 29504-451 */
+                       av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
+                               av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops.set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                       }
+                       break;
+
+               case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
+
+                       av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params;
+
+                               /* set TDA9819 into DVB mode */
+                               saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
+                               saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
+
+                               /* tuner on this needs a slower i2c bus speed */
+                               av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
+                               break;
+                       }
+                       break;
+
+               case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
+                       /* ALPS BSBE1 */
+                       av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
+                               av7110->fe->tuner_priv = &av7110->i2c_adap;
+
+                               if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) {
+                                       printk("dvb-ttpci: LNBP21 not found!\n");
+                                       if (av7110->fe->ops.release)
+                                               av7110->fe->ops.release(av7110->fe);
+                                       av7110->fe = NULL;
+                               } else {
+                                       av7110->fe->ops.dishnetwork_send_legacy_command = NULL;
+                                       av7110->recover = dvb_s_recover;
+                               }
+                       }
+                       break;
+               }
+       }
+
+       if (!av7110->fe) {
+               /* FIXME: propagate the failure code from the lower layers */
+               ret = -ENOMEM;
+               printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      av7110->dev->pci->vendor,
+                      av7110->dev->pci->device,
+                      av7110->dev->pci->subsystem_vendor,
+                      av7110->dev->pci->subsystem_device);
+       } else {
+               FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
+               FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
+
+               ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
+               if (ret < 0) {
+                       printk("av7110: Frontend registration failed!\n");
+                       dvb_frontend_detach(av7110->fe);
+                       av7110->fe = NULL;
+               }
+       }
+       return ret;
+}
+
+/* Budgetpatch note:
+ * Original hardware design by Roberto Deza:
+ * There is a DVB_Wiki at
+ * http://www.linuxtv.org/
+ *
+ * New software triggering design by Emard that works on
+ * original Roberto Deza's hardware:
+ *
+ * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
+ * GPIO3 is in budget-patch hardware connectd to port B VSYNC
+ * HS is an internal event of 7146, accessible with RPS
+ * and temporarily raised high every n lines
+ * (n in defined in the RPS_THRESH1 counter threshold)
+ * I think HS is raised high on the beginning of the n-th line
+ * and remains high until this n-th line that triggered
+ * it is completely received. When the receiption of n-th line
+ * ends, HS is lowered.
+ *
+ * To transmit data over DMA, 7146 needs changing state at
+ * port B VSYNC pin. Any changing of port B VSYNC will
+ * cause some DMA data transfer, with more or less packets loss.
+ * It depends on the phase and frequency of VSYNC and
+ * the way of 7146 is instructed to trigger on port B (defined
+ * in DD1_INIT register, 3rd nibble from the right valid
+ * numbers are 0-7, see datasheet)
+ *
+ * The correct triggering can minimize packet loss,
+ * dvbtraffic should give this stable bandwidths:
+ *   22k transponder = 33814 kbit/s
+ * 27.5k transponder = 38045 kbit/s
+ * by experiment it is found that the best results
+ * (stable bandwidths and almost no packet loss)
+ * are obtained using DD1_INIT triggering number 2
+ * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
+ * and a VSYNC phase that occurs in the middle of DMA transfer
+ * (about byte 188*512=96256 in the DMA window).
+ *
+ * Phase of HS is still not clear to me how to control,
+ * It just happens to be so. It can be seen if one enables
+ * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
+ * time RPS_INTERRUPT is called, the Event Counter 1 will
+ * increment. That's how the 7146 is programmed to do event
+ * counting in this budget-patch.c
+ * I *think* HPS setting has something to do with the phase
+ * of HS but I can't be 100% sure in that.
+ *
+ * hardware debug note: a working budget card (including budget patch)
+ * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
+ * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
+ * and that means 3*25=75 Hz of interrupt freqency, as seen by
+ * watch cat /proc/interrupts
+ *
+ * If this frequency is 3x lower (and data received in the DMA
+ * buffer don't start with 0x47, but in the middle of packets,
+ * whose lengths appear to be like 188 292 188 104 etc.
+ * this means VSYNC line is not connected in the hardware.
+ * (check soldering pcb and pins)
+ * The same behaviour of missing VSYNC can be duplicated on budget
+ * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
+ */
+static int __devinit av7110_attach(struct saa7146_dev* dev,
+                                  struct saa7146_pci_extension_data *pci_ext)
+{
+       const int length = TS_WIDTH * TS_HEIGHT;
+       struct pci_dev *pdev = dev->pci;
+       struct av7110 *av7110;
+       struct task_struct *thread;
+       int ret, count = 0;
+
+       dprintk(4, "dev: %p\n", dev);
+
+       /* Set RPS_IRQ to 1 to track rps1 activity.
+        * Enabling this won't send any interrupt to PC CPU.
+        */
+#define RPS_IRQ 0
+
+       if (budgetpatch == 1) {
+               budgetpatch = 0;
+               /* autodetect the presence of budget patch
+                * this only works if saa7146 has been recently
+                * reset with with MASK_31 to MC1
+                *
+                * will wait for VBI_B event (vertical blank at port B)
+                * and will reset GPIO3 after VBI_B is detected.
+                * (GPIO3 should be raised high by CPU to
+                * test if GPIO3 will generate vertical blank signal
+                * in budget patch GPIO3 is connected to VSYNC_B
+                */
+
+               /* RESET SAA7146 */
+               saa7146_write(dev, MC1, MASK_31);
+               /* autodetection success seems to be time-dependend after reset */
+
+               /* Fix VSYNC level */
+               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+               /* set vsync_b triggering */
+               saa7146_write(dev, DD1_STREAM_B, 0);
+               /* port B VSYNC at rising edge */
+               saa7146_write(dev, DD1_INIT, 0x00000200);
+               saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
+               saa7146_write(dev, MC2,
+                             1 * (MASK_08 | MASK_24)  |   // BRS control
+                             0 * (MASK_09 | MASK_25)  |   // a
+                             1 * (MASK_10 | MASK_26)  |   // b
+                             0 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
+                             0 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
+                             0 * (MASK_01 | MASK_15)      // DEBI
+               );
+
+               /* start writing RPS1 code from beginning */
+               count = 0;
+               /* Disable RPS1 */
+               saa7146_write(dev, MC1, MASK_29);
+               /* RPS1 timeout disable */
+               saa7146_write(dev, RPS_TOV1, 0);
+               WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
+               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+               WRITE_RPS1(GPIO3_MSK);
+               WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+#if RPS_IRQ
+               /* issue RPS1 interrupt to increment counter */
+               WRITE_RPS1(CMD_INTERRUPT);
+#endif
+               WRITE_RPS1(CMD_STOP);
+               /* Jump to begin of RPS program as safety measure               (p37) */
+               WRITE_RPS1(CMD_JUMP);
+               WRITE_RPS1(dev->d_rps1.dma_handle);
+
+#if RPS_IRQ
+               /* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+                * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+                * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+                */
+               saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+               /* set event counter 1 threshold to maximum allowed value        (rEC p55) */
+               saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+               /* Set RPS1 Address register to point to RPS code               (r108 p42) */
+               saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+               /* Enable RPS1,                                                 (rFC p33) */
+               saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
+
+               mdelay(10);
+               /* now send VSYNC_B to rps1 by rising GPIO3 */
+               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+               mdelay(10);
+               /* if rps1 responded by lowering the GPIO3,
+                * then we have budgetpatch hardware
+                */
+               if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
+                       budgetpatch = 1;
+                       printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
+               }
+               /* Disable RPS1 */
+               saa7146_write(dev, MC1, ( MASK_29 ));
+#if RPS_IRQ
+               printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+#endif
+       }
+
+       /* prepare the av7110 device struct */
+       av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
+       if (!av7110) {
+               dprintk(1, "out of memory\n");
+               return -ENOMEM;
+       }
+
+       av7110->card_name = (char*) pci_ext->ext_priv;
+       av7110->dev = dev;
+       dev->ext_priv = av7110;
+
+       ret = get_firmware(av7110);
+       if (ret < 0)
+               goto err_kfree_0;
+
+       ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
+                                  THIS_MODULE, &dev->pci->dev, adapter_nr);
+       if (ret < 0)
+               goto err_put_firmware_1;
+
+       /* the Siemens DVB needs this if you want to have the i2c chips
+          get recognized before the main driver is fully loaded */
+       saa7146_write(dev, GPIO_CTRL, 0x500000);
+
+       strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
+
+       saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
+
+       ret = i2c_add_adapter(&av7110->i2c_adap);
+       if (ret < 0)
+               goto err_dvb_unregister_adapter_2;
+
+       ttpci_eeprom_parse_mac(&av7110->i2c_adap,
+                              av7110->dvb_adapter.proposed_mac);
+       ret = -ENOMEM;
+
+       /* full-ts mod? */
+       if (full_ts)
+               av7110->full_ts = true;
+
+       /* check for full-ts flag in eeprom */
+       if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) {
+               u8 flags = i2c_readreg(av7110, 0xaa, 2);
+               if (flags != 0xff && (flags & 0x01))
+                       av7110->full_ts = true;
+       }
+
+       if (av7110->full_ts) {
+               printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n");
+               spin_lock_init(&av7110->feedlock1);
+               av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
+                                                                &av7110->pt);
+               if (!av7110->grabbing)
+                       goto err_i2c_del_3;
+
+               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+               saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+
+               saa7146_write(dev, DD1_INIT, 0x00000600);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+               saa7146_write(dev, BRS_CTRL, 0x60000000);
+               saa7146_write(dev, MC2, MASK_08 | MASK_24);
+
+               /* dma3 */
+               saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
+               saa7146_write(dev, BASE_ODD3, 0);
+               saa7146_write(dev, BASE_EVEN3, 0);
+               saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
+               saa7146_write(dev, PITCH3, TS_WIDTH);
+               saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
+               saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
+               saa7146_write(dev, MC2, MASK_04 | MASK_20);
+
+               tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
+
+       } else if (budgetpatch) {
+               spin_lock_init(&av7110->feedlock1);
+               av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
+                                                                &av7110->pt);
+               if (!av7110->grabbing)
+                       goto err_i2c_del_3;
+
+               saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
+               saa7146_write(dev, BCS_CTRL, 0x80400040);
+               /* set dd1 stream a & b */
+               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+               saa7146_write(dev, DD1_INIT, 0x03000200);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+               saa7146_write(dev, BRS_CTRL, 0x60000000);
+               saa7146_write(dev, BASE_ODD3, 0);
+               saa7146_write(dev, BASE_EVEN3, 0);
+               saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
+               saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
+
+               saa7146_write(dev, PITCH3, TS_WIDTH);
+               saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
+
+               /* upload all */
+               saa7146_write(dev, MC2, 0x077c077c);
+               saa7146_write(dev, GPIO_CTRL, 0x000000);
+#if RPS_IRQ
+               /* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+                * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+                * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+                */
+               saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+               /* set event counter 1 threshold to maximum allowed value        (rEC p55) */
+               saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+               /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
+               count = 0;
+
+               /* Wait Source Line Counter Threshold                           (p36) */
+               WRITE_RPS1(CMD_PAUSE | EVT_HS);
+               /* Set GPIO3=1                                                  (p42) */
+               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+               WRITE_RPS1(GPIO3_MSK);
+               WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
+#if RPS_IRQ
+               /* issue RPS1 interrupt */
+               WRITE_RPS1(CMD_INTERRUPT);
+#endif
+               /* Wait reset Source Line Counter Threshold                     (p36) */
+               WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
+               /* Set GPIO3=0                                                  (p42) */
+               WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+               WRITE_RPS1(GPIO3_MSK);
+               WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+#if RPS_IRQ
+               /* issue RPS1 interrupt */
+               WRITE_RPS1(CMD_INTERRUPT);
+#endif
+               /* Jump to begin of RPS program                                 (p37) */
+               WRITE_RPS1(CMD_JUMP);
+               WRITE_RPS1(dev->d_rps1.dma_handle);
+
+               /* Fix VSYNC level */
+               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+               /* Set RPS1 Address register to point to RPS code               (r108 p42) */
+               saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+               /* Set Source Line Counter Threshold, using BRS                 (rCC p43)
+                * It generates HS event every TS_HEIGHT lines
+                * this is related to TS_WIDTH set in register
+                * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
+                * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
+                * then RPS_THRESH1 should be set to trigger
+                * every TS_HEIGHT (512) lines.
+                */
+               saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+
+               /* Enable RPS1                                                  (rFC p33) */
+               saa7146_write(dev, MC1, (MASK_13 | MASK_29));
+
+               /* end of budgetpatch register initialization */
+               tasklet_init (&av7110->vpe_tasklet,  vpeirq,  (unsigned long) av7110);
+       } else {
+               saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
+               saa7146_write(dev, BCS_CTRL, 0x80400040);
+
+               /* set dd1 stream a & b */
+               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+               saa7146_write(dev, DD1_INIT, 0x03000000);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+               /* upload all */
+               saa7146_write(dev, MC2, 0x077c077c);
+               saa7146_write(dev, GPIO_CTRL, 0x000000);
+       }
+
+       tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
+       tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
+
+       mutex_init(&av7110->pid_mutex);
+
+       /* locks for data transfers from/to AV7110 */
+       spin_lock_init(&av7110->debilock);
+       mutex_init(&av7110->dcomlock);
+       av7110->debitype = -1;
+
+       /* default OSD window */
+       av7110->osdwin = 1;
+       mutex_init(&av7110->osd_mutex);
+
+       /* TV standard */
+       av7110->vidmode = tv_standard == 1 ? AV7110_VIDEO_MODE_NTSC
+                                          : AV7110_VIDEO_MODE_PAL;
+
+       /* ARM "watchdog" */
+       init_waitqueue_head(&av7110->arm_wait);
+       av7110->arm_thread = NULL;
+
+       /* allocate and init buffers */
+       av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
+       if (!av7110->debi_virt)
+               goto err_saa71466_vfree_4;
+
+
+       av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
+       if (!av7110->iobuf)
+               goto err_pci_free_5;
+
+       ret = av7110_av_init(av7110);
+       if (ret < 0)
+               goto err_iobuf_vfree_6;
+
+       /* init BMP buffer */
+       av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
+       init_waitqueue_head(&av7110->bmpq);
+
+       ret = av7110_ca_init(av7110);
+       if (ret < 0)
+               goto err_av7110_av_exit_7;
+
+       /* load firmware into AV7110 cards */
+       ret = av7110_bootarm(av7110);
+       if (ret < 0)
+               goto err_av7110_ca_exit_8;
+
+       ret = av7110_firmversion(av7110);
+       if (ret < 0)
+               goto err_stop_arm_9;
+
+       if (FW_VERSION(av7110->arm_app)<0x2501)
+               printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
+                       "System might be unstable!\n", FW_VERSION(av7110->arm_app));
+
+       thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
+       if (IS_ERR(thread)) {
+               ret = PTR_ERR(thread);
+               goto err_stop_arm_9;
+       }
+       av7110->arm_thread = thread;
+
+       /* set initial volume in mixer struct */
+       av7110->mixer.volume_left  = volume;
+       av7110->mixer.volume_right = volume;
+
+       ret = av7110_register(av7110);
+       if (ret < 0)
+               goto err_arm_thread_stop_10;
+
+       init_av7110_av(av7110);
+
+       /* special case DVB-C: these cards have an analog tuner
+          plus need some special handling, so we have separate
+          saa7146_ext_vv data for these... */
+       ret = av7110_init_v4l(av7110);
+       if (ret < 0)
+               goto err_av7110_unregister_11;
+
+       av7110->dvb_adapter.priv = av7110;
+       ret = frontend_init(av7110);
+       if (ret < 0)
+               goto err_av7110_exit_v4l_12;
+
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+       av7110_ir_init(av7110);
+#endif
+       printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
+       av7110_num++;
+out:
+       return ret;
+
+err_av7110_exit_v4l_12:
+       av7110_exit_v4l(av7110);
+err_av7110_unregister_11:
+       dvb_unregister(av7110);
+err_arm_thread_stop_10:
+       av7110_arm_sync(av7110);
+err_stop_arm_9:
+       /* Nothing to do. Rejoice. */
+err_av7110_ca_exit_8:
+       av7110_ca_exit(av7110);
+err_av7110_av_exit_7:
+       av7110_av_exit(av7110);
+err_iobuf_vfree_6:
+       vfree(av7110->iobuf);
+err_pci_free_5:
+       pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
+err_saa71466_vfree_4:
+       if (av7110->grabbing)
+               saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
+err_i2c_del_3:
+       i2c_del_adapter(&av7110->i2c_adap);
+err_dvb_unregister_adapter_2:
+       dvb_unregister_adapter(&av7110->dvb_adapter);
+err_put_firmware_1:
+       put_firmware(av7110);
+err_kfree_0:
+       kfree(av7110);
+       goto out;
+}
+
+static int __devexit av7110_detach(struct saa7146_dev* saa)
+{
+       struct av7110 *av7110 = saa->ext_priv;
+       dprintk(4, "%p\n", av7110);
+
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+       av7110_ir_exit(av7110);
+#endif
+       if (budgetpatch || av7110->full_ts) {
+               if (budgetpatch) {
+                       /* Disable RPS1 */
+                       saa7146_write(saa, MC1, MASK_29);
+                       /* VSYNC LOW (inactive) */
+                       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+               }
+               saa7146_write(saa, MC1, MASK_20);       /* DMA3 off */
+               SAA7146_IER_DISABLE(saa, MASK_10);
+               SAA7146_ISR_CLEAR(saa, MASK_10);
+               msleep(50);
+               tasklet_kill(&av7110->vpe_tasklet);
+               saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
+       }
+       av7110_exit_v4l(av7110);
+
+       av7110_arm_sync(av7110);
+
+       tasklet_kill(&av7110->debi_tasklet);
+       tasklet_kill(&av7110->gpio_tasklet);
+
+       dvb_unregister(av7110);
+
+       SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
+       SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
+
+       av7110_ca_exit(av7110);
+       av7110_av_exit(av7110);
+
+       vfree(av7110->iobuf);
+       pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
+                           av7110->debi_bus);
+
+       i2c_del_adapter(&av7110->i2c_adap);
+
+       dvb_unregister_adapter (&av7110->dvb_adapter);
+
+       av7110_num--;
+
+       put_firmware(av7110);
+
+       kfree(av7110);
+
+       saa->ext_priv = NULL;
+
+       return 0;
+}
+
+
+static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
+{
+       struct av7110 *av7110 = dev->ext_priv;
+
+       //print_time("av7110_irq");
+
+       /* Note: Don't try to handle the DEBI error irq (MASK_18), in
+        * intel mode the timeout is asserted all the time...
+        */
+
+       if (*isr & MASK_19) {
+               //printk("av7110_irq: DEBI\n");
+               /* Note 1: The DEBI irq is level triggered: We must enable it
+                * only after we started a DMA xfer, and disable it here
+                * immediately, or it will be signalled all the time while
+                * DEBI is idle.
+                * Note 2: You would think that an irq which is masked is
+                * not signalled by the hardware. Not so for the SAA7146:
+                * An irq is signalled as long as the corresponding bit
+                * in the ISR is set, and disabling irqs just prevents the
+                * hardware from setting the ISR bit. This means a) that we
+                * must clear the ISR *after* disabling the irq (which is why
+                * we must do it here even though saa7146_core did it already),
+                * and b) that if we were to disable an edge triggered irq
+                * (like the gpio irqs sadly are) temporarily we would likely
+                * loose some. This sucks :-(
+                */
+               SAA7146_IER_DISABLE(av7110->dev, MASK_19);
+               SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
+               tasklet_schedule(&av7110->debi_tasklet);
+       }
+
+       if (*isr & MASK_03) {
+               //printk("av7110_irq: GPIO\n");
+               tasklet_schedule(&av7110->gpio_tasklet);
+       }
+
+       if (*isr & MASK_10)
+               tasklet_schedule(&av7110->vpe_tasklet);
+}
+
+
+static struct saa7146_extension av7110_extension_driver;
+
+#define MAKE_AV7110_INFO(x_var,x_name) \
+static struct saa7146_pci_extension_data x_var = { \
+       .ext_priv = x_name, \
+       .ext = &av7110_extension_driver }
+
+MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(ttt_1_X,    "Technotrend/Hauppauge WinTV DVB-T rev1.X");
+MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
+MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
+MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
+MAKE_AV7110_INFO(tts_2_3,    "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
+MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
+MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
+MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
+MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");
+
+static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(fsc,         0x110a, 0x0000),
+       MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
+       MAKE_EXTENSION_PCI(ttt_1_X,     0x13c2, 0x0001),
+       MAKE_EXTENSION_PCI(ttc_2_X,     0x13c2, 0x0002),
+       MAKE_EXTENSION_PCI(tts_2_X,     0x13c2, 0x0003),
+       MAKE_EXTENSION_PCI(gxs_1_3,     0x13c2, 0x0004),
+       MAKE_EXTENSION_PCI(fss,         0x13c2, 0x0006),
+       MAKE_EXTENSION_PCI(ttt,         0x13c2, 0x0008),
+       MAKE_EXTENSION_PCI(ttc_1_X,     0x13c2, 0x000a),
+       MAKE_EXTENSION_PCI(tts_2_3,     0x13c2, 0x000e),
+       MAKE_EXTENSION_PCI(tts_1_3se,   0x13c2, 0x1002),
+
+/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
+/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
+
+       {
+               .vendor    = 0,
+       }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+
+static struct saa7146_extension av7110_extension_driver = {
+       .name           = "av7110",
+       .flags          = SAA7146_USE_I2C_IRQ,
+
+       .module         = THIS_MODULE,
+       .pci_tbl        = &pci_tbl[0],
+       .attach         = av7110_attach,
+       .detach         = __devexit_p(av7110_detach),
+
+       .irq_mask       = MASK_19 | MASK_03 | MASK_10,
+       .irq_func       = av7110_irq,
+};
+
+
+static int __init av7110_init(void)
+{
+       int retval;
+       retval = saa7146_register_extension(&av7110_extension_driver);
+       return retval;
+}
+
+
+static void __exit av7110_exit(void)
+{
+       saa7146_unregister_extension(&av7110_extension_driver);
+}
+
+module_init(av7110_init);
+module_exit(av7110_exit);
+
+MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
+                  "Siemens, Technotrend, Hauppauge");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h
new file mode 100644 (file)
index 0000000..88b3b2d
--- /dev/null
@@ -0,0 +1,314 @@
+#ifndef _AV7110_H_
+#define _AV7110_H_
+
+#include <linux/interrupt.h>
+#include <linux/socket.h>
+#include <linux/netdevice.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+
+#include <linux/dvb/video.h>
+#include <linux/dvb/audio.h>
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/ca.h>
+#include <linux/dvb/osd.h>
+#include <linux/dvb/net.h>
+#include <linux/mutex.h>
+
+#include "dvbdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+#include "dvb_ringbuffer.h"
+#include "dvb_frontend.h"
+#include "ves1820.h"
+#include "ves1x93.h"
+#include "stv0299.h"
+#include "tda8083.h"
+#include "sp8870.h"
+#include "stv0297.h"
+#include "l64781.h"
+
+#include <media/saa7146_vv.h>
+
+
+#define ANALOG_TUNER_VES1820 1
+#define ANALOG_TUNER_STV0297 2
+
+extern int av7110_debug;
+
+#define dprintk(level,args...) \
+           do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0)
+
+#define MAXFILT 32
+
+enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
+
+enum av7110_video_mode {
+       AV7110_VIDEO_MODE_PAL   = 0,
+       AV7110_VIDEO_MODE_NTSC  = 1
+};
+
+struct av7110_p2t {
+       u8                pes[TS_SIZE];
+       u8                counter;
+       long int          pos;
+       int               frags;
+       struct dvb_demux_feed *feed;
+};
+
+/* video MPEG decoder events: */
+/* (code copied from dvb_frontend.c, should maybe be factored out...) */
+#define MAX_VIDEO_EVENT 8
+struct dvb_video_events {
+       struct video_event        events[MAX_VIDEO_EVENT];
+       int                       eventw;
+       int                       eventr;
+       int                       overflow;
+       wait_queue_head_t         wait_queue;
+       spinlock_t                lock;
+};
+
+
+struct av7110;
+
+/* infrared remote control */
+struct infrared {
+       u16     key_map[256];
+       struct input_dev        *input_dev;
+       char                    input_phys[32];
+       struct timer_list       keyup_timer;
+       struct tasklet_struct   ir_tasklet;
+       void                    (*ir_handler)(struct av7110 *av7110, u32 ircom);
+       u32                     ir_command;
+       u32                     ir_config;
+       u32                     device_mask;
+       u8                      protocol;
+       u8                      inversion;
+       u16                     last_key;
+       u16                     last_toggle;
+       u8                      delay_timer_finished;
+};
+
+
+/* place to store all the necessary device information */
+struct av7110 {
+
+       /* devices */
+
+       struct dvb_device       dvb_dev;
+       struct dvb_net          dvb_net;
+
+       struct video_device     *v4l_dev;
+       struct video_device     *vbi_dev;
+
+       struct saa7146_dev      *dev;
+
+       struct i2c_adapter      i2c_adap;
+
+       char                    *card_name;
+
+       /* support for analog module of dvb-c */
+       int                     analog_tuner_flags;
+       int                     current_input;
+       u32                     current_freq;
+
+       struct tasklet_struct   debi_tasklet;
+       struct tasklet_struct   gpio_tasklet;
+
+       int adac_type;         /* audio DAC type */
+#define DVB_ADAC_TI      0
+#define DVB_ADAC_CRYSTAL  1
+#define DVB_ADAC_MSP34x0  2
+#define DVB_ADAC_MSP34x5  3
+#define DVB_ADAC_NONE   -1
+
+
+       /* buffers */
+
+       void                   *iobuf;   /* memory for all buffers */
+       struct dvb_ringbuffer   avout;   /* buffer for video or A/V mux */
+#define AVOUTLEN (128*1024)
+       struct dvb_ringbuffer   aout;    /* buffer for audio */
+#define AOUTLEN (64*1024)
+       void                   *bmpbuf;
+#define BMPLEN (8*32768+1024)
+
+       /* bitmap buffers and states */
+
+       int                     bmpp;
+       int                     bmplen;
+       volatile int            bmp_state;
+#define BMP_NONE     0
+#define BMP_LOADING  1
+#define BMP_LOADED   2
+       wait_queue_head_t       bmpq;
+
+
+       /* DEBI and polled command interface */
+
+       spinlock_t              debilock;
+       struct mutex            dcomlock;
+       volatile int            debitype;
+       volatile int            debilen;
+
+
+       /* Recording and playback flags */
+
+       int                     rec_mode;
+       int                     playing;
+#define RP_NONE  0
+#define RP_VIDEO 1
+#define RP_AUDIO 2
+#define RP_AV   3
+
+
+       /* OSD */
+
+       int                     osdwin;      /* currently active window */
+       u16                     osdbpp[8];
+       struct mutex            osd_mutex;
+
+       /* CA */
+
+       ca_slot_info_t          ci_slot[2];
+
+       enum av7110_video_mode  vidmode;
+       struct dmxdev           dmxdev;
+       struct dvb_demux        demux;
+
+       struct dmx_frontend     hw_frontend;
+       struct dmx_frontend     mem_frontend;
+
+       /* for budget mode demux1 */
+       struct dmxdev           dmxdev1;
+       struct dvb_demux        demux1;
+       struct dvb_net          dvb_net1;
+       spinlock_t              feedlock1;
+       int                     feeding1;
+       u32                     ttbp;
+       unsigned char           *grabbing;
+       struct saa7146_pgtable  pt;
+       struct tasklet_struct   vpe_tasklet;
+       bool                    full_ts;
+
+       int                     fe_synced;
+       struct mutex            pid_mutex;
+
+       int                     video_blank;
+       struct video_status     videostate;
+       u16                     display_panscan;
+       int                     display_ar;
+       int                     trickmode;
+#define TRICK_NONE   0
+#define TRICK_FAST   1
+#define TRICK_SLOW   2
+#define TRICK_FREEZE 3
+       struct audio_status     audiostate;
+
+       struct dvb_demux_filter *handle2filter[32];
+       struct av7110_p2t        p2t_filter[MAXFILT];
+       struct dvb_filter_pes2ts p2t[2];
+       struct ipack             ipack[2];
+       u8                      *kbuf[2];
+
+       int sinfo;
+       int feeding;
+
+       int arm_errors;
+       int registered;
+
+
+       /* AV711X */
+
+       u32                 arm_fw;
+       u32                 arm_rtsl;
+       u32                 arm_vid;
+       u32                 arm_app;
+       u32                 avtype;
+       int                 arm_ready;
+       struct task_struct *arm_thread;
+       wait_queue_head_t   arm_wait;
+       u16                 arm_loops;
+
+       void               *debi_virt;
+       dma_addr_t          debi_bus;
+
+       u16                 pids[DMX_PES_OTHER];
+
+       struct dvb_ringbuffer    ci_rbuffer;
+       struct dvb_ringbuffer    ci_wbuffer;
+
+       struct audio_mixer      mixer;
+
+       struct dvb_adapter       dvb_adapter;
+       struct dvb_device        *video_dev;
+       struct dvb_device        *audio_dev;
+       struct dvb_device        *ca_dev;
+       struct dvb_device        *osd_dev;
+
+       struct dvb_video_events  video_events;
+       video_size_t             video_size;
+
+       u16                     wssMode;
+       u16                     wssData;
+
+       struct infrared         ir;
+
+       /* firmware stuff */
+       unsigned char *bin_fw;
+       unsigned long size_fw;
+
+       unsigned char *bin_dpram;
+       unsigned long size_dpram;
+
+       unsigned char *bin_root;
+       unsigned long size_root;
+
+       struct dvb_frontend* fe;
+       fe_status_t fe_status;
+
+       /* crash recovery */
+       void                            (*recover)(struct av7110* av7110);
+       fe_sec_voltage_t                saved_voltage;
+       fe_sec_tone_mode_t              saved_tone;
+       struct dvb_diseqc_master_cmd    saved_master_cmd;
+       fe_sec_mini_cmd_t               saved_minicmd;
+
+       int (*fe_init)(struct dvb_frontend* fe);
+       int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
+       int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
+       int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
+       int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
+       int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
+       int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
+       int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
+       int (*fe_set_frontend)(struct dvb_frontend *fe);
+};
+
+
+extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+                      u16 subpid, u16 pcrpid);
+
+extern int av7110_check_ir_config(struct av7110 *av7110, int force);
+extern int av7110_ir_init(struct av7110 *av7110);
+extern void av7110_ir_exit(struct av7110 *av7110);
+
+/* msp3400 i2c subaddresses */
+#define MSP_WR_DEM 0x10
+#define MSP_RD_DEM 0x11
+#define MSP_WR_DSP 0x12
+#define MSP_RD_DSP 0x13
+
+extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
+extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
+extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
+
+
+extern int av7110_init_analog_module(struct av7110 *av7110);
+extern int av7110_init_v4l(struct av7110 *av7110);
+extern int av7110_exit_v4l(struct av7110 *av7110);
+
+#endif /* _AV7110_H_ */
diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c
new file mode 100644 (file)
index 0000000..952b33d
--- /dev/null
@@ -0,0 +1,1626 @@
+/*
+ * av7110_av.c: audio and video MPEG decoder stuff
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * originally based on code by:
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+
+#include "av7110.h"
+#include "av7110_hw.h"
+#include "av7110_av.h"
+#include "av7110_ipack.h"
+
+/* MPEG-2 (ISO 13818 / H.222.0) stream types */
+#define PROG_STREAM_MAP  0xBC
+#define PRIVATE_STREAM1  0xBD
+#define PADDING_STREAM  0xBE
+#define PRIVATE_STREAM2  0xBF
+#define AUDIO_STREAM_S  0xC0
+#define AUDIO_STREAM_E  0xDF
+#define VIDEO_STREAM_S  0xE0
+#define VIDEO_STREAM_E  0xEF
+#define ECM_STREAM      0xF0
+#define EMM_STREAM      0xF1
+#define DSM_CC_STREAM   0xF2
+#define ISO13522_STREAM  0xF3
+#define PROG_STREAM_DIR  0xFF
+
+#define PTS_DTS_FLAGS   0xC0
+
+//pts_dts flags
+#define PTS_ONLY        0x80
+#define PTS_DTS                 0xC0
+#define TS_SIZE                 188
+#define TRANS_ERROR     0x80
+#define PAY_START       0x40
+#define TRANS_PRIO      0x20
+#define PID_MASK_HI     0x1F
+//flags
+#define TRANS_SCRMBL1   0x80
+#define TRANS_SCRMBL2   0x40
+#define ADAPT_FIELD     0x20
+#define PAYLOAD                 0x10
+#define COUNT_MASK      0x0F
+
+// adaptation flags
+#define DISCON_IND      0x80
+#define RAND_ACC_IND    0x40
+#define ES_PRI_IND      0x20
+#define PCR_FLAG        0x10
+#define OPCR_FLAG       0x08
+#define SPLICE_FLAG     0x04
+#define TRANS_PRIV      0x02
+#define ADAP_EXT_FLAG   0x01
+
+// adaptation extension flags
+#define LTW_FLAG        0x80
+#define PIECE_RATE      0x40
+#define SEAM_SPLICE     0x20
+
+
+static void p_to_t(u8 const *buf, long int length, u16 pid,
+                  u8 *counter, struct dvb_demux_feed *feed);
+static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
+
+
+int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
+{
+       struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;
+
+       if (!(dvbdmxfeed->ts_type & TS_PACKET))
+               return 0;
+       if (buf[3] == 0xe0)      // video PES do not have a length in TS
+               buf[4] = buf[5] = 0;
+       if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
+               return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
+                                        &dvbdmxfeed->feed.ts, DMX_OK);
+       else
+               return dvb_filter_pes2ts(p2t, buf, len, 1);
+}
+
+static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
+{
+       struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
+
+       dvbdmxfeed->cb.ts(data, 188, NULL, 0,
+                         &dvbdmxfeed->feed.ts, DMX_OK);
+       return 0;
+}
+
+int av7110_av_start_record(struct av7110 *av7110, int av,
+                          struct dvb_demux_feed *dvbdmxfeed)
+{
+       int ret = 0;
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+
+       dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
+
+       if (av7110->playing || (av7110->rec_mode & av))
+               return -EBUSY;
+       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+       dvbdmx->recording = 1;
+       av7110->rec_mode |= av;
+
+       switch (av7110->rec_mode) {
+       case RP_AUDIO:
+               dvb_filter_pes2ts_init(&av7110->p2t[0],
+                                      dvbdmx->pesfilter[0]->pid,
+                                      dvb_filter_pes2ts_cb,
+                                      (void *) dvbdmx->pesfilter[0]);
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+               break;
+
+       case RP_VIDEO:
+               dvb_filter_pes2ts_init(&av7110->p2t[1],
+                                      dvbdmx->pesfilter[1]->pid,
+                                      dvb_filter_pes2ts_cb,
+                                      (void *) dvbdmx->pesfilter[1]);
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+               break;
+
+       case RP_AV:
+               dvb_filter_pes2ts_init(&av7110->p2t[0],
+                                      dvbdmx->pesfilter[0]->pid,
+                                      dvb_filter_pes2ts_cb,
+                                      (void *) dvbdmx->pesfilter[0]);
+               dvb_filter_pes2ts_init(&av7110->p2t[1],
+                                      dvbdmx->pesfilter[1]->pid,
+                                      dvb_filter_pes2ts_cb,
+                                      (void *) dvbdmx->pesfilter[1]);
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
+               break;
+       }
+       return ret;
+}
+
+int av7110_av_start_play(struct av7110 *av7110, int av)
+{
+       int ret = 0;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (av7110->rec_mode)
+               return -EBUSY;
+       if (av7110->playing & av)
+               return -EBUSY;
+
+       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+
+       if (av7110->playing == RP_NONE) {
+               av7110_ipack_reset(&av7110->ipack[0]);
+               av7110_ipack_reset(&av7110->ipack[1]);
+       }
+
+       av7110->playing |= av;
+       switch (av7110->playing) {
+       case RP_AUDIO:
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+               break;
+       case RP_VIDEO:
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+               av7110->sinfo = 0;
+               break;
+       case RP_AV:
+               av7110->sinfo = 0;
+               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
+               break;
+       }
+       return ret;
+}
+
+int av7110_av_stop(struct av7110 *av7110, int av)
+{
+       int ret = 0;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (!(av7110->playing & av) && !(av7110->rec_mode & av))
+               return 0;
+       av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+       if (av7110->playing) {
+               av7110->playing &= ~av;
+               switch (av7110->playing) {
+               case RP_AUDIO:
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+                       break;
+               case RP_VIDEO:
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+                       break;
+               case RP_NONE:
+                       ret = av7110_set_vidmode(av7110, av7110->vidmode);
+                       break;
+               }
+       } else {
+               av7110->rec_mode &= ~av;
+               switch (av7110->rec_mode) {
+               case RP_AUDIO:
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+                       break;
+               case RP_VIDEO:
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+                       break;
+               case RP_NONE:
+                       break;
+               }
+       }
+       return ret;
+}
+
+
+int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
+{
+       int len;
+       u32 sync;
+       u16 blen;
+
+       if (!dlen) {
+               wake_up(&buf->queue);
+               return -1;
+       }
+       while (1) {
+               len = dvb_ringbuffer_avail(buf);
+               if (len < 6) {
+                       wake_up(&buf->queue);
+                       return -1;
+               }
+               sync =  DVB_RINGBUFFER_PEEK(buf, 0) << 24;
+               sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16;
+               sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
+               sync |= DVB_RINGBUFFER_PEEK(buf, 3);
+
+               if (((sync &~ 0x0f) == 0x000001e0) ||
+                   ((sync &~ 0x1f) == 0x000001c0) ||
+                   (sync == 0x000001bd))
+                       break;
+               printk("resync\n");
+               DVB_RINGBUFFER_SKIP(buf, 1);
+       }
+       blen =  DVB_RINGBUFFER_PEEK(buf, 4) << 8;
+       blen |= DVB_RINGBUFFER_PEEK(buf, 5);
+       blen += 6;
+       if (len < blen || blen > dlen) {
+               //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
+               wake_up(&buf->queue);
+               return -1;
+       }
+
+       dvb_ringbuffer_read(buf, dest, (size_t) blen);
+
+       dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
+              (unsigned long) buf->pread, (unsigned long) buf->pwrite);
+       wake_up(&buf->queue);
+       return blen;
+}
+
+
+int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
+{
+       int err, vol, val, balance = 0;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       av7110->mixer.volume_left = volleft;
+       av7110->mixer.volume_right = volright;
+
+       switch (av7110->adac_type) {
+       case DVB_ADAC_TI:
+               volleft = (volleft * 256) / 1036;
+               volright = (volright * 256) / 1036;
+               if (volleft > 0x3f)
+                       volleft = 0x3f;
+               if (volright > 0x3f)
+                       volright = 0x3f;
+               if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
+                       return err;
+               return SendDAC(av7110, 4, volright);
+
+       case DVB_ADAC_CRYSTAL:
+               volleft = 127 - volleft / 2;
+               volright = 127 - volright / 2;
+               i2c_writereg(av7110, 0x20, 0x03, volleft);
+               i2c_writereg(av7110, 0x20, 0x04, volright);
+               return 0;
+
+       case DVB_ADAC_MSP34x0:
+               vol  = (volleft > volright) ? volleft : volright;
+               val     = (vol * 0x73 / 255) << 8;
+               if (vol > 0)
+                      balance = ((volright - volleft) * 127) / vol;
+               msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
+               msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
+               msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
+               return 0;
+
+       case DVB_ADAC_MSP34x5:
+               vol = (volleft > volright) ? volleft : volright;
+               val = (vol * 0x73 / 255) << 8;
+               if (vol > 0)
+                       balance = ((volright - volleft) * 127) / vol;
+               msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
+               msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
+               return 0;
+       }
+
+       return 0;
+}
+
+int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
+{
+       int ret;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
+
+       if (!ret && !av7110->playing) {
+               ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+                          av7110->pids[DMX_PES_AUDIO],
+                          av7110->pids[DMX_PES_TELETEXT],
+                          0, av7110->pids[DMX_PES_PCR]);
+               if (!ret)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+       }
+       return ret;
+}
+
+
+static enum av7110_video_mode sw2mode[16] = {
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+};
+
+static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
+{
+       int i;
+       int hsize, vsize;
+       int sw;
+       u8 *p;
+       int ret = 0;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (av7110->sinfo)
+               return 0;
+       for (i = 7; i < count - 10; i++) {
+               p = buf + i;
+               if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
+                       continue;
+               p += 4;
+               hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
+               vsize = ((p[1] &0x0F) << 8) | (p[2]);
+               sw = (p[3] & 0x0F);
+               ret = av7110_set_vidmode(av7110, sw2mode[sw]);
+               if (!ret) {
+                       dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
+                       av7110->sinfo = 1;
+               }
+               break;
+       }
+       return ret;
+}
+
+
+/****************************************************************************
+ * I/O buffer management and control
+ ****************************************************************************/
+
+static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
+                                        const u8 *buf, unsigned long count)
+{
+       unsigned long todo = count;
+       int free;
+
+       while (todo > 0) {
+               if (dvb_ringbuffer_free(rbuf) < 2048) {
+                       if (wait_event_interruptible(rbuf->queue,
+                                                    (dvb_ringbuffer_free(rbuf) >= 2048)))
+                               return count - todo;
+               }
+               free = dvb_ringbuffer_free(rbuf);
+               if (free > todo)
+                       free = todo;
+               dvb_ringbuffer_write(rbuf, buf, free);
+               todo -= free;
+               buf += free;
+       }
+
+       return count - todo;
+}
+
+static void play_video_cb(u8 *buf, int count, void *priv)
+{
+       struct av7110 *av7110 = (struct av7110 *) priv;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if ((buf[3] & 0xe0) == 0xe0) {
+               get_video_format(av7110, buf, count);
+               aux_ring_buffer_write(&av7110->avout, buf, count);
+       } else
+               aux_ring_buffer_write(&av7110->aout, buf, count);
+}
+
+static void play_audio_cb(u8 *buf, int count, void *priv)
+{
+       struct av7110 *av7110 = (struct av7110 *) priv;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       aux_ring_buffer_write(&av7110->aout, buf, count);
+}
+
+
+#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
+
+static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
+                      unsigned long count, int nonblock, int type)
+{
+       struct dvb_ringbuffer *rb;
+       u8 *kb;
+       unsigned long todo = count;
+
+       dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
+
+       rb = (type) ? &av7110->avout : &av7110->aout;
+       kb = av7110->kbuf[type];
+
+       if (!kb)
+               return -ENOBUFS;
+
+       if (nonblock && !FREE_COND_TS)
+               return -EWOULDBLOCK;
+
+       while (todo >= TS_SIZE) {
+               if (!FREE_COND_TS) {
+                       if (nonblock)
+                               return count - todo;
+                       if (wait_event_interruptible(rb->queue, FREE_COND_TS))
+                               return count - todo;
+               }
+               if (copy_from_user(kb, buf, TS_SIZE))
+                       return -EFAULT;
+               write_ts_to_decoder(av7110, type, kb, TS_SIZE);
+               todo -= TS_SIZE;
+               buf += TS_SIZE;
+       }
+
+       return count - todo;
+}
+
+
+#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
+                  dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
+
+static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf,
+                       unsigned long count, int nonblock, int type)
+{
+       unsigned long todo = count, n;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (!av7110->kbuf[type])
+               return -ENOBUFS;
+
+       if (nonblock && !FREE_COND)
+               return -EWOULDBLOCK;
+
+       while (todo > 0) {
+               if (!FREE_COND) {
+                       if (nonblock)
+                               return count - todo;
+                       if (wait_event_interruptible(av7110->avout.queue,
+                                                    FREE_COND))
+                               return count - todo;
+               }
+               n = todo;
+               if (n > IPACKS * 2)
+                       n = IPACKS * 2;
+               if (copy_from_user(av7110->kbuf[type], buf, n))
+                       return -EFAULT;
+               av7110_ipack_instant_repack(av7110->kbuf[type], n,
+                                           &av7110->ipack[type]);
+               todo -= n;
+               buf += n;
+       }
+       return count - todo;
+}
+
+static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
+                       unsigned long count, int nonblock, int type)
+{
+       unsigned long todo = count, n;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (!av7110->kbuf[type])
+               return -ENOBUFS;
+
+       if (nonblock && !FREE_COND)
+               return -EWOULDBLOCK;
+
+       while (todo > 0) {
+               if (!FREE_COND) {
+                       if (nonblock)
+                               return count - todo;
+                       if (wait_event_interruptible(av7110->avout.queue,
+                                                    FREE_COND))
+                               return count - todo;
+               }
+               n = todo;
+               if (n > IPACKS * 2)
+                       n = IPACKS * 2;
+               av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]);
+               todo -= n;
+               buf += n;
+       }
+       return count - todo;
+}
+
+static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf,
+                        unsigned long count, int nonblock, int type)
+{
+       unsigned long todo = count, n;
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (!av7110->kbuf[type])
+               return -ENOBUFS;
+       if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024)
+               return -EWOULDBLOCK;
+
+       while (todo > 0) {
+               if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) {
+                       if (nonblock)
+                               return count - todo;
+                       if (wait_event_interruptible(av7110->aout.queue,
+                                       (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
+                               return count-todo;
+               }
+               n = todo;
+               if (n > IPACKS * 2)
+                       n = IPACKS * 2;
+               if (copy_from_user(av7110->kbuf[type], buf, n))
+                       return -EFAULT;
+               av7110_ipack_instant_repack(av7110->kbuf[type], n,
+                                           &av7110->ipack[type]);
+               todo -= n;
+               buf += n;
+       }
+       return count - todo;
+}
+
+void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed)
+{
+       memset(p->pes, 0, TS_SIZE);
+       p->counter = 0;
+       p->pos = 0;
+       p->frags = 0;
+       if (feed)
+               p->feed = feed;
+}
+
+static void clear_p2t(struct av7110_p2t *p)
+{
+       memset(p->pes, 0, TS_SIZE);
+//     p->counter = 0;
+       p->pos = 0;
+       p->frags = 0;
+}
+
+
+static int find_pes_header(u8 const *buf, long int length, int *frags)
+{
+       int c = 0;
+       int found = 0;
+
+       *frags = 0;
+
+       while (c < length - 3 && !found) {
+               if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
+                   buf[c + 2] == 0x01) {
+                       switch ( buf[c + 3] ) {
+                       case PROG_STREAM_MAP:
+                       case PRIVATE_STREAM2:
+                       case PROG_STREAM_DIR:
+                       case ECM_STREAM     :
+                       case EMM_STREAM     :
+                       case PADDING_STREAM :
+                       case DSM_CC_STREAM  :
+                       case ISO13522_STREAM:
+                       case PRIVATE_STREAM1:
+                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+                               found = 1;
+                               break;
+
+                       default:
+                               c++;
+                               break;
+                       }
+               } else
+                       c++;
+       }
+       if (c == length - 3 && !found) {
+               if (buf[length - 1] == 0x00)
+                       *frags = 1;
+               if (buf[length - 2] == 0x00 &&
+                   buf[length - 1] == 0x00)
+                       *frags = 2;
+               if (buf[length - 3] == 0x00 &&
+                   buf[length - 2] == 0x00 &&
+                   buf[length - 1] == 0x01)
+                       *frags = 3;
+               return -1;
+       }
+
+       return c;
+}
+
+void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
+{
+       int c, c2, l, add;
+       int check, rest;
+
+       c = 0;
+       c2 = 0;
+       if (p->frags){
+               check = 0;
+               switch(p->frags) {
+               case 1:
+                       if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
+                               check = 1;
+                               c += 2;
+                       }
+                       break;
+               case 2:
+                       if (buf[c] == 0x01) {
+                               check = 1;
+                               c++;
+                       }
+                       break;
+               case 3:
+                       check = 1;
+               }
+               if (check) {
+                       switch (buf[c]) {
+                       case PROG_STREAM_MAP:
+                       case PRIVATE_STREAM2:
+                       case PROG_STREAM_DIR:
+                       case ECM_STREAM     :
+                       case EMM_STREAM     :
+                       case PADDING_STREAM :
+                       case DSM_CC_STREAM  :
+                       case ISO13522_STREAM:
+                       case PRIVATE_STREAM1:
+                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+                               p->pes[0] = 0x00;
+                               p->pes[1] = 0x00;
+                               p->pes[2] = 0x01;
+                               p->pes[3] = buf[c];
+                               p->pos = 4;
+                               memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos);
+                               c += (TS_SIZE - 4) - p->pos;
+                               p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed);
+                               clear_p2t(p);
+                               break;
+
+                       default:
+                               c = 0;
+                               break;
+                       }
+               }
+               p->frags = 0;
+       }
+
+       if (p->pos) {
+               c2 = find_pes_header(buf + c, length - c, &p->frags);
+               if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
+                       l = c2+c;
+               else
+                       l = (TS_SIZE - 4) - p->pos;
+               memcpy(p->pes + p->pos, buf, l);
+               c += l;
+               p->pos += l;
+               p_to_t(p->pes, p->pos, pid, &p->counter, p->feed);
+               clear_p2t(p);
+       }
+
+       add = 0;
+       while (c < length) {
+               c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
+               if (c2 >= 0) {
+                       c2 += c + add;
+                       if (c2 > c){
+                               p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
+                               c = c2;
+                               clear_p2t(p);
+                               add = 0;
+                       } else
+                               add = 1;
+               } else {
+                       l = length - c;
+                       rest = l % (TS_SIZE - 4);
+                       l -= rest;
+                       p_to_t(buf + c, l, pid, &p->counter, p->feed);
+                       memcpy(p->pes, buf + c + l, rest);
+                       p->pos = rest;
+                       c = length;
+               }
+       }
+}
+
+
+static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
+{
+       int i;
+       int c = 0;
+       int fill;
+       u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 };
+
+       fill = (TS_SIZE - 4) - length;
+       if (pes_start)
+               tshead[1] = 0x40;
+       if (fill)
+               tshead[3] = 0x30;
+       tshead[1] |= (u8)((pid & 0x1F00) >> 8);
+       tshead[2] |= (u8)(pid & 0x00FF);
+       tshead[3] |= ((*counter)++ & 0x0F);
+       memcpy(buf, tshead, 4);
+       c += 4;
+
+       if (fill) {
+               buf[4] = fill - 1;
+               c++;
+               if (fill > 1) {
+                       buf[5] = 0x00;
+                       c++;
+               }
+               for (i = 6; i < fill + 4; i++) {
+                       buf[i] = 0xFF;
+                       c++;
+               }
+       }
+
+       return c;
+}
+
+
+static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
+                  struct dvb_demux_feed *feed)
+{
+       int l, pes_start;
+       u8 obuf[TS_SIZE];
+       long c = 0;
+
+       pes_start = 0;
+       if (length > 3 &&
+            buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
+               switch (buf[3]) {
+                       case PROG_STREAM_MAP:
+                       case PRIVATE_STREAM2:
+                       case PROG_STREAM_DIR:
+                       case ECM_STREAM     :
+                       case EMM_STREAM     :
+                       case PADDING_STREAM :
+                       case DSM_CC_STREAM  :
+                       case ISO13522_STREAM:
+                       case PRIVATE_STREAM1:
+                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+                               pes_start = 1;
+                               break;
+
+                       default:
+                               break;
+               }
+
+       while (c < length) {
+               memset(obuf, 0, TS_SIZE);
+               if (length - c >= (TS_SIZE - 4)){
+                       l = write_ts_header2(pid, counter, pes_start,
+                                            obuf, (TS_SIZE - 4));
+                       memcpy(obuf + l, buf + c, TS_SIZE - l);
+                       c += TS_SIZE - l;
+               } else {
+                       l = write_ts_header2(pid, counter, pes_start,
+                                            obuf, length - c);
+                       memcpy(obuf + l, buf + c, TS_SIZE - l);
+                       c = length;
+               }
+               feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
+               pes_start = 0;
+       }
+}
+
+
+static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
+{
+       struct ipack *ipack = &av7110->ipack[type];
+
+       if (buf[1] & TRANS_ERROR) {
+               av7110_ipack_reset(ipack);
+               return -1;
+       }
+
+       if (!(buf[3] & PAYLOAD))
+               return -1;
+
+       if (buf[1] & PAY_START)
+               av7110_ipack_flush(ipack);
+
+       if (buf[3] & ADAPT_FIELD) {
+               len -= buf[4] + 1;
+               buf += buf[4] + 1;
+               if (!len)
+                       return 0;
+       }
+
+       av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
+       return 0;
+}
+
+
+int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct av7110 *av7110 = (struct av7110 *) demux->priv;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
+               return 0;
+
+       switch (feed->pes_type) {
+       case 0:
+               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
+                       return -EINVAL;
+               break;
+       case 1:
+               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
+                       return -EINVAL;
+               break;
+       default:
+               return -1;
+       }
+
+       return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
+}
+
+
+
+/******************************************************************************
+ * Video MPEG decoder events
+ ******************************************************************************/
+void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
+{
+       struct dvb_video_events *events = &av7110->video_events;
+       int wp;
+
+       spin_lock_bh(&events->lock);
+
+       wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
+       if (wp == events->eventr) {
+               events->overflow = 1;
+               events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
+       }
+
+       //FIXME: timestamp?
+       memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
+       events->eventw = wp;
+
+       spin_unlock_bh(&events->lock);
+
+       wake_up_interruptible(&events->wait_queue);
+}
+
+
+static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
+{
+       struct dvb_video_events *events = &av7110->video_events;
+
+       if (events->overflow) {
+               events->overflow = 0;
+               return -EOVERFLOW;
+       }
+       if (events->eventw == events->eventr) {
+               int ret;
+
+               if (flags & O_NONBLOCK)
+                       return -EWOULDBLOCK;
+
+               ret = wait_event_interruptible(events->wait_queue,
+                                              events->eventw != events->eventr);
+               if (ret < 0)
+                       return ret;
+       }
+
+       spin_lock_bh(&events->lock);
+
+       memcpy(event, &events->events[events->eventr],
+              sizeof(struct video_event));
+       events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
+
+       spin_unlock_bh(&events->lock);
+
+       return 0;
+}
+
+
+/******************************************************************************
+ * DVB device file operations
+ ******************************************************************************/
+
+static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned int mask = 0;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY)
+               poll_wait(file, &av7110->avout.queue, wait);
+
+       poll_wait(file, &av7110->video_events.wait_queue, wait);
+
+       if (av7110->video_events.eventw != av7110->video_events.eventr)
+               mask = POLLPRI;
+
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+               if (av7110->playing) {
+                       if (FREE_COND)
+                               mask |= (POLLOUT | POLLWRNORM);
+                       } else /* if not playing: may play if asked for */
+                               mask |= (POLLOUT | POLLWRNORM);
+       }
+
+       return mask;
+}
+
+static ssize_t dvb_video_write(struct file *file, const char __user *buf,
+                              size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned char c;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+               return -EPERM;
+
+       if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
+               return -EPERM;
+
+       if (get_user(c, buf))
+               return -EFAULT;
+       if (c == 0x47 && count % TS_SIZE == 0)
+               return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
+       else
+               return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
+}
+
+static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned int mask = 0;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       poll_wait(file, &av7110->aout.queue, wait);
+
+       if (av7110->playing) {
+               if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
+                       mask |= (POLLOUT | POLLWRNORM);
+       } else /* if not playing: may play if asked for */
+               mask = (POLLOUT | POLLWRNORM);
+
+       return mask;
+}
+
+static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
+                              size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned char c;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
+               printk(KERN_ERR "not audio source memory\n");
+               return -EPERM;
+       }
+
+       if (get_user(c, buf))
+               return -EFAULT;
+       if (c == 0x47 && count % TS_SIZE == 0)
+               return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
+       else
+               return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
+}
+
+static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
+
+#define MIN_IFRAME 400000
+
+static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
+{
+       unsigned i, n;
+       int progressive = 0;
+       int match = 0;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (!(av7110->playing & RP_VIDEO)) {
+               if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
+                       return -EBUSY;
+       }
+
+       /* search in buf for instances of 00 00 01 b5 1? */
+       for (i = 0; i < len; i++) {
+               unsigned char c;
+               if (get_user(c, buf + i))
+                       return -EFAULT;
+               if (match == 5) {
+                       progressive = c & 0x08;
+                       match = 0;
+               }
+               if (c == 0x00) {
+                       match = (match == 1 || match == 2) ? 2 : 1;
+                       continue;
+               }
+               switch (match++) {
+               case 2: if (c == 0x01)
+                               continue;
+                       break;
+               case 3: if (c == 0xb5)
+                               continue;
+                       break;
+               case 4: if ((c & 0xf0) == 0x10)
+                               continue;
+                       break;
+               }
+               match = 0;
+       }
+
+       /* setting n always > 1, fixes problems when playing stillframes
+          consisting of I- and P-Frames */
+       n = MIN_IFRAME / len + 1;
+
+       /* FIXME: nonblock? */
+       dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1);
+
+       for (i = 0; i < n; i++)
+               dvb_play(av7110, buf, len, 0, 1);
+
+       av7110_ipack_flush(&av7110->ipack[1]);
+
+       if (progressive)
+               return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
+       else
+               return 0;
+}
+
+
+static int dvb_video_ioctl(struct file *file,
+                          unsigned int cmd, void *parg)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned long arg = (unsigned long) parg;
+       int ret = 0;
+
+       dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
+
+       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+               if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
+                    cmd != VIDEO_GET_SIZE ) {
+                       return -EPERM;
+               }
+       }
+
+       switch (cmd) {
+       case VIDEO_STOP:
+               av7110->videostate.play_state = VIDEO_STOPPED;
+               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
+                       ret = av7110_av_stop(av7110, RP_VIDEO);
+               else
+                       ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
+                              av7110->videostate.video_blank ? 0 : 1);
+               if (!ret)
+                       av7110->trickmode = TRICK_NONE;
+               break;
+
+       case VIDEO_PLAY:
+               av7110->trickmode = TRICK_NONE;
+               if (av7110->videostate.play_state == VIDEO_FREEZED) {
+                       av7110->videostate.play_state = VIDEO_PLAYING;
+                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
+                       if (ret)
+                               break;
+               }
+               if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
+                       if (av7110->playing == RP_AV) {
+                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+                               if (ret)
+                                       break;
+                               av7110->playing &= ~RP_VIDEO;
+                       }
+                       ret = av7110_av_start_play(av7110, RP_VIDEO);
+               }
+               if (!ret)
+                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
+               if (!ret)
+                       av7110->videostate.play_state = VIDEO_PLAYING;
+               break;
+
+       case VIDEO_FREEZE:
+               av7110->videostate.play_state = VIDEO_FREEZED;
+               if (av7110->playing & RP_VIDEO)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
+               else
+                       ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
+               if (!ret)
+                       av7110->trickmode = TRICK_FREEZE;
+               break;
+
+       case VIDEO_CONTINUE:
+               if (av7110->playing & RP_VIDEO)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
+               if (!ret)
+                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
+               if (!ret) {
+                       av7110->videostate.play_state = VIDEO_PLAYING;
+                       av7110->trickmode = TRICK_NONE;
+               }
+               break;
+
+       case VIDEO_SELECT_SOURCE:
+               av7110->videostate.stream_source = (video_stream_source_t) arg;
+               break;
+
+       case VIDEO_SET_BLANK:
+               av7110->videostate.video_blank = (int) arg;
+               break;
+
+       case VIDEO_GET_STATUS:
+               memcpy(parg, &av7110->videostate, sizeof(struct video_status));
+               break;
+
+       case VIDEO_GET_EVENT:
+               ret = dvb_video_get_event(av7110, parg, file->f_flags);
+               break;
+
+       case VIDEO_GET_SIZE:
+               memcpy(parg, &av7110->video_size, sizeof(video_size_t));
+               break;
+
+       case VIDEO_SET_DISPLAY_FORMAT:
+       {
+               video_displayformat_t format = (video_displayformat_t) arg;
+               switch (format) {
+               case VIDEO_PAN_SCAN:
+                       av7110->display_panscan = VID_PAN_SCAN_PREF;
+                       break;
+               case VIDEO_LETTER_BOX:
+                       av7110->display_panscan = VID_VC_AND_PS_PREF;
+                       break;
+               case VIDEO_CENTER_CUT_OUT:
+                       av7110->display_panscan = VID_CENTRE_CUT_PREF;
+                       break;
+               default:
+                       ret = -EINVAL;
+               }
+               if (ret < 0)
+                       break;
+               av7110->videostate.display_format = format;
+               ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
+                                   1, av7110->display_panscan);
+               break;
+       }
+
+       case VIDEO_SET_FORMAT:
+               if (arg > 1) {
+                       ret = -EINVAL;
+                       break;
+               }
+               av7110->display_ar = arg;
+               ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
+                                   1, (u16) arg);
+               break;
+
+       case VIDEO_STILLPICTURE:
+       {
+               struct video_still_picture *pic =
+                       (struct video_still_picture *) parg;
+               av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+               ret = play_iframe(av7110, pic->iFrame, pic->size,
+                                 file->f_flags & O_NONBLOCK);
+               break;
+       }
+
+       case VIDEO_FAST_FORWARD:
+               //note: arg is ignored by firmware
+               if (av7110->playing & RP_VIDEO)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+                                           __Scan_I, 2, AV_PES, 0);
+               else
+                       ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg);
+               if (!ret) {
+                       av7110->trickmode = TRICK_FAST;
+                       av7110->videostate.play_state = VIDEO_PLAYING;
+               }
+               break;
+
+       case VIDEO_SLOWMOTION:
+               if (av7110->playing&RP_VIDEO) {
+                       if (av7110->trickmode != TRICK_SLOW)
+                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
+                       if (!ret)
+                               ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
+               } else {
+                       ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0);
+                       if (!ret)
+                               ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0);
+                       if (!ret)
+                               ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
+               }
+               if (!ret) {
+                       av7110->trickmode = TRICK_SLOW;
+                       av7110->videostate.play_state = VIDEO_PLAYING;
+               }
+               break;
+
+       case VIDEO_GET_CAPABILITIES:
+               *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |
+                       VIDEO_CAP_SYS | VIDEO_CAP_PROG;
+               break;
+
+       case VIDEO_CLEAR_BUFFER:
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+               av7110_ipack_reset(&av7110->ipack[1]);
+               if (av7110->playing == RP_AV) {
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+                                           __Play, 2, AV_PES, 0);
+                       if (ret)
+                               break;
+                       if (av7110->trickmode == TRICK_FAST)
+                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+                                                   __Scan_I, 2, AV_PES, 0);
+                       if (av7110->trickmode == TRICK_SLOW) {
+                               ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+                                                   __Slow, 2, 0, 0);
+                               if (!ret)
+                                       ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
+                       }
+                       if (av7110->trickmode == TRICK_FREEZE)
+                               ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1);
+               }
+               break;
+
+       case VIDEO_SET_STREAMTYPE:
+               break;
+
+       default:
+               ret = -ENOIOCTLCMD;
+               break;
+       }
+
+       return ret;
+}
+
+static int dvb_audio_ioctl(struct file *file,
+                          unsigned int cmd, void *parg)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned long arg = (unsigned long) parg;
+       int ret = 0;
+
+       dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
+
+       if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
+           (cmd != AUDIO_GET_STATUS))
+               return -EPERM;
+
+       switch (cmd) {
+       case AUDIO_STOP:
+               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
+                       ret = av7110_av_stop(av7110, RP_AUDIO);
+               else
+                       ret = audcom(av7110, AUDIO_CMD_MUTE);
+               if (!ret)
+                       av7110->audiostate.play_state = AUDIO_STOPPED;
+               break;
+
+       case AUDIO_PLAY:
+               if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
+                       ret = av7110_av_start_play(av7110, RP_AUDIO);
+               if (!ret)
+                       ret = audcom(av7110, AUDIO_CMD_UNMUTE);
+               if (!ret)
+                       av7110->audiostate.play_state = AUDIO_PLAYING;
+               break;
+
+       case AUDIO_PAUSE:
+               ret = audcom(av7110, AUDIO_CMD_MUTE);
+               if (!ret)
+                       av7110->audiostate.play_state = AUDIO_PAUSED;
+               break;
+
+       case AUDIO_CONTINUE:
+               if (av7110->audiostate.play_state == AUDIO_PAUSED) {
+                       av7110->audiostate.play_state = AUDIO_PLAYING;
+                       ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
+               }
+               break;
+
+       case AUDIO_SELECT_SOURCE:
+               av7110->audiostate.stream_source = (audio_stream_source_t) arg;
+               break;
+
+       case AUDIO_SET_MUTE:
+       {
+               ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
+               if (!ret)
+                       av7110->audiostate.mute_state = (int) arg;
+               break;
+       }
+
+       case AUDIO_SET_AV_SYNC:
+               av7110->audiostate.AV_sync_state = (int) arg;
+               ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
+               break;
+
+       case AUDIO_SET_BYPASS_MODE:
+               if (FW_VERSION(av7110->arm_app) < 0x2621)
+                       ret = -EINVAL;
+               av7110->audiostate.bypass_mode = (int)arg;
+               break;
+
+       case AUDIO_CHANNEL_SELECT:
+               av7110->audiostate.channel_select = (audio_channel_select_t) arg;
+               switch(av7110->audiostate.channel_select) {
+               case AUDIO_STEREO:
+                       ret = audcom(av7110, AUDIO_CMD_STEREO);
+                       if (!ret) {
+                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                                       i2c_writereg(av7110, 0x20, 0x02, 0x49);
+                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
+                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220);
+                       }
+                       break;
+               case AUDIO_MONO_LEFT:
+                       ret = audcom(av7110, AUDIO_CMD_MONO_L);
+                       if (!ret) {
+                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                                       i2c_writereg(av7110, 0x20, 0x02, 0x4a);
+                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
+                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200);
+                       }
+                       break;
+               case AUDIO_MONO_RIGHT:
+                       ret = audcom(av7110, AUDIO_CMD_MONO_R);
+                       if (!ret) {
+                               if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+                                       i2c_writereg(av7110, 0x20, 0x02, 0x45);
+                               else if (av7110->adac_type == DVB_ADAC_MSP34x5)
+                                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210);
+                       }
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+               }
+               break;
+
+       case AUDIO_GET_STATUS:
+               memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
+               break;
+
+       case AUDIO_GET_CAPABILITIES:
+               if (FW_VERSION(av7110->arm_app) < 0x2621)
+                       *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
+               else
+                       *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 |
+                                               AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
+               break;
+
+       case AUDIO_CLEAR_BUFFER:
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
+               av7110_ipack_reset(&av7110->ipack[0]);
+               if (av7110->playing == RP_AV)
+                       ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+                                           __Play, 2, AV_PES, 0);
+               break;
+
+       case AUDIO_SET_ID:
+               break;
+
+       case AUDIO_SET_MIXER:
+       {
+               struct audio_mixer *amix = (struct audio_mixer *)parg;
+               ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
+               break;
+       }
+
+       case AUDIO_SET_STREAMTYPE:
+               break;
+
+       default:
+               ret = -ENOIOCTLCMD;
+       }
+
+       return ret;
+}
+
+
+static int dvb_video_open(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       int err;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if ((err = dvb_generic_open(inode, file)) < 0)
+               return err;
+
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+               av7110->video_blank = 1;
+               av7110->audiostate.AV_sync_state = 1;
+               av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
+
+               /*  empty event queue */
+               av7110->video_events.eventr = av7110->video_events.eventw = 0;
+       }
+
+       return 0;
+}
+
+static int dvb_video_release(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+               av7110_av_stop(av7110, RP_VIDEO);
+       }
+
+       return dvb_generic_release(inode, file);
+}
+
+static int dvb_audio_open(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       int err = dvb_generic_open(inode, file);
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       if (err < 0)
+               return err;
+       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
+       av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
+       return 0;
+}
+
+static int dvb_audio_release(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+
+       dprintk(2, "av7110:%p, \n", av7110);
+
+       av7110_av_stop(av7110, RP_AUDIO);
+       return dvb_generic_release(inode, file);
+}
+
+
+
+/******************************************************************************
+ * driver registration
+ ******************************************************************************/
+
+static const struct file_operations dvb_video_fops = {
+       .owner          = THIS_MODULE,
+       .write          = dvb_video_write,
+       .unlocked_ioctl = dvb_generic_ioctl,
+       .open           = dvb_video_open,
+       .release        = dvb_video_release,
+       .poll           = dvb_video_poll,
+       .llseek         = noop_llseek,
+};
+
+static struct dvb_device dvbdev_video = {
+       .priv           = NULL,
+       .users          = 6,
+       .readers        = 5,    /* arbitrary */
+       .writers        = 1,
+       .fops           = &dvb_video_fops,
+       .kernel_ioctl   = dvb_video_ioctl,
+};
+
+static const struct file_operations dvb_audio_fops = {
+       .owner          = THIS_MODULE,
+       .write          = dvb_audio_write,
+       .unlocked_ioctl = dvb_generic_ioctl,
+       .open           = dvb_audio_open,
+       .release        = dvb_audio_release,
+       .poll           = dvb_audio_poll,
+       .llseek         = noop_llseek,
+};
+
+static struct dvb_device dvbdev_audio = {
+       .priv           = NULL,
+       .users          = 1,
+       .writers        = 1,
+       .fops           = &dvb_audio_fops,
+       .kernel_ioctl   = dvb_audio_ioctl,
+};
+
+
+int av7110_av_register(struct av7110 *av7110)
+{
+       av7110->audiostate.AV_sync_state = 0;
+       av7110->audiostate.mute_state = 0;
+       av7110->audiostate.play_state = AUDIO_STOPPED;
+       av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
+       av7110->audiostate.channel_select = AUDIO_STEREO;
+       av7110->audiostate.bypass_mode = 0;
+
+       av7110->videostate.video_blank = 0;
+       av7110->videostate.play_state = VIDEO_STOPPED;
+       av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
+       av7110->videostate.video_format = VIDEO_FORMAT_4_3;
+       av7110->videostate.display_format = VIDEO_LETTER_BOX;
+       av7110->display_ar = VIDEO_FORMAT_4_3;
+       av7110->display_panscan = VID_VC_AND_PS_PREF;
+
+       init_waitqueue_head(&av7110->video_events.wait_queue);
+       spin_lock_init(&av7110->video_events.lock);
+       av7110->video_events.eventw = av7110->video_events.eventr = 0;
+       av7110->video_events.overflow = 0;
+       memset(&av7110->video_size, 0, sizeof (video_size_t));
+
+       dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
+                           &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
+
+       dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
+                           &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
+
+       return 0;
+}
+
+void av7110_av_unregister(struct av7110 *av7110)
+{
+       dvb_unregister_device(av7110->audio_dev);
+       dvb_unregister_device(av7110->video_dev);
+}
+
+int av7110_av_init(struct av7110 *av7110)
+{
+       void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
+       int i, ret;
+
+       for (i = 0; i < 2; i++) {
+               struct ipack *ipack = av7110->ipack + i;
+
+               ret = av7110_ipack_init(ipack, IPACKS, play[i]);
+               if (ret < 0) {
+                       if (i)
+                               av7110_ipack_free(--ipack);
+                       goto out;
+               }
+               ipack->data = av7110;
+       }
+
+       dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
+       dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);
+
+       av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);
+       av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;
+out:
+       return ret;
+}
+
+void av7110_av_exit(struct av7110 *av7110)
+{
+       av7110_ipack_free(&av7110->ipack[0]);
+       av7110_ipack_free(&av7110->ipack[1]);
+}
diff --git a/drivers/media/pci/ttpci/av7110_av.h b/drivers/media/pci/ttpci/av7110_av.h
new file mode 100644 (file)
index 0000000..5f02ef8
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _AV7110_AV_H_
+#define _AV7110_AV_H_
+
+struct av7110;
+
+extern int av7110_set_vidmode(struct av7110 *av7110,
+                             enum av7110_video_mode mode);
+
+extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
+extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
+extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
+
+extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
+extern int av7110_av_stop(struct av7110 *av7110, int av);
+extern int av7110_av_start_record(struct av7110 *av7110, int av,
+                         struct dvb_demux_feed *dvbdmxfeed);
+extern int av7110_av_start_play(struct av7110 *av7110, int av);
+
+extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
+
+extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
+extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
+
+extern int av7110_av_register(struct av7110 *av7110);
+extern void av7110_av_unregister(struct av7110 *av7110);
+extern int av7110_av_init(struct av7110 *av7110);
+extern void av7110_av_exit(struct av7110 *av7110);
+
+
+#endif /* _AV7110_AV_H_ */
diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c
new file mode 100644 (file)
index 0000000..9fc1dd0
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ * av7110_ca.c: CA and CI stuff
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * originally based on code by:
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+#include <linux/gfp.h>
+
+#include "av7110.h"
+#include "av7110_hw.h"
+#include "av7110_ca.h"
+
+
+void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
+{
+       dprintk(8, "av7110:%p\n",av7110);
+
+       if (len < 3)
+               return;
+       switch (data[0]) {
+       case CI_MSG_CI_INFO:
+               if (data[2] != 1 && data[2] != 2)
+                       break;
+               switch (data[1]) {
+               case 0:
+                       av7110->ci_slot[data[2] - 1].flags = 0;
+                       break;
+               case 1:
+                       av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT;
+                       break;
+               case 2:
+                       av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY;
+                       break;
+               }
+               break;
+       case CI_SWITCH_PRG_REPLY:
+               //av7110->ci_stat=data[1];
+               break;
+       default:
+               break;
+       }
+}
+
+
+void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
+{
+       if (dvb_ringbuffer_free(cibuf) < len + 2)
+               return;
+
+       DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8);
+       DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff);
+       dvb_ringbuffer_write(cibuf, data, len);
+       wake_up_interruptible(&cibuf->queue);
+}
+
+
+/******************************************************************************
+ * CI link layer file ops
+ ******************************************************************************/
+
+static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
+{
+       struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p;
+       void *data;
+
+       for (p = tab; *p; p++) {
+               data = vmalloc(size);
+               if (!data) {
+                       while (p-- != tab) {
+                               vfree(p[0]->data);
+                               p[0]->data = NULL;
+                       }
+                       return -ENOMEM;
+               }
+               dvb_ringbuffer_init(*p, data, size);
+       }
+       return 0;
+}
+
+static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
+{
+       dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
+       dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
+}
+
+static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
+{
+       vfree(cirbuf->data);
+       cirbuf->data = NULL;
+       vfree(ciwbuf->data);
+       ciwbuf->data = NULL;
+}
+
+static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
+                      int slots, ca_slot_info_t *slot)
+{
+       int i;
+       int len = 0;
+       u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 };
+
+       for (i = 0; i < 2; i++) {
+               if (slots & (1 << i))
+                       len += 8;
+       }
+
+       if (dvb_ringbuffer_free(cibuf) < len)
+               return -EBUSY;
+
+       for (i = 0; i < 2; i++) {
+               if (slots & (1 << i)) {
+                       msg[2] = i;
+                       dvb_ringbuffer_write(cibuf, msg, 8);
+                       slot[i].flags = 0;
+               }
+       }
+
+       return 0;
+}
+
+static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file,
+                          const char __user *buf, size_t count, loff_t *ppos)
+{
+       int free;
+       int non_blocking = file->f_flags & O_NONBLOCK;
+       u8 *page = (u8 *)__get_free_page(GFP_USER);
+       int res;
+
+       if (!page)
+               return -ENOMEM;
+
+       res = -EINVAL;
+       if (count > 2048)
+               goto out;
+
+       res = -EFAULT;
+       if (copy_from_user(page, buf, count))
+               goto out;
+
+       free = dvb_ringbuffer_free(cibuf);
+       if (count + 2 > free) {
+               res = -EWOULDBLOCK;
+               if (non_blocking)
+                       goto out;
+               res = -ERESTARTSYS;
+               if (wait_event_interruptible(cibuf->queue,
+                                            (dvb_ringbuffer_free(cibuf) >= count + 2)))
+                       goto out;
+       }
+
+       DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8);
+       DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff);
+
+       res = dvb_ringbuffer_write(cibuf, page, count);
+out:
+       free_page((unsigned long)page);
+       return res;
+}
+
+static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
+                         char __user *buf, size_t count, loff_t *ppos)
+{
+       int avail;
+       int non_blocking = file->f_flags & O_NONBLOCK;
+       ssize_t len;
+
+       if (!cibuf->data || !count)
+               return 0;
+       if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
+               return -EWOULDBLOCK;
+       if (wait_event_interruptible(cibuf->queue,
+                                    !dvb_ringbuffer_empty(cibuf)))
+               return -ERESTARTSYS;
+       avail = dvb_ringbuffer_avail(cibuf);
+       if (avail < 4)
+               return 0;
+       len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
+       len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
+       if (avail < len + 2 || count < len)
+               return -EINVAL;
+       DVB_RINGBUFFER_SKIP(cibuf, 2);
+
+       return dvb_ringbuffer_read_user(cibuf, buf, len);
+}
+
+static int dvb_ca_open(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       int err = dvb_generic_open(inode, file);
+
+       dprintk(8, "av7110:%p\n",av7110);
+
+       if (err < 0)
+               return err;
+       ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
+       return 0;
+}
+
+static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
+       struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
+       unsigned int mask = 0;
+
+       dprintk(8, "av7110:%p\n",av7110);
+
+       poll_wait(file, &rbuf->queue, wait);
+       poll_wait(file, &wbuf->queue, wait);
+
+       if (!dvb_ringbuffer_empty(rbuf))
+               mask |= (POLLIN | POLLRDNORM);
+
+       if (dvb_ringbuffer_free(wbuf) > 1024)
+               mask |= (POLLOUT | POLLWRNORM);
+
+       return mask;
+}
+
+static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+       unsigned long arg = (unsigned long) parg;
+
+       dprintk(8, "av7110:%p\n",av7110);
+
+       switch (cmd) {
+       case CA_RESET:
+               return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]);
+               break;
+       case CA_GET_CAP:
+       {
+               ca_caps_t cap;
+
+               cap.slot_num = 2;
+               cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ?
+                                CA_CI_LINK : CA_CI) | CA_DESCR;
+               cap.descr_num = 16;
+               cap.descr_type = CA_ECD;
+               memcpy(parg, &cap, sizeof(cap));
+               break;
+       }
+
+       case CA_GET_SLOT_INFO:
+       {
+               ca_slot_info_t *info=(ca_slot_info_t *)parg;
+
+               if (info->num < 0 || info->num > 1)
+                       return -EINVAL;
+               av7110->ci_slot[info->num].num = info->num;
+               av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
+                                                       CA_CI_LINK : CA_CI;
+               memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
+               break;
+       }
+
+       case CA_GET_MSG:
+               break;
+
+       case CA_SEND_MSG:
+               break;
+
+       case CA_GET_DESCR_INFO:
+       {
+               ca_descr_info_t info;
+
+               info.num = 16;
+               info.type = CA_ECD;
+               memcpy(parg, &info, sizeof (info));
+               break;
+       }
+
+       case CA_SET_DESCR:
+       {
+               ca_descr_t *descr = (ca_descr_t*) parg;
+
+               if (descr->index >= 16)
+                       return -EINVAL;
+               if (descr->parity > 1)
+                       return -EINVAL;
+               av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
+                             (descr->index<<8)|descr->parity,
+                             (descr->cw[0]<<8)|descr->cw[1],
+                             (descr->cw[2]<<8)|descr->cw[3],
+                             (descr->cw[4]<<8)|descr->cw[5],
+                             (descr->cw[6]<<8)|descr->cw[7]);
+               break;
+       }
+
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
+                           size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+
+       dprintk(8, "av7110:%p\n",av7110);
+       return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
+}
+
+static ssize_t dvb_ca_read(struct file *file, char __user *buf,
+                          size_t count, loff_t *ppos)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct av7110 *av7110 = dvbdev->priv;
+
+       dprintk(8, "av7110:%p\n",av7110);
+       return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
+}
+
+static const struct file_operations dvb_ca_fops = {
+       .owner          = THIS_MODULE,
+       .read           = dvb_ca_read,
+       .write          = dvb_ca_write,
+       .unlocked_ioctl = dvb_generic_ioctl,
+       .open           = dvb_ca_open,
+       .release        = dvb_generic_release,
+       .poll           = dvb_ca_poll,
+       .llseek         = default_llseek,
+};
+
+static struct dvb_device dvbdev_ca = {
+       .priv           = NULL,
+       .users          = 1,
+       .writers        = 1,
+       .fops           = &dvb_ca_fops,
+       .kernel_ioctl   = dvb_ca_ioctl,
+};
+
+
+int av7110_ca_register(struct av7110 *av7110)
+{
+       return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
+                                  &dvbdev_ca, av7110, DVB_DEVICE_CA);
+}
+
+void av7110_ca_unregister(struct av7110 *av7110)
+{
+       dvb_unregister_device(av7110->ca_dev);
+}
+
+int av7110_ca_init(struct av7110* av7110)
+{
+       return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
+}
+
+void av7110_ca_exit(struct av7110* av7110)
+{
+       ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
+}
diff --git a/drivers/media/pci/ttpci/av7110_ca.h b/drivers/media/pci/ttpci/av7110_ca.h
new file mode 100644 (file)
index 0000000..70ee855
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _AV7110_CA_H_
+#define _AV7110_CA_H_
+
+struct av7110;
+
+extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
+extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
+
+extern int av7110_ca_register(struct av7110 *av7110);
+extern void av7110_ca_unregister(struct av7110 *av7110);
+extern int av7110_ca_init(struct av7110* av7110);
+extern void av7110_ca_exit(struct av7110* av7110);
+
+#endif /* _AV7110_CA_H_ */
diff --git a/drivers/media/pci/ttpci/av7110_hw.c b/drivers/media/pci/ttpci/av7110_hw.c
new file mode 100644 (file)
index 0000000..f1cbfe5
--- /dev/null
@@ -0,0 +1,1208 @@
+/*
+ * av7110_hw.c: av7110 low level hardware access and firmware interface
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * originally based on code by:
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+/* for debugging ARM communication: */
+//#define COM_DEBUG
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+
+#include "av7110.h"
+#include "av7110_hw.h"
+
+#define _NOHANDSHAKE
+
+/****************************************************************************
+ * DEBI functions
+ ****************************************************************************/
+
+/* This DEBI code is based on the Stradis driver
+   by Nathan Laredo <laredo@gnu.org> */
+
+int av7110_debiwrite(struct av7110 *av7110, u32 config,
+                    int addr, u32 val, int count)
+{
+       struct saa7146_dev *dev = av7110->dev;
+
+       if (count <= 0 || count > 32764) {
+               printk("%s: invalid count %d\n", __func__, count);
+               return -1;
+       }
+       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
+               printk("%s: wait_for_debi_done failed\n", __func__);
+               return -1;
+       }
+       saa7146_write(dev, DEBI_CONFIG, config);
+       if (count <= 4)         /* immediate transfer */
+               saa7146_write(dev, DEBI_AD, val);
+       else                    /* block transfer */
+               saa7146_write(dev, DEBI_AD, av7110->debi_bus);
+       saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
+       saa7146_write(dev, MC2, (2 << 16) | 2);
+       return 0;
+}
+
+u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
+{
+       struct saa7146_dev *dev = av7110->dev;
+       u32 result = 0;
+
+       if (count > 32764 || count <= 0) {
+               printk("%s: invalid count %d\n", __func__, count);
+               return 0;
+       }
+       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
+               printk("%s: wait_for_debi_done #1 failed\n", __func__);
+               return 0;
+       }
+       saa7146_write(dev, DEBI_AD, av7110->debi_bus);
+       saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
+
+       saa7146_write(dev, DEBI_CONFIG, config);
+       saa7146_write(dev, MC2, (2 << 16) | 2);
+       if (count > 4)
+               return count;
+       if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
+               printk("%s: wait_for_debi_done #2 failed\n", __func__);
+               return 0;
+       }
+
+       result = saa7146_read(dev, DEBI_AD);
+       result &= (0xffffffffUL >> ((4 - count) * 8));
+       return result;
+}
+
+
+
+/* av7110 ARM core boot stuff */
+#if 0
+void av7110_reset_arm(struct av7110 *av7110)
+{
+       saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
+
+       /* Disable DEBI and GPIO irq */
+       SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
+       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
+
+       saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
+       msleep(30);     /* the firmware needs some time to initialize */
+
+       ARM_ResetMailBox(av7110);
+
+       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
+       SAA7146_IER_ENABLE(av7110->dev, MASK_03);
+
+       av7110->arm_ready = 1;
+       dprintk(1, "reset ARM\n");
+}
+#endif  /*  0  */
+
+static int waitdebi(struct av7110 *av7110, int adr, int state)
+{
+       int k;
+
+       dprintk(4, "%p\n", av7110);
+
+       for (k = 0; k < 100; k++) {
+               if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
+                       return 0;
+               udelay(5);
+       }
+       return -ETIMEDOUT;
+}
+
+static int load_dram(struct av7110 *av7110, u32 *data, int len)
+{
+       int i;
+       int blocks, rest;
+       u32 base, bootblock = AV7110_BOOT_BLOCK;
+
+       dprintk(4, "%p\n", av7110);
+
+       blocks = len / AV7110_BOOT_MAX_SIZE;
+       rest = len % AV7110_BOOT_MAX_SIZE;
+       base = DRAM_START_CODE;
+
+       for (i = 0; i < blocks; i++) {
+               if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+                       printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
+                       return -ETIMEDOUT;
+               }
+               dprintk(4, "writing DRAM block %d\n", i);
+               mwdebi(av7110, DEBISWAB, bootblock,
+                      ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE);
+               bootblock ^= 0x1400;
+               iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
+               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2);
+               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
+               base += AV7110_BOOT_MAX_SIZE;
+       }
+
+       if (rest > 0) {
+               if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+                       printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
+                       return -ETIMEDOUT;
+               }
+               if (rest > 4)
+                       mwdebi(av7110, DEBISWAB, bootblock,
+                              ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest);
+               else
+                       mwdebi(av7110, DEBISWAB, bootblock,
+                              ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4);
+
+               iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
+               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2);
+               iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
+       }
+       if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+               printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
+               return -ETIMEDOUT;
+       }
+       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2);
+       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
+       if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) {
+               printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
+               return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+
+/* we cannot write av7110 DRAM directly, so load a bootloader into
+ * the DPRAM which implements a simple boot protocol */
+int av7110_bootarm(struct av7110 *av7110)
+{
+       const struct firmware *fw;
+       const char *fw_name = "av7110/bootcode.bin";
+       struct saa7146_dev *dev = av7110->dev;
+       u32 ret;
+       int i;
+
+       dprintk(4, "%p\n", av7110);
+
+       av7110->arm_ready = 0;
+
+       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
+
+       /* Disable DEBI and GPIO irq */
+       SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
+       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
+
+       /* enable DEBI */
+       saa7146_write(av7110->dev, MC1, 0x08800880);
+       saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
+       saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+       /* test DEBI */
+       iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
+       /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
+       iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
+
+       if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
+               printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
+                      "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
+                      ret, 0x10325476);
+               return -1;
+       }
+       for (i = 0; i < 8192; i += 4)
+               iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
+       dprintk(2, "debi test OK\n");
+
+       /* boot */
+       dprintk(1, "load boot code\n");
+       saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
+       //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
+       //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
+
+       ret = request_firmware(&fw, fw_name, &dev->pci->dev);
+       if (ret) {
+               printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
+                       fw_name);
+               return ret;
+       }
+
+       mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
+       release_firmware(fw);
+       iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
+
+       if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
+               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
+                      "saa7146_wait_for_debi_done() timed out\n");
+               return -ETIMEDOUT;
+       }
+       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
+       mdelay(1);
+
+       dprintk(1, "load dram code\n");
+       if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
+               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
+                      "load_dram() failed\n");
+               return -1;
+       }
+
+       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
+       mdelay(1);
+
+       dprintk(1, "load dpram code\n");
+       mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
+
+       if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
+               printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
+                      "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
+               return -ETIMEDOUT;
+       }
+       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
+       msleep(30);     /* the firmware needs some time to initialize */
+
+       //ARM_ClearIrq(av7110);
+       ARM_ResetMailBox(av7110);
+       SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
+       SAA7146_IER_ENABLE(av7110->dev, MASK_03);
+
+       av7110->arm_errors = 0;
+       av7110->arm_ready = 1;
+       return 0;
+}
+MODULE_FIRMWARE("av7110/bootcode.bin");
+
+/****************************************************************************
+ * DEBI command polling
+ ****************************************************************************/
+
+int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
+{
+       unsigned long start;
+       u32 stat;
+       int err;
+
+       if (FW_VERSION(av7110->arm_app) <= 0x261c) {
+               /* not supported by old firmware */
+               msleep(50);
+               return 0;
+       }
+
+       /* new firmware */
+       start = jiffies;
+       for (;;) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (mutex_lock_interruptible(&av7110->dcomlock))
+                       return -ERESTARTSYS;
+               stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
+               mutex_unlock(&av7110->dcomlock);
+               if ((stat & flags) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
+                               __func__, stat & flags);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+       return 0;
+}
+
+static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+{
+       int i;
+       unsigned long start;
+       char *type = NULL;
+       u16 flags[2] = {0, 0};
+       u32 stat;
+       int err;
+
+//     dprintk(4, "%p\n", av7110);
+
+       if (!av7110->arm_ready) {
+               dprintk(1, "arm not ready.\n");
+               return -ENXIO;
+       }
+
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
+                       av7110->arm_errors++;
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+
+       if (FW_VERSION(av7110->arm_app) <= 0x261f)
+               wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
+
+#ifndef _NOHANDSHAKE
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+#endif
+
+       switch ((buf[0] >> 8) & 0xff) {
+       case COMTYPE_PIDFILTER:
+       case COMTYPE_ENCODER:
+       case COMTYPE_REC_PLAY:
+       case COMTYPE_MPEGDECODER:
+               type = "MSG";
+               flags[0] = GPMQOver;
+               flags[1] = GPMQFull;
+               break;
+       case COMTYPE_OSD:
+               type = "OSD";
+               flags[0] = OSDQOver;
+               flags[1] = OSDQFull;
+               break;
+       case COMTYPE_MISC:
+               if (FW_VERSION(av7110->arm_app) >= 0x261d) {
+                       type = "MSG";
+                       flags[0] = GPMQOver;
+                       flags[1] = GPMQBusy;
+               }
+               break;
+       default:
+               break;
+       }
+
+       if (type != NULL) {
+               /* non-immediate COMMAND type */
+               start = jiffies;
+               for (;;) {
+                       err = time_after(jiffies, start + ARM_WAIT_FREE);
+                       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
+                       if (stat & flags[0]) {
+                               printk(KERN_ERR "%s: %s QUEUE overflow\n",
+                                       __func__, type);
+                               return -1;
+                       }
+                       if ((stat & flags[1]) == 0)
+                               break;
+                       if (err) {
+                               printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
+                                       __func__, type);
+                               av7110->arm_errors++;
+                               return -ETIMEDOUT;
+                       }
+                       msleep(1);
+               }
+       }
+
+       for (i = 2; i < length; i++)
+               wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
+
+       if (length)
+               wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
+       else
+               wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
+
+       wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
+
+       if (FW_VERSION(av7110->arm_app) <= 0x261f)
+               wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
+
+#ifdef COM_DEBUG
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
+                              __func__, (buf[0] >> 8) & 0xff);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+
+       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
+       if (stat & GPMQOver) {
+               printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__);
+               return -ENOSPC;
+       }
+       else if (stat & OSDQOver) {
+               printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__);
+               return -ENOSPC;
+       }
+#endif
+
+       return 0;
+}
+
+static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+{
+       int ret;
+
+//     dprintk(4, "%p\n", av7110);
+
+       if (!av7110->arm_ready) {
+               dprintk(1, "arm not ready.\n");
+               return -1;
+       }
+       if (mutex_lock_interruptible(&av7110->dcomlock))
+               return -ERESTARTSYS;
+
+       ret = __av7110_send_fw_cmd(av7110, buf, length);
+       mutex_unlock(&av7110->dcomlock);
+       if (ret && ret!=-ERESTARTSYS)
+               printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
+                      __func__, ret);
+       return ret;
+}
+
+int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
+{
+       va_list args;
+       u16 buf[num + 2];
+       int i, ret;
+
+//     dprintk(4, "%p\n", av7110);
+
+       buf[0] = ((type << 8) | com);
+       buf[1] = num;
+
+       if (num) {
+               va_start(args, num);
+               for (i = 0; i < num; i++)
+                       buf[i + 2] = va_arg(args, u32);
+               va_end(args);
+       }
+
+       ret = av7110_send_fw_cmd(av7110, buf, num + 2);
+       if (ret && ret != -ERESTARTSYS)
+               printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
+       return ret;
+}
+
+#if 0
+int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
+{
+       int i, ret;
+       u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
+               16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+       dprintk(4, "%p\n", av7110);
+
+       for(i = 0; i < len && i < 32; i++)
+       {
+               if(i % 2 == 0)
+                       cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
+               else
+                       cmd[(i / 2) + 2] |= buf[i];
+       }
+
+       ret = av7110_send_fw_cmd(av7110, cmd, 18);
+       if (ret && ret != -ERESTARTSYS)
+               printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
+       return ret;
+}
+#endif  /*  0  */
+
+int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
+                     int request_buf_len, u16 *reply_buf, int reply_buf_len)
+{
+       int err;
+       s16 i;
+       unsigned long start;
+#ifdef COM_DEBUG
+       u32 stat;
+#endif
+
+       dprintk(4, "%p\n", av7110);
+
+       if (!av7110->arm_ready) {
+               dprintk(1, "arm not ready.\n");
+               return -1;
+       }
+
+       if (mutex_lock_interruptible(&av7110->dcomlock))
+               return -ERESTARTSYS;
+
+       if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
+               mutex_unlock(&av7110->dcomlock);
+               printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
+               return err;
+       }
+
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
+                       mutex_unlock(&av7110->dcomlock);
+                       return -ETIMEDOUT;
+               }
+#ifdef _NOHANDSHAKE
+               msleep(1);
+#endif
+       }
+
+#ifndef _NOHANDSHAKE
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
+                       mutex_unlock(&av7110->dcomlock);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+#endif
+
+#ifdef COM_DEBUG
+       stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
+       if (stat & GPMQOver) {
+               printk(KERN_ERR "%s: GPMQOver\n", __func__);
+               mutex_unlock(&av7110->dcomlock);
+               return -1;
+       }
+       else if (stat & OSDQOver) {
+               printk(KERN_ERR "%s: OSDQOver\n", __func__);
+               mutex_unlock(&av7110->dcomlock);
+               return -1;
+       }
+#endif
+
+       for (i = 0; i < reply_buf_len; i++)
+               reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
+
+       mutex_unlock(&av7110->dcomlock);
+       return 0;
+}
+
+static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
+{
+       int ret;
+       ret = av7110_fw_request(av7110, &tag, 0, buf, length);
+       if (ret)
+               printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
+       return ret;
+}
+
+
+/****************************************************************************
+ * Firmware commands
+ ****************************************************************************/
+
+/* get version of the firmware ROM, RTSL, video ucode and ARM application  */
+int av7110_firmversion(struct av7110 *av7110)
+{
+       u16 buf[20];
+       u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
+
+       dprintk(4, "%p\n", av7110);
+
+       if (av7110_fw_query(av7110, tag, buf, 16)) {
+               printk("dvb-ttpci: failed to boot firmware @ card %d\n",
+                      av7110->dvb_adapter.num);
+               return -EIO;
+       }
+
+       av7110->arm_fw = (buf[0] << 16) + buf[1];
+       av7110->arm_rtsl = (buf[2] << 16) + buf[3];
+       av7110->arm_vid = (buf[4] << 16) + buf[5];
+       av7110->arm_app = (buf[6] << 16) + buf[7];
+       av7110->avtype = (buf[8] << 16) + buf[9];
+
+       printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
+              av7110->dvb_adapter.num, av7110->arm_fw,
+              av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
+
+       /* print firmware capabilities */
+       if (FW_CI_LL_SUPPORT(av7110->arm_app))
+               printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
+                      av7110->dvb_adapter.num);
+       else
+               printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
+                      av7110->dvb_adapter.num);
+
+       return 0;
+}
+
+
+int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
+{
+       int i, ret;
+       u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
+                       16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+       dprintk(4, "%p\n", av7110);
+
+       if (len > 10)
+               len = 10;
+
+       buf[1] = len + 2;
+       buf[2] = len;
+
+       if (burst != -1)
+               buf[3] = burst ? 0x01 : 0x00;
+       else
+               buf[3] = 0xffff;
+
+       for (i = 0; i < len; i++)
+               buf[i + 4] = msg[i];
+
+       ret = av7110_send_fw_cmd(av7110, buf, 18);
+       if (ret && ret!=-ERESTARTSYS)
+               printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
+       return ret;
+}
+
+
+#ifdef CONFIG_DVB_AV7110_OSD
+
+static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
+}
+
+static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
+                    enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
+                            windownr, colordepth, index, blending);
+}
+
+static inline int SetColor_(struct av7110 *av7110, u8 windownr,
+                    enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
+                            windownr, colordepth, index, colorhi, colorlo);
+}
+
+static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
+                         u16 colorfg, u16 colorbg)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
+                            windownr, fontsize, colorfg, colorbg);
+}
+
+static int FlushText(struct av7110 *av7110)
+{
+       unsigned long start;
+       int err;
+
+       if (mutex_lock_interruptible(&av7110->dcomlock))
+               return -ERESTARTSYS;
+       start = jiffies;
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_OSD);
+               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+                       break;
+               if (err) {
+                       printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
+                              __func__);
+                       mutex_unlock(&av7110->dcomlock);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+       mutex_unlock(&av7110->dcomlock);
+       return 0;
+}
+
+static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
+{
+       int i, ret;
+       unsigned long start;
+       int length = strlen(buf) + 1;
+       u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
+
+       if (mutex_lock_interruptible(&av7110->dcomlock))
+               return -ERESTARTSYS;
+
+       start = jiffies;
+       while (1) {
+               ret = time_after(jiffies, start + ARM_WAIT_OSD);
+               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+                       break;
+               if (ret) {
+                       printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
+                              __func__);
+                       mutex_unlock(&av7110->dcomlock);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+#ifndef _NOHANDSHAKE
+       start = jiffies;
+       while (1) {
+               ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (ret) {
+                       printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
+                              __func__);
+                       mutex_unlock(&av7110->dcomlock);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+#endif
+       for (i = 0; i < length / 2; i++)
+               wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
+                     swab16(*(u16 *)(buf + 2 * i)), 2);
+       if (length & 1)
+               wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
+       ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
+       mutex_unlock(&av7110->dcomlock);
+       if (ret && ret!=-ERESTARTSYS)
+               printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
+       return ret;
+}
+
+static inline int DrawLine(struct av7110 *av7110, u8 windownr,
+                          u16 x, u16 y, u16 dx, u16 dy, u16 color)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
+                            windownr, x, y, dx, dy, color);
+}
+
+static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
+                           u16 x, u16 y, u16 dx, u16 dy, u16 color)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
+                            windownr, x, y, dx, dy, color);
+}
+
+static inline int HideWindow(struct av7110 *av7110, u8 windownr)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
+}
+
+static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
+}
+
+static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
+}
+
+static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
+}
+
+static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
+                                 osd_raw_window_t disptype,
+                                 u16 width, u16 height)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
+                            windownr, disptype, width, height);
+}
+
+
+static enum av7110_osd_palette_type bpp2pal[8] = {
+       Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
+};
+static osd_raw_window_t bpp2bit[8] = {
+       OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
+};
+
+static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
+{
+       int ret = wait_event_timeout(av7110->bmpq,
+                               av7110->bmp_state != BMP_LOADING, 10*HZ);
+       if (ret == 0) {
+               printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
+                      ret, av7110->bmp_state);
+               av7110->bmp_state = BMP_NONE;
+               return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+static inline int LoadBitmap(struct av7110 *av7110,
+                            u16 dx, u16 dy, int inc, u8 __user * data)
+{
+       u16 format;
+       int bpp;
+       int i;
+       int d, delta;
+       u8 c;
+       int ret;
+
+       dprintk(4, "%p\n", av7110);
+
+       format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
+
+       av7110->bmp_state = BMP_LOADING;
+       if      (format == OSD_BITMAP8) {
+               bpp=8; delta = 1;
+       } else if (format == OSD_BITMAP4) {
+               bpp=4; delta = 2;
+       } else if (format == OSD_BITMAP2) {
+               bpp=2; delta = 4;
+       } else if (format == OSD_BITMAP1) {
+               bpp=1; delta = 8;
+       } else {
+               av7110->bmp_state = BMP_NONE;
+               return -EINVAL;
+       }
+       av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
+       av7110->bmpp = 0;
+       if (av7110->bmplen > 32768) {
+               av7110->bmp_state = BMP_NONE;
+               return -EINVAL;
+       }
+       for (i = 0; i < dy; i++) {
+               if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
+                       av7110->bmp_state = BMP_NONE;
+                       return -EINVAL;
+               }
+       }
+       if (format != OSD_BITMAP8) {
+               for (i = 0; i < dx * dy / delta; i++) {
+                       c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
+                       for (d = delta - 2; d >= 0; d--) {
+                               c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
+                                     << ((delta - d - 1) * bpp));
+                               ((u8 *)av7110->bmpbuf)[1024 + i] = c;
+                       }
+               }
+       }
+       av7110->bmplen += 1024;
+       dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
+       ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
+       if (!ret)
+               ret = WaitUntilBmpLoaded(av7110);
+       return ret;
+}
+
+static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
+{
+       dprintk(4, "%p\n", av7110);
+
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
+}
+
+static inline int ReleaseBitmap(struct av7110 *av7110)
+{
+       dprintk(4, "%p\n", av7110);
+
+       if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
+               return -1;
+       if (av7110->bmp_state == BMP_LOADING)
+               dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
+       av7110->bmp_state = BMP_NONE;
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
+}
+
+static u32 RGB2YUV(u16 R, u16 G, u16 B)
+{
+       u16 y, u, v;
+       u16 Y, Cr, Cb;
+
+       y = R * 77 + G * 150 + B * 29;  /* Luma=0.299R+0.587G+0.114B 0..65535 */
+       u = 2048 + B * 8 -(y >> 5);     /* Cr 0..4095 */
+       v = 2048 + R * 8 -(y >> 5);     /* Cb 0..4095 */
+
+       Y = y / 256;
+       Cb = u / 16;
+       Cr = v / 16;
+
+       return Cr | (Cb << 16) | (Y << 8);
+}
+
+static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
+{
+       int ret;
+
+       u16 ch, cl;
+       u32 yuv;
+
+       yuv = blend ? RGB2YUV(r,g,b) : 0;
+       cl = (yuv & 0xffff);
+       ch = ((yuv >> 16) & 0xffff);
+       ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+                       color, ch, cl);
+       if (!ret)
+               ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+                               color, ((blend >> 4) & 0x0f));
+       return ret;
+}
+
+static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
+{
+       int i;
+       int length = last - first + 1;
+
+       if (length * 4 > DATA_BUFF3_SIZE)
+               return -EINVAL;
+
+       for (i = 0; i < length; i++) {
+               u32 color, blend, yuv;
+
+               if (get_user(color, colors + i))
+                       return -EFAULT;
+               blend = (color & 0xF0000000) >> 4;
+               yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
+                                    (color >> 16) & 0xFF) | blend : 0;
+               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
+               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
+       }
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
+                           av7110->osdwin,
+                           bpp2pal[av7110->osdbpp[av7110->osdwin]],
+                           first, last);
+}
+
+static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
+                      int x1, int y1, int inc, u8 __user * data)
+{
+       uint w, h, bpp, bpl, size, lpb, bnum, brest;
+       int i;
+       int rc,release_rc;
+
+       w = x1 - x0 + 1;
+       h = y1 - y0 + 1;
+       if (inc <= 0)
+               inc = w;
+       if (w <= 0 || w > 720 || h <= 0 || h > 576)
+               return -EINVAL;
+       bpp = av7110->osdbpp[av7110->osdwin] + 1;
+       bpl = ((w * bpp + 7) & ~7) / 8;
+       size = h * bpl;
+       lpb = (32 * 1024) / bpl;
+       bnum = size / (lpb * bpl);
+       brest = size - bnum * lpb * bpl;
+
+       if (av7110->bmp_state == BMP_LOADING) {
+               /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
+               BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
+               rc = WaitUntilBmpLoaded(av7110);
+               if (rc)
+                       return rc;
+               /* just continue. This should work for all fw versions
+                * if bnum==1 && !brest && LoadBitmap was successful
+                */
+       }
+
+       rc = 0;
+       for (i = 0; i < bnum; i++) {
+               rc = LoadBitmap(av7110, w, lpb, inc, data);
+               if (rc)
+                       break;
+               rc = BlitBitmap(av7110, x0, y0 + i * lpb);
+               if (rc)
+                       break;
+               data += lpb * inc;
+       }
+       if (!rc && brest) {
+               rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
+               if (!rc)
+                       rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
+       }
+       release_rc = ReleaseBitmap(av7110);
+       if (!rc)
+               rc = release_rc;
+       if (rc)
+               dprintk(1,"returns %d\n",rc);
+       return rc;
+}
+
+int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&av7110->osd_mutex))
+               return -ERESTARTSYS;
+
+       switch (dc->cmd) {
+       case OSD_Close:
+               ret = DestroyOSDWindow(av7110, av7110->osdwin);
+               break;
+       case OSD_Open:
+               av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
+               ret = CreateOSDWindow(av7110, av7110->osdwin,
+                               bpp2bit[av7110->osdbpp[av7110->osdwin]],
+                               dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+               if (ret)
+                       break;
+               if (!dc->data) {
+                       ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+                       if (ret)
+                               break;
+                       ret = SetColorBlend(av7110, av7110->osdwin);
+               }
+               break;
+       case OSD_Show:
+               ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
+               break;
+       case OSD_Hide:
+               ret = HideWindow(av7110, av7110->osdwin);
+               break;
+       case OSD_Clear:
+               ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
+               break;
+       case OSD_Fill:
+               ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
+               break;
+       case OSD_SetColor:
+               ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
+               break;
+       case OSD_SetPalette:
+               if (FW_VERSION(av7110->arm_app) >= 0x2618)
+                       ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
+               else {
+                       int i, len = dc->x0-dc->color+1;
+                       u8 __user *colors = (u8 __user *)dc->data;
+                       u8 r, g = 0, b = 0, blend = 0;
+                       ret = 0;
+                       for (i = 0; i<len; i++) {
+                               if (get_user(r, colors + i * 4) ||
+                                   get_user(g, colors + i * 4 + 1) ||
+                                   get_user(b, colors + i * 4 + 2) ||
+                                   get_user(blend, colors + i * 4 + 3)) {
+                                       ret = -EFAULT;
+                                       break;
+                                   }
+                               ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
+                               if (ret)
+                                       break;
+                       }
+               }
+               break;
+       case OSD_SetPixel:
+               ret = DrawLine(av7110, av7110->osdwin,
+                        dc->x0, dc->y0, 0, 0, dc->color);
+               break;
+       case OSD_SetRow:
+               dc->y1 = dc->y0;
+               /* fall through */
+       case OSD_SetBlock:
+               ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
+               break;
+       case OSD_FillRow:
+               ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+                         dc->x1-dc->x0+1, dc->y1, dc->color);
+               break;
+       case OSD_FillBlock:
+               ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+                         dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
+               break;
+       case OSD_Line:
+               ret = DrawLine(av7110, av7110->osdwin,
+                        dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
+               break;
+       case OSD_Text:
+       {
+               char textbuf[240];
+
+               if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
+                       ret = -EFAULT;
+                       break;
+               }
+               textbuf[239] = 0;
+               if (dc->x1 > 3)
+                       dc->x1 = 3;
+               ret = SetFont(av7110, av7110->osdwin, dc->x1,
+                       (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
+               if (!ret)
+                       ret = FlushText(av7110);
+               if (!ret)
+                       ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
+               break;
+       }
+       case OSD_SetWindow:
+               if (dc->x0 < 1 || dc->x0 > 7)
+                       ret = -EINVAL;
+               else {
+                       av7110->osdwin = dc->x0;
+                       ret = 0;
+               }
+               break;
+       case OSD_MoveWindow:
+               ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+               if (!ret)
+                       ret = SetColorBlend(av7110, av7110->osdwin);
+               break;
+       case OSD_OpenRaw:
+               if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
+                       ret = -EINVAL;
+                       break;
+               }
+               if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
+                       av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
+               else
+                       av7110->osdbpp[av7110->osdwin] = 0;
+               ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
+                               dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+               if (ret)
+                       break;
+               if (!dc->data) {
+                       ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+                       if (!ret)
+                               ret = SetColorBlend(av7110, av7110->osdwin);
+               }
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       mutex_unlock(&av7110->osd_mutex);
+       if (ret==-ERESTARTSYS)
+               dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
+       else if (ret)
+               dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
+
+       return ret;
+}
+
+int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
+{
+       switch (cap->cmd) {
+       case OSD_CAP_MEMSIZE:
+               if (FW_4M_SDRAM(av7110->arm_app))
+                       cap->val = 1000000;
+               else
+                       cap->val = 92000;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+#endif /* CONFIG_DVB_AV7110_OSD */
diff --git a/drivers/media/pci/ttpci/av7110_hw.h b/drivers/media/pci/ttpci/av7110_hw.h
new file mode 100644 (file)
index 0000000..1634aba
--- /dev/null
@@ -0,0 +1,495 @@
+#ifndef _AV7110_HW_H_
+#define _AV7110_HW_H_
+
+#include "av7110.h"
+
+/* DEBI transfer mode defs */
+
+#define DEBINOSWAP 0x000e0000
+#define DEBISWAB   0x001e0000
+#define DEBISWAP   0x002e0000
+
+#define ARM_WAIT_FREE  (HZ)
+#define ARM_WAIT_SHAKE (HZ/5)
+#define ARM_WAIT_OSD (HZ)
+
+
+enum av7110_bootstate
+{
+       BOOTSTATE_BUFFER_EMPTY  = 0,
+       BOOTSTATE_BUFFER_FULL   = 1,
+       BOOTSTATE_AV7110_BOOT_COMPLETE  = 2
+};
+
+enum av7110_type_rec_play_format
+{      RP_None,
+       AudioPES,
+       AudioMp2,
+       AudioPCM,
+       VideoPES,
+       AV_PES
+};
+
+enum av7110_osd_palette_type
+{
+       NoPalet =  0,      /* No palette */
+       Pal1Bit =  2,      /* 2 colors for 1 Bit Palette    */
+       Pal2Bit =  4,      /* 4 colors for 2 bit palette    */
+       Pal4Bit =  16,     /* 16 colors for 4 bit palette   */
+       Pal8Bit =  256     /* 256 colors for 16 bit palette */
+};
+
+/* switch defines */
+#define SB_GPIO 3
+#define SB_OFF SAA7146_GPIO_OUTLO  /* SlowBlank off (TV-Mode) */
+#define SB_ON  SAA7146_GPIO_INPUT  /* SlowBlank on  (AV-Mode) */
+#define SB_WIDE SAA7146_GPIO_OUTHI  /* SlowBlank 6V  (16/9-Mode) (not implemented) */
+
+#define FB_GPIO 1
+#define FB_OFF SAA7146_GPIO_LO     /* FastBlank off (CVBS-Mode) */
+#define FB_ON  SAA7146_GPIO_OUTHI  /* FastBlank on  (RGB-Mode) */
+#define FB_LOOP        SAA7146_GPIO_INPUT  /* FastBlank loop-through (PC graphics ???) */
+
+enum av7110_video_output_mode
+{
+       NO_OUT       = 0,               /* disable analog output */
+       CVBS_RGB_OUT = 1,
+       CVBS_YC_OUT  = 2,
+       YC_OUT       = 3
+};
+
+/* firmware internal msg q status: */
+#define GPMQFull       0x0001          /* Main Message Queue Full */
+#define GPMQOver       0x0002          /* Main Message Queue Overflow */
+#define HPQFull                0x0004          /* High Priority Msg Queue Full */
+#define HPQOver                0x0008
+#define OSDQFull       0x0010          /* OSD Queue Full */
+#define OSDQOver       0x0020
+#define GPMQBusy       0x0040          /* Queue not empty, FW >= 261d */
+#define HPQBusy                0x0080
+#define OSDQBusy       0x0100
+
+/* hw section filter flags */
+#define        SECTION_EIT             0x01
+#define        SECTION_SINGLE          0x00
+#define        SECTION_CYCLE           0x02
+#define        SECTION_CONTINUOS       0x04
+#define        SECTION_MODE            0x06
+#define SECTION_IPMPE          0x0C    /* size up to 4k */
+#define SECTION_HIGH_SPEED     0x1C    /* larger buffer */
+#define DATA_PIPING_FLAG       0x20    /* for Data Piping Filter */
+
+#define        PBUFSIZE_NONE 0x0000
+#define        PBUFSIZE_1P   0x0100
+#define        PBUFSIZE_2P   0x0200
+#define        PBUFSIZE_1K   0x0300
+#define        PBUFSIZE_2K   0x0400
+#define        PBUFSIZE_4K   0x0500
+#define        PBUFSIZE_8K   0x0600
+#define PBUFSIZE_16K  0x0700
+#define PBUFSIZE_32K  0x0800
+
+
+/* firmware command codes */
+enum av7110_osd_command {
+       WCreate,
+       WDestroy,
+       WMoveD,
+       WMoveA,
+       WHide,
+       WTop,
+       DBox,
+       DLine,
+       DText,
+       Set_Font,
+       SetColor,
+       SetBlend,
+       SetWBlend,
+       SetCBlend,
+       SetNonBlend,
+       LoadBmp,
+       BlitBmp,
+       ReleaseBmp,
+       SetWTrans,
+       SetWNoTrans,
+       Set_Palette
+};
+
+enum av7110_pid_command {
+       MultiPID,
+       VideoPID,
+       AudioPID,
+       InitFilt,
+       FiltError,
+       NewVersion,
+       CacheError,
+       AddPIDFilter,
+       DelPIDFilter,
+       Scan,
+       SetDescr,
+       SetIR,
+       FlushTSQueue
+};
+
+enum av7110_mpeg_command {
+       SelAudChannels
+};
+
+enum av7110_audio_command {
+       AudioDAC,
+       CabADAC,
+       ON22K,
+       OFF22K,
+       MainSwitch,
+       ADSwitch,
+       SendDiSEqC,
+       SetRegister,
+       SpdifSwitch
+};
+
+enum av7110_request_command {
+       AudioState,
+       AudioBuffState,
+       VideoState1,
+       VideoState2,
+       VideoState3,
+       CrashCounter,
+       ReqVersion,
+       ReqVCXO,
+       ReqRegister,
+       ReqSecFilterError,
+       ReqSTC
+};
+
+enum av7110_encoder_command {
+       SetVidMode,
+       SetTestMode,
+       LoadVidCode,
+       SetMonitorType,
+       SetPanScanType,
+       SetFreezeMode,
+       SetWSSConfig
+};
+
+enum av7110_rec_play_state {
+       __Record,
+       __Stop,
+       __Play,
+       __Pause,
+       __Slow,
+       __FF_IP,
+       __Scan_I,
+       __Continue
+};
+
+enum av7110_fw_cmd_misc {
+       AV7110_FW_VIDEO_ZOOM = 1,
+       AV7110_FW_VIDEO_COMMAND,
+       AV7110_FW_AUDIO_COMMAND
+};
+
+enum av7110_command_type {
+       COMTYPE_NOCOM,
+       COMTYPE_PIDFILTER,
+       COMTYPE_MPEGDECODER,
+       COMTYPE_OSD,
+       COMTYPE_BMP,
+       COMTYPE_ENCODER,
+       COMTYPE_AUDIODAC,
+       COMTYPE_REQUEST,
+       COMTYPE_SYSTEM,
+       COMTYPE_REC_PLAY,
+       COMTYPE_COMMON_IF,
+       COMTYPE_PID_FILTER,
+       COMTYPE_PES,
+       COMTYPE_TS,
+       COMTYPE_VIDEO,
+       COMTYPE_AUDIO,
+       COMTYPE_CI_LL,
+       COMTYPE_MISC = 0x80
+};
+
+#define VID_NONE_PREF          0x00    /* No aspect ration processing preferred */
+#define VID_PAN_SCAN_PREF      0x01    /* Pan and Scan Display preferred */
+#define VID_VERT_COMP_PREF     0x02    /* Vertical compression display preferred */
+#define VID_VC_AND_PS_PREF     0x03    /* PanScan and vertical Compression if allowed */
+#define VID_CENTRE_CUT_PREF    0x05    /* PanScan with zero vector */
+
+/* MPEG video decoder commands */
+#define AV_VIDEO_CMD_STOP      0x000e
+#define AV_VIDEO_CMD_PLAY      0x000d
+#define AV_VIDEO_CMD_FREEZE    0x0102
+#define AV_VIDEO_CMD_FFWD      0x0016
+#define AV_VIDEO_CMD_SLOW      0x0022
+
+/* MPEG audio decoder commands */
+#define AUDIO_CMD_MUTE         0x0001
+#define AUDIO_CMD_UNMUTE       0x0002
+#define AUDIO_CMD_PCM16                0x0010
+#define AUDIO_CMD_STEREO       0x0080
+#define AUDIO_CMD_MONO_L       0x0100
+#define AUDIO_CMD_MONO_R       0x0200
+#define AUDIO_CMD_SYNC_OFF     0x000e
+#define AUDIO_CMD_SYNC_ON      0x000f
+
+/* firmware data interface codes */
+#define DATA_NONE               0x00
+#define DATA_FSECTION           0x01
+#define DATA_IPMPE              0x02
+#define DATA_MPEG_RECORD        0x03
+#define DATA_DEBUG_MESSAGE      0x04
+#define DATA_COMMON_INTERFACE   0x05
+#define DATA_MPEG_PLAY          0x06
+#define DATA_BMP_LOAD           0x07
+#define DATA_IRCOMMAND          0x08
+#define DATA_PIPING             0x09
+#define DATA_STREAMING          0x0a
+#define DATA_CI_GET             0x0b
+#define DATA_CI_PUT             0x0c
+#define DATA_MPEG_VIDEO_EVENT   0x0d
+
+#define DATA_PES_RECORD                 0x10
+#define DATA_PES_PLAY           0x11
+#define DATA_TS_RECORD          0x12
+#define DATA_TS_PLAY            0x13
+
+/* ancient CI command codes, only two are actually still used
+ * by the link level CI firmware */
+#define CI_CMD_ERROR            0x00
+#define CI_CMD_ACK              0x01
+#define CI_CMD_SYSTEM_READY     0x02
+#define CI_CMD_KEYPRESS                 0x03
+#define CI_CMD_ON_TUNED                 0x04
+#define CI_CMD_ON_SWITCH_PROGRAM 0x05
+#define CI_CMD_SECTION_ARRIVED  0x06
+#define CI_CMD_SECTION_TIMEOUT  0x07
+#define CI_CMD_TIME             0x08
+#define CI_CMD_ENTER_MENU       0x09
+#define CI_CMD_FAST_PSI                 0x0a
+#define CI_CMD_GET_SLOT_INFO    0x0b
+
+#define CI_MSG_NONE             0x00
+#define CI_MSG_CI_INFO          0x01
+#define CI_MSG_MENU             0x02
+#define CI_MSG_LIST             0x03
+#define CI_MSG_TEXT             0x04
+#define CI_MSG_REQUEST_INPUT    0x05
+#define CI_MSG_INPUT_COMPLETE   0x06
+#define CI_MSG_LIST_MORE        0x07
+#define CI_MSG_MENU_MORE        0x08
+#define CI_MSG_CLOSE_MMI_IMM    0x09
+#define CI_MSG_SECTION_REQUEST  0x0a
+#define CI_MSG_CLOSE_FILTER     0x0b
+#define CI_PSI_COMPLETE                 0x0c
+#define CI_MODULE_READY                 0x0d
+#define CI_SWITCH_PRG_REPLY     0x0e
+#define CI_MSG_TEXT_MORE        0x0f
+
+#define CI_MSG_CA_PMT           0xe0
+#define CI_MSG_ERROR            0xf0
+
+
+/* base address of the dual ported RAM which serves as communication
+ * area between PCI bus and av7110,
+ * as seen by the DEBI bus of the saa7146 */
+#define        DPRAM_BASE 0x4000
+
+/* boot protocol area */
+#define AV7110_BOOT_STATE      (DPRAM_BASE + 0x3F8)
+#define AV7110_BOOT_SIZE       (DPRAM_BASE + 0x3FA)
+#define AV7110_BOOT_BASE       (DPRAM_BASE + 0x3FC)
+#define AV7110_BOOT_BLOCK      (DPRAM_BASE + 0x400)
+#define AV7110_BOOT_MAX_SIZE   0xc00
+
+/* firmware command protocol area */
+#define IRQ_STATE      (DPRAM_BASE + 0x0F4)
+#define IRQ_STATE_EXT  (DPRAM_BASE + 0x0F6)
+#define MSGSTATE       (DPRAM_BASE + 0x0F8)
+#define COMMAND                (DPRAM_BASE + 0x0FC)
+#define COM_BUFF       (DPRAM_BASE + 0x100)
+#define COM_BUFF_SIZE  0x20
+
+/* various data buffers */
+#define BUFF1_BASE     (DPRAM_BASE + 0x120)
+#define BUFF1_SIZE     0xE0
+
+#define DATA_BUFF0_BASE        (DPRAM_BASE + 0x200)
+#define DATA_BUFF0_SIZE        0x0800
+
+#define DATA_BUFF1_BASE        (DATA_BUFF0_BASE+DATA_BUFF0_SIZE)
+#define DATA_BUFF1_SIZE        0x0800
+
+#define DATA_BUFF2_BASE        (DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
+#define DATA_BUFF2_SIZE        0x0800
+
+#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
+#define DATA_BUFF3_SIZE 0x0400
+
+#define Reserved       (DPRAM_BASE + 0x1E00)
+#define Reserved_SIZE  0x1C0
+
+
+/* firmware status area */
+#define STATUS_BASE    (DPRAM_BASE + 0x1FC0)
+#define STATUS_LOOPS   (STATUS_BASE + 0x08)
+
+#define STATUS_MPEG_WIDTH     (STATUS_BASE + 0x0C)
+/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */
+#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E)
+
+/* firmware data protocol area */
+#define RX_TYPE                (DPRAM_BASE + 0x1FE8)
+#define RX_LEN         (DPRAM_BASE + 0x1FEA)
+#define TX_TYPE                (DPRAM_BASE + 0x1FEC)
+#define TX_LEN         (DPRAM_BASE + 0x1FEE)
+
+#define RX_BUFF                (DPRAM_BASE + 0x1FF4)
+#define TX_BUFF                (DPRAM_BASE + 0x1FF6)
+
+#define HANDSHAKE_REG  (DPRAM_BASE + 0x1FF8)
+#define COM_IF_LOCK    (DPRAM_BASE + 0x1FFA)
+
+#define IRQ_RX         (DPRAM_BASE + 0x1FFC)
+#define IRQ_TX         (DPRAM_BASE + 0x1FFE)
+
+/* used by boot protocol to load firmware into av7110 DRAM */
+#define DRAM_START_CODE                0x2e000404
+#define DRAM_MAX_CODE_SIZE     0x00100000
+
+/* saa7146 gpio lines */
+#define RESET_LINE             2
+#define DEBI_DONE_LINE         1
+#define ARM_IRQ_LINE           0
+
+
+
+extern int av7110_bootarm(struct av7110 *av7110);
+extern int av7110_firmversion(struct av7110 *av7110);
+#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
+#define FW_4M_SDRAM(arm_app)      ((arm_app) & 0x40000000)
+#define FW_VERSION(arm_app)      ((arm_app) & 0x0000FFFF)
+
+extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
+extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
+extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
+                            int request_buf_len, u16 *reply_buf, int reply_buf_len);
+
+
+/* DEBI (saa7146 data extension bus interface) access */
+extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
+                           int addr, u32 val, int count);
+extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
+                          int addr, int count);
+
+
+/* DEBI during interrupt */
+/* single word writes */
+static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+{
+       av7110_debiwrite(av7110, config, addr, val, count);
+}
+
+/* buffer writes */
+static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
+                         const u8 *val, int count)
+{
+       memcpy(av7110->debi_virt, val, count);
+       av7110_debiwrite(av7110, config, addr, 0, count);
+}
+
+static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+{
+       u32 res;
+
+       res=av7110_debiread(av7110, config, addr, count);
+       if (count<=4)
+               memcpy(av7110->debi_virt, (char *) &res, count);
+       return res;
+}
+
+/* DEBI outside interrupts, only for count <= 4! */
+static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&av7110->debilock, flags);
+       av7110_debiwrite(av7110, config, addr, val, count);
+       spin_unlock_irqrestore(&av7110->debilock, flags);
+}
+
+static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+{
+       unsigned long flags;
+       u32 res;
+
+       spin_lock_irqsave(&av7110->debilock, flags);
+       res=av7110_debiread(av7110, config, addr, count);
+       spin_unlock_irqrestore(&av7110->debilock, flags);
+       return res;
+}
+
+/* handle mailbox registers of the dual ported RAM */
+static inline void ARM_ResetMailBox(struct av7110 *av7110)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&av7110->debilock, flags);
+       av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
+       av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
+       spin_unlock_irqrestore(&av7110->debilock, flags);
+}
+
+static inline void ARM_ClearMailBox(struct av7110 *av7110)
+{
+       iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
+}
+
+static inline void ARM_ClearIrq(struct av7110 *av7110)
+{
+       irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
+}
+
+/****************************************************************************
+ * Firmware commands
+ ****************************************************************************/
+
+static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
+}
+
+static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
+}
+
+static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
+                            (com>>16), (com&0xffff),
+                            (arg>>16), (arg&0xffff));
+}
+
+static inline int audcom(struct av7110 *av7110, u32 com)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
+                            (com>>16), (com&0xffff));
+}
+
+static inline int Set22K(struct av7110 *av7110, int state)
+{
+       return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
+}
+
+
+extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
+
+
+#ifdef CONFIG_DVB_AV7110_OSD
+extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
+extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
+#endif /* CONFIG_DVB_AV7110_OSD */
+
+
+
+#endif /* _AV7110_HW_H_ */
diff --git a/drivers/media/pci/ttpci/av7110_ipack.c b/drivers/media/pci/ttpci/av7110_ipack.c
new file mode 100644 (file)
index 0000000..699ef8b
--- /dev/null
@@ -0,0 +1,403 @@
+#include "dvb_filter.h"
+#include "av7110_ipack.h"
+#include <linux/string.h>      /* for memcpy() */
+#include <linux/vmalloc.h>
+
+
+void av7110_ipack_reset(struct ipack *p)
+{
+       p->found = 0;
+       p->cid = 0;
+       p->plength = 0;
+       p->flag1 = 0;
+       p->flag2 = 0;
+       p->hlength = 0;
+       p->mpeg = 0;
+       p->check = 0;
+       p->which = 0;
+       p->done = 0;
+       p->count = 0;
+}
+
+
+int av7110_ipack_init(struct ipack *p, int size,
+                     void (*func)(u8 *buf, int size, void *priv))
+{
+       if (!(p->buf = vmalloc(size*sizeof(u8)))) {
+               printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
+               return -ENOMEM;
+       }
+       p->size = size;
+       p->func = func;
+       p->repack_subids = 0;
+       av7110_ipack_reset(p);
+       return 0;
+}
+
+
+void av7110_ipack_free(struct ipack *p)
+{
+       vfree(p->buf);
+}
+
+
+static void send_ipack(struct ipack *p)
+{
+       int off;
+       struct dvb_audio_info ai;
+       int ac3_off = 0;
+       int streamid = 0;
+       int nframes = 0;
+       int f = 0;
+
+       switch (p->mpeg) {
+       case 2:
+               if (p->count < 10)
+                       return;
+               p->buf[3] = p->cid;
+               p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
+               p->buf[5] = (u8)((p->count - 6) & 0x00ff);
+               if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
+                       off = 9 + p->buf[8];
+                       streamid = p->buf[off];
+                       if ((streamid & 0xf8) == 0x80) {
+                               ai.off = 0;
+                               ac3_off = ((p->buf[off + 2] << 8)|
+                                          p->buf[off + 3]);
+                               if (ac3_off < p->count)
+                                       f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
+                                                                  p->count - ac3_off, &ai, 0);
+                               if (!f) {
+                                       nframes = (p->count - off - 3 - ac3_off) /
+                                               ai.framesize + 1;
+                                       p->buf[off + 2] = (ac3_off >> 8) & 0xff;
+                                       p->buf[off + 3] = (ac3_off) & 0xff;
+                                       p->buf[off + 1] = nframes;
+                                       ac3_off +=  nframes * ai.framesize - p->count;
+                               }
+                       }
+               }
+               p->func(p->buf, p->count, p->data);
+
+               p->buf[6] = 0x80;
+               p->buf[7] = 0x00;
+               p->buf[8] = 0x00;
+               p->count = 9;
+               if (p->repack_subids && p->cid == PRIVATE_STREAM1
+                   && (streamid & 0xf8) == 0x80) {
+                       p->count += 4;
+                       p->buf[9] = streamid;
+                       p->buf[10] = (ac3_off >> 8) & 0xff;
+                       p->buf[11] = (ac3_off) & 0xff;
+                       p->buf[12] = 0;
+               }
+               break;
+
+       case 1:
+               if (p->count < 8)
+                       return;
+               p->buf[3] = p->cid;
+               p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
+               p->buf[5] = (u8)((p->count - 6) & 0x00ff);
+               p->func(p->buf, p->count, p->data);
+
+               p->buf[6] = 0x0f;
+               p->count = 7;
+               break;
+       }
+}
+
+
+void av7110_ipack_flush(struct ipack *p)
+{
+       if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
+               return;
+       p->plength = p->found - 6;
+       p->found = 0;
+       send_ipack(p);
+       av7110_ipack_reset(p);
+}
+
+
+static void write_ipack(struct ipack *p, const u8 *data, int count)
+{
+       u8 headr[3] = { 0x00, 0x00, 0x01 };
+
+       if (p->count < 6) {
+               memcpy(p->buf, headr, 3);
+               p->count = 6;
+       }
+
+       if (p->count + count < p->size){
+               memcpy(p->buf+p->count, data, count);
+               p->count += count;
+       } else {
+               int rest = p->size - p->count;
+               memcpy(p->buf+p->count, data, rest);
+               p->count += rest;
+               send_ipack(p);
+               if (count - rest > 0)
+                       write_ipack(p, data + rest, count - rest);
+       }
+}
+
+
+int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
+{
+       int l;
+       int c = 0;
+
+       while (c < count && (p->mpeg == 0 ||
+                            (p->mpeg == 1 && p->found < 7) ||
+                            (p->mpeg == 2 && p->found < 9))
+              &&  (p->found < 5 || !p->done)) {
+               switch (p->found) {
+               case 0:
+               case 1:
+                       if (buf[c] == 0x00)
+                               p->found++;
+                       else
+                               p->found = 0;
+                       c++;
+                       break;
+               case 2:
+                       if (buf[c] == 0x01)
+                               p->found++;
+                       else if (buf[c] == 0)
+                               p->found = 2;
+                       else
+                               p->found = 0;
+                       c++;
+                       break;
+               case 3:
+                       p->cid = 0;
+                       switch (buf[c]) {
+                       case PROG_STREAM_MAP:
+                       case PRIVATE_STREAM2:
+                       case PROG_STREAM_DIR:
+                       case ECM_STREAM     :
+                       case EMM_STREAM     :
+                       case PADDING_STREAM :
+                       case DSM_CC_STREAM  :
+                       case ISO13522_STREAM:
+                               p->done = 1;
+                               /* fall through */
+                       case PRIVATE_STREAM1:
+                       case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+                       case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+                               p->found++;
+                               p->cid = buf[c];
+                               c++;
+                               break;
+                       default:
+                               p->found = 0;
+                               break;
+                       }
+                       break;
+
+               case 4:
+                       if (count-c > 1) {
+                               p->plen[0] = buf[c];
+                               c++;
+                               p->plen[1] = buf[c];
+                               c++;
+                               p->found += 2;
+                               p->plength = (p->plen[0] << 8) | p->plen[1];
+                       } else {
+                               p->plen[0] = buf[c];
+                               p->found++;
+                               return count;
+                       }
+                       break;
+               case 5:
+                       p->plen[1] = buf[c];
+                       c++;
+                       p->found++;
+                       p->plength = (p->plen[0] << 8) | p->plen[1];
+                       break;
+               case 6:
+                       if (!p->done) {
+                               p->flag1 = buf[c];
+                               c++;
+                               p->found++;
+                               if ((p->flag1 & 0xc0) == 0x80)
+                                       p->mpeg = 2;
+                               else {
+                                       p->hlength = 0;
+                                       p->which = 0;
+                                       p->mpeg = 1;
+                                       p->flag2 = 0;
+                               }
+                       }
+                       break;
+
+               case 7:
+                       if (!p->done && p->mpeg == 2) {
+                               p->flag2 = buf[c];
+                               c++;
+                               p->found++;
+                       }
+                       break;
+
+               case 8:
+                       if (!p->done && p->mpeg == 2) {
+                               p->hlength = buf[c];
+                               c++;
+                               p->found++;
+                       }
+                       break;
+               }
+       }
+
+       if (c == count)
+               return count;
+
+       if (!p->plength)
+               p->plength = MMAX_PLENGTH - 6;
+
+       if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
+                       (p->mpeg == 1 && p->found >= 7))) {
+               switch (p->cid) {
+               case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+               case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+               case PRIVATE_STREAM1:
+                       if (p->mpeg == 2 && p->found == 9) {
+                               write_ipack(p, &p->flag1, 1);
+                               write_ipack(p, &p->flag2, 1);
+                               write_ipack(p, &p->hlength, 1);
+                       }
+
+                       if (p->mpeg == 1 && p->found == 7)
+                               write_ipack(p, &p->flag1, 1);
+
+                       if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
+                           p->found < 14) {
+                               while (c < count && p->found < 14) {
+                                       p->pts[p->found - 9] = buf[c];
+                                       write_ipack(p, buf + c, 1);
+                                       c++;
+                                       p->found++;
+                               }
+                               if (c == count)
+                                       return count;
+                       }
+
+                       if (p->mpeg == 1 && p->which < 2000) {
+
+                               if (p->found == 7) {
+                                       p->check = p->flag1;
+                                       p->hlength = 1;
+                               }
+
+                               while (!p->which && c < count &&
+                                      p->check == 0xff){
+                                       p->check = buf[c];
+                                       write_ipack(p, buf + c, 1);
+                                       c++;
+                                       p->found++;
+                                       p->hlength++;
+                               }
+
+                               if (c == count)
+                                       return count;
+
+                               if ((p->check & 0xc0) == 0x40 && !p->which) {
+                                       p->check = buf[c];
+                                       write_ipack(p, buf + c, 1);
+                                       c++;
+                                       p->found++;
+                                       p->hlength++;
+
+                                       p->which = 1;
+                                       if (c == count)
+                                               return count;
+                                       p->check = buf[c];
+                                       write_ipack(p, buf + c, 1);
+                                       c++;
+                                       p->found++;
+                                       p->hlength++;
+                                       p->which = 2;
+                                       if (c == count)
+                                               return count;
+                               }
+
+                               if (p->which == 1) {
+                                       p->check = buf[c];
+                                       write_ipack(p, buf + c, 1);
+                                       c++;
+                                       p->found++;
+                                       p->hlength++;
+                                       p->which = 2;
+                                       if (c == count)
+                                               return count;
+                               }
+
+                               if ((p->check & 0x30) && p->check != 0xff) {
+                                       p->flag2 = (p->check & 0xf0) << 2;
+                                       p->pts[0] = p->check;
+                                       p->which = 3;
+                               }
+
+                               if (c == count)
+                                       return count;
+                               if (p->which > 2){
+                                       if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
+                                               while (c < count && p->which < 7) {
+                                                       p->pts[p->which - 2] = buf[c];
+                                                       write_ipack(p, buf + c, 1);
+                                                       c++;
+                                                       p->found++;
+                                                       p->which++;
+                                                       p->hlength++;
+                                               }
+                                               if (c == count)
+                                                       return count;
+                                       } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
+                                               while (c < count && p->which < 12) {
+                                                       if (p->which < 7)
+                                                               p->pts[p->which - 2] = buf[c];
+                                                       write_ipack(p, buf + c, 1);
+                                                       c++;
+                                                       p->found++;
+                                                       p->which++;
+                                                       p->hlength++;
+                                               }
+                                               if (c == count)
+                                                       return count;
+                                       }
+                                       p->which = 2000;
+                               }
+
+                       }
+
+                       while (c < count && p->found < p->plength + 6) {
+                               l = count - c;
+                               if (l + p->found > p->plength + 6)
+                                       l = p->plength + 6 - p->found;
+                               write_ipack(p, buf + c, l);
+                               p->found += l;
+                               c += l;
+                       }
+                       break;
+               }
+
+
+               if (p->done) {
+                       if (p->found + count - c < p->plength + 6) {
+                               p->found += count - c;
+                               c = count;
+                       } else {
+                               c += p->plength + 6 - p->found;
+                               p->found = p->plength + 6;
+                       }
+               }
+
+               if (p->plength && p->found == p->plength + 6) {
+                       send_ipack(p);
+                       av7110_ipack_reset(p);
+                       if (c < count)
+                               av7110_ipack_instant_repack(buf + c, count - c, p);
+               }
+       }
+       return count;
+}
diff --git a/drivers/media/pci/ttpci/av7110_ipack.h b/drivers/media/pci/ttpci/av7110_ipack.h
new file mode 100644 (file)
index 0000000..becf94d
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _AV7110_IPACK_H_
+#define _AV7110_IPACK_H_
+
+extern int av7110_ipack_init(struct ipack *p, int size,
+                            void (*func)(u8 *buf,  int size, void *priv));
+
+extern void av7110_ipack_reset(struct ipack *p);
+extern int  av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
+extern void av7110_ipack_free(struct ipack * p);
+extern void av7110_ipack_flush(struct ipack *p);
+
+#endif
diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
new file mode 100644 (file)
index 0000000..908f272
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * Driver for the remote control of SAA7146 based AV7110 cards
+ *
+ * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
+ * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include "av7110.h"
+#include "av7110_hw.h"
+
+
+#define AV_CNT         4
+
+#define IR_RC5         0
+#define IR_RCMM                1
+#define IR_RC5_EXT     2 /* internal only */
+
+#define IR_ALL         0xffffffff
+
+#define UP_TIMEOUT     (HZ*7/25)
+
+
+/* Note: enable ir debugging by or'ing debug with 16 */
+
+static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM};
+module_param_array(ir_protocol, int, NULL, 0644);
+MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)");
+
+static int ir_inversion[AV_CNT];
+module_param_array(ir_inversion, int, NULL, 0644);
+MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted");
+
+static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL };
+module_param_array(ir_device_mask, uint, NULL, 0644);
+MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)");
+
+
+static int av_cnt;
+static struct av7110 *av_list[AV_CNT];
+
+static u16 default_key_map [256] = {
+       KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
+       KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
+       KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
+       0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
+       KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
+       KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
+       KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
+       0, 0, 0, 0, KEY_EPG, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
+};
+
+
+/* key-up timer */
+static void av7110_emit_keyup(unsigned long parm)
+{
+       struct infrared *ir = (struct infrared *) parm;
+
+       if (!ir || !test_bit(ir->last_key, ir->input_dev->key))
+               return;
+
+       input_report_key(ir->input_dev, ir->last_key, 0);
+       input_sync(ir->input_dev);
+}
+
+
+/* tasklet */
+static void av7110_emit_key(unsigned long parm)
+{
+       struct infrared *ir = (struct infrared *) parm;
+       u32 ircom = ir->ir_command;
+       u8 data;
+       u8 addr;
+       u16 toggle;
+       u16 keycode;
+
+       /* extract device address and data */
+       switch (ir->protocol) {
+       case IR_RC5: /* RC5: 5 bits device address, 6 bits data */
+               data = ircom & 0x3f;
+               addr = (ircom >> 6) & 0x1f;
+               toggle = ircom & 0x0800;
+               break;
+
+       case IR_RCMM: /* RCMM: ? bits device address, ? bits data */
+               data = ircom & 0xff;
+               addr = (ircom >> 8) & 0x1f;
+               toggle = ircom & 0x8000;
+               break;
+
+       case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */
+               data = ircom & 0x3f;
+               addr = (ircom >> 6) & 0x1f;
+               /* invert 7th data bit for backward compatibility with RC5 keymaps */
+               if (!(ircom & 0x1000))
+                       data |= 0x40;
+               toggle = ircom & 0x0800;
+               break;
+
+       default:
+               printk("%s invalid protocol %x\n", __func__, ir->protocol);
+               return;
+       }
+
+       input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data);
+       input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
+
+       keycode = ir->key_map[data];
+
+       dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n",
+               __func__, ircom, addr, data, keycode);
+
+       /* check device address */
+       if (!(ir->device_mask & (1 << addr)))
+               return;
+
+       if (!keycode) {
+               printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n",
+                       __func__, ircom, addr, data);
+               return;
+       }
+
+       if (timer_pending(&ir->keyup_timer)) {
+               del_timer(&ir->keyup_timer);
+               if (ir->last_key != keycode || toggle != ir->last_toggle) {
+                       ir->delay_timer_finished = 0;
+                       input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
+                       input_event(ir->input_dev, EV_KEY, keycode, 1);
+                       input_sync(ir->input_dev);
+               } else if (ir->delay_timer_finished) {
+                       input_event(ir->input_dev, EV_KEY, keycode, 2);
+                       input_sync(ir->input_dev);
+               }
+       } else {
+               ir->delay_timer_finished = 0;
+               input_event(ir->input_dev, EV_KEY, keycode, 1);
+               input_sync(ir->input_dev);
+       }
+
+       ir->last_key = keycode;
+       ir->last_toggle = toggle;
+
+       ir->keyup_timer.expires = jiffies + UP_TIMEOUT;
+       add_timer(&ir->keyup_timer);
+
+}
+
+
+/* register with input layer */
+static void input_register_keys(struct infrared *ir)
+{
+       int i;
+
+       set_bit(EV_KEY, ir->input_dev->evbit);
+       set_bit(EV_REP, ir->input_dev->evbit);
+       set_bit(EV_MSC, ir->input_dev->evbit);
+
+       set_bit(MSC_RAW, ir->input_dev->mscbit);
+       set_bit(MSC_SCAN, ir->input_dev->mscbit);
+
+       memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
+
+       for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) {
+               if (ir->key_map[i] > KEY_MAX)
+                       ir->key_map[i] = 0;
+               else if (ir->key_map[i] > KEY_RESERVED)
+                       set_bit(ir->key_map[i], ir->input_dev->keybit);
+       }
+
+       ir->input_dev->keycode = ir->key_map;
+       ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
+       ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
+}
+
+
+/* called by the input driver after rep[REP_DELAY] ms */
+static void input_repeat_key(unsigned long parm)
+{
+       struct infrared *ir = (struct infrared *) parm;
+
+       ir->delay_timer_finished = 1;
+}
+
+
+/* check for configuration changes */
+int av7110_check_ir_config(struct av7110 *av7110, int force)
+{
+       int i;
+       int modified = force;
+       int ret = -ENODEV;
+
+       for (i = 0; i < av_cnt; i++)
+               if (av7110 == av_list[i])
+                       break;
+
+       if (i < av_cnt && av7110) {
+               if ((av7110->ir.protocol & 1) != ir_protocol[i] ||
+                   av7110->ir.inversion != ir_inversion[i])
+                       modified = true;
+
+               if (modified) {
+                       /* protocol */
+                       if (ir_protocol[i]) {
+                               ir_protocol[i] = 1;
+                               av7110->ir.protocol = IR_RCMM;
+                               av7110->ir.ir_config = 0x0001;
+                       } else if (FW_VERSION(av7110->arm_app) >= 0x2620) {
+                               av7110->ir.protocol = IR_RC5_EXT;
+                               av7110->ir.ir_config = 0x0002;
+                       } else {
+                               av7110->ir.protocol = IR_RC5;
+                               av7110->ir.ir_config = 0x0000;
+                       }
+                       /* inversion */
+                       if (ir_inversion[i]) {
+                               ir_inversion[i] = 1;
+                               av7110->ir.ir_config |= 0x8000;
+                       }
+                       av7110->ir.inversion = ir_inversion[i];
+                       /* update ARM */
+                       ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
+                                               av7110->ir.ir_config);
+               } else
+                       ret = 0;
+
+               /* address */
+               if (av7110->ir.device_mask != ir_device_mask[i])
+                       av7110->ir.device_mask = ir_device_mask[i];
+       }
+
+       return ret;
+}
+
+
+/* /proc/av7110_ir interface */
+static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
+                                   size_t count, loff_t *pos)
+{
+       char *page;
+       u32 ir_config;
+       int size = sizeof ir_config + sizeof av_list[0]->ir.key_map;
+       int i;
+
+       if (count < size)
+               return -EINVAL;
+
+       page = vmalloc(size);
+       if (!page)
+               return -ENOMEM;
+
+       if (copy_from_user(page, buffer, size)) {
+               vfree(page);
+               return -EFAULT;
+       }
+
+       memcpy(&ir_config, page, sizeof ir_config);
+
+       for (i = 0; i < av_cnt; i++) {
+               /* keymap */
+               memcpy(av_list[i]->ir.key_map, page + sizeof ir_config,
+                       sizeof(av_list[i]->ir.key_map));
+               /* protocol, inversion, address */
+               ir_protocol[i] = ir_config & 0x0001;
+               ir_inversion[i] = ir_config & 0x8000 ? 1 : 0;
+               if (ir_config & 0x4000)
+                       ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f);
+               else
+                       ir_device_mask[i] = IR_ALL;
+               /* update configuration */
+               av7110_check_ir_config(av_list[i], false);
+               input_register_keys(&av_list[i]->ir);
+       }
+       vfree(page);
+       return count;
+}
+
+static const struct file_operations av7110_ir_proc_fops = {
+       .owner          = THIS_MODULE,
+       .write          = av7110_ir_proc_write,
+       .llseek         = noop_llseek,
+};
+
+/* interrupt handler */
+static void ir_handler(struct av7110 *av7110, u32 ircom)
+{
+       dprintk(4, "ir command = %08x\n", ircom);
+       av7110->ir.ir_command = ircom;
+       tasklet_schedule(&av7110->ir.ir_tasklet);
+}
+
+
+int __devinit av7110_ir_init(struct av7110 *av7110)
+{
+       struct input_dev *input_dev;
+       static struct proc_dir_entry *e;
+       int err;
+
+       if (av_cnt >= ARRAY_SIZE(av_list))
+               return -ENOSPC;
+
+       av_list[av_cnt++] = av7110;
+       av7110_check_ir_config(av7110, true);
+
+       init_timer(&av7110->ir.keyup_timer);
+       av7110->ir.keyup_timer.function = av7110_emit_keyup;
+       av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir;
+
+       input_dev = input_allocate_device();
+       if (!input_dev)
+               return -ENOMEM;
+
+       av7110->ir.input_dev = input_dev;
+       snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
+               "pci-%s/ir0", pci_name(av7110->dev->pci));
+
+       input_dev->name = "DVB on-card IR receiver";
+
+       input_dev->phys = av7110->ir.input_phys;
+       input_dev->id.bustype = BUS_PCI;
+       input_dev->id.version = 2;
+       if (av7110->dev->pci->subsystem_vendor) {
+               input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
+               input_dev->id.product = av7110->dev->pci->subsystem_device;
+       } else {
+               input_dev->id.vendor = av7110->dev->pci->vendor;
+               input_dev->id.product = av7110->dev->pci->device;
+       }
+       input_dev->dev.parent = &av7110->dev->pci->dev;
+       /* initial keymap */
+       memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map);
+       input_register_keys(&av7110->ir);
+       err = input_register_device(input_dev);
+       if (err) {
+               input_free_device(input_dev);
+               return err;
+       }
+       input_dev->timer.function = input_repeat_key;
+       input_dev->timer.data = (unsigned long) &av7110->ir;
+
+       if (av_cnt == 1) {
+               e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
+               if (e)
+                       e->size = 4 + 256 * sizeof(u16);
+       }
+
+       tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
+       av7110->ir.ir_handler = ir_handler;
+
+       return 0;
+}
+
+
+void __devexit av7110_ir_exit(struct av7110 *av7110)
+{
+       int i;
+
+       if (av_cnt == 0)
+               return;
+
+       del_timer_sync(&av7110->ir.keyup_timer);
+       av7110->ir.ir_handler = NULL;
+       tasklet_kill(&av7110->ir.ir_tasklet);
+
+       for (i = 0; i < av_cnt; i++)
+               if (av_list[i] == av7110) {
+                       av_list[i] = av_list[av_cnt-1];
+                       av_list[av_cnt-1] = NULL;
+                       break;
+               }
+
+       if (av_cnt == 1)
+               remove_proc_entry("av7110_ir", NULL);
+
+       input_unregister_device(av7110->ir.input_dev);
+
+       av_cnt--;
+}
+
+//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
+//MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ttpci/av7110_v4l.c b/drivers/media/pci/ttpci/av7110_v4l.c
new file mode 100644 (file)
index 0000000..1b2d151
--- /dev/null
@@ -0,0 +1,966 @@
+/*
+ * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * originally based on code by:
+ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+
+#include "av7110.h"
+#include "av7110_hw.h"
+#include "av7110_av.h"
+
+int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
+{
+       u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
+       struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg };
+
+       switch (av7110->adac_type) {
+       case DVB_ADAC_MSP34x0:
+               msgs.addr = 0x40;
+               break;
+       case DVB_ADAC_MSP34x5:
+               msgs.addr = 0x42;
+               break;
+       default:
+               return 0;
+       }
+
+       if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
+               dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
+                      av7110->dvb_adapter.num, reg, val);
+               return -EIO;
+       }
+       return 0;
+}
+
+static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
+{
+       u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
+       u8 msg2[2];
+       struct i2c_msg msgs[2] = {
+               { .flags = 0       , .len = 3, .buf = msg1 },
+               { .flags = I2C_M_RD, .len = 2, .buf = msg2 }
+       };
+
+       switch (av7110->adac_type) {
+       case DVB_ADAC_MSP34x0:
+               msgs[0].addr = 0x40;
+               msgs[1].addr = 0x40;
+               break;
+       case DVB_ADAC_MSP34x5:
+               msgs[0].addr = 0x42;
+               msgs[1].addr = 0x42;
+               break;
+       default:
+               return 0;
+       }
+
+       if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
+               dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
+                      av7110->dvb_adapter.num, reg);
+               return -EIO;
+       }
+       *val = (msg2[0] << 8) | msg2[1];
+       return 0;
+}
+
+static struct v4l2_input inputs[4] = {
+       {
+               .index          = 0,
+               .name           = "DVB",
+               .type           = V4L2_INPUT_TYPE_CAMERA,
+               .audioset       = 1,
+               .tuner          = 0, /* ignored */
+               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+               .status         = 0,
+               .capabilities   = V4L2_IN_CAP_STD,
+       }, {
+               .index          = 1,
+               .name           = "Television",
+               .type           = V4L2_INPUT_TYPE_TUNER,
+               .audioset       = 1,
+               .tuner          = 0,
+               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+               .status         = 0,
+               .capabilities   = V4L2_IN_CAP_STD,
+       }, {
+               .index          = 2,
+               .name           = "Video",
+               .type           = V4L2_INPUT_TYPE_CAMERA,
+               .audioset       = 0,
+               .tuner          = 0,
+               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+               .status         = 0,
+               .capabilities   = V4L2_IN_CAP_STD,
+       }, {
+               .index          = 3,
+               .name           = "Y/C",
+               .type           = V4L2_INPUT_TYPE_CAMERA,
+               .audioset       = 0,
+               .tuner          = 0,
+               .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+               .status         = 0,
+               .capabilities   = V4L2_IN_CAP_STD,
+       }
+};
+
+static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
+{
+       struct av7110 *av7110 = dev->ext_priv;
+       u8 buf[] = { 0x00, reg, data };
+       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
+
+       dprintk(4, "dev: %p\n", dev);
+
+       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
+               return -1;
+       return 0;
+}
+
+static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
+{
+       struct av7110 *av7110 = dev->ext_priv;
+       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
+
+       dprintk(4, "dev: %p\n", dev);
+
+       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
+               return -1;
+       return 0;
+}
+
+static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
+{
+       u32 div;
+       u8 config;
+       u8 buf[4];
+
+       dprintk(4, "freq: 0x%08x\n", freq);
+
+       /* magic number: 614. tuning with the frequency given by v4l2
+          is always off by 614*62.5 = 38375 kHz...*/
+       div = freq + 614;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x8e;
+
+       if (freq < (u32) (16 * 168.25))
+               config = 0xa0;
+       else if (freq < (u32) (16 * 447.25))
+               config = 0x90;
+       else
+               config = 0x30;
+       config &= ~0x02;
+
+       buf[3] = config;
+
+       return tuner_write(dev, 0x61, buf);
+}
+
+static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
+{
+       struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+       u32 div;
+       u8 data[4];
+
+       div = (freq + 38900000 + 31250) / 62500;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0xce;
+
+       if (freq < 45000000)
+               return -EINVAL;
+       else if (freq < 137000000)
+               data[3] = 0x01;
+       else if (freq < 403000000)
+               data[3] = 0x02;
+       else if (freq < 860000000)
+               data[3] = 0x04;
+       else
+               return -EINVAL;
+
+       if (av7110->fe->ops.i2c_gate_ctrl)
+               av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1);
+       return tuner_write(dev, 0x63, data);
+}
+
+
+
+static struct saa7146_standard analog_standard[];
+static struct saa7146_standard dvb_standard[];
+static struct saa7146_standard standard[];
+
+static struct v4l2_audio msp3400_v4l2_audio = {
+       .index = 0,
+       .name = "Television",
+       .capability = V4L2_AUDCAP_STEREO
+};
+
+static int av7110_dvb_c_switch(struct saa7146_fh *fh)
+{
+       struct saa7146_dev *dev = fh->dev;
+       struct saa7146_vv *vv = dev->vv_data;
+       struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+       u16 adswitch;
+       int source, sync, err;
+
+       dprintk(4, "%p\n", av7110);
+
+       if ((vv->video_status & STATUS_OVERLAY) != 0) {
+               vv->ov_suspend = vv->video_fh;
+               err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
+               if (err != 0) {
+                       dprintk(2, "suspending video failed\n");
+                       vv->ov_suspend = NULL;
+               }
+       }
+
+       if (0 != av7110->current_input) {
+               dprintk(1, "switching to analog TV:\n");
+               adswitch = 1;
+               source = SAA7146_HPS_SOURCE_PORT_B;
+               sync = SAA7146_HPS_SYNC_PORT_B;
+               memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
+
+               switch (av7110->current_input) {
+               case 1:
+                       dprintk(1, "switching SAA7113 to Analog Tuner Input\n");
+                       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
+                       msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
+                       msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
+                       msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
+                       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
+                       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
+
+                       if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+                               if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
+                                       dprintk(1, "setting band in demodulator failed\n");
+                       } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+                               saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD)
+                               saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF)
+                       }
+                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
+                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+                       break;
+               case 2:
+                       dprintk(1, "switching SAA7113 to Video AV CVBS Input\n");
+                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
+                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+                       break;
+               case 3:
+                       dprintk(1, "switching SAA7113 to Video AV Y/C Input\n");
+                       if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
+                               dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+                       break;
+               default:
+                       dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input\n");
+               }
+       } else {
+               adswitch = 0;
+               source = SAA7146_HPS_SOURCE_PORT_A;
+               sync = SAA7146_HPS_SYNC_PORT_A;
+               memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
+               dprintk(1, "switching DVB mode\n");
+               msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
+               msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
+               msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
+               msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
+               msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
+               msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
+
+               if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+                       if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
+                               dprintk(1, "setting band in demodulator failed\n");
+               } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
+                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
+               }
+       }
+
+       /* hmm, this does not do anything!? */
+       if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
+               dprintk(1, "ADSwitch error\n");
+
+       saa7146_set_hps_source_and_sync(dev, source, sync);
+
+       if (vv->ov_suspend != NULL) {
+               saa7146_start_preview(vv->ov_suspend);
+               vv->ov_suspend = NULL;
+       }
+
+       return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+       u16 stereo_det;
+       s8 stereo;
+
+       dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+
+       if (!av7110->analog_tuner_flags || t->index != 0)
+               return -EINVAL;
+
+       memset(t, 0, sizeof(*t));
+       strcpy((char *)t->name, "Television");
+
+       t->type = V4L2_TUNER_ANALOG_TV;
+       t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+               V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+       t->rangelow = 772;      /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+       t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
+       /* FIXME: add the real signal strength here */
+       t->signal = 0xffff;
+       t->afc = 0;
+
+       /* FIXME: standard / stereo detection is still broken */
+       msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
+       dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+       msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
+       dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+       stereo = (s8)(stereo_det >> 8);
+       if (stereo > 0x10) {
+               /* stereo */
+               t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+               t->audmode = V4L2_TUNER_MODE_STEREO;
+       } else if (stereo < -0x10) {
+               /* bilingual */
+               t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+               t->audmode = V4L2_TUNER_MODE_LANG1;
+       } else /* mono */
+               t->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+       return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+       u16 fm_matrix, src;
+       dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+
+       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+               return -EINVAL;
+
+       switch (t->audmode) {
+       case V4L2_TUNER_MODE_STEREO:
+               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
+               fm_matrix = 0x3001; /* stereo */
+               src = 0x0020;
+               break;
+       case V4L2_TUNER_MODE_LANG1_LANG2:
+               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
+               fm_matrix = 0x3000; /* bilingual */
+               src = 0x0020;
+               break;
+       case V4L2_TUNER_MODE_LANG1:
+               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
+               fm_matrix = 0x3000; /* mono */
+               src = 0x0000;
+               break;
+       case V4L2_TUNER_MODE_LANG2:
+               dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
+               fm_matrix = 0x3000; /* mono */
+               src = 0x0010;
+               break;
+       default: /* case V4L2_TUNER_MODE_MONO: */
+               dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
+               fm_matrix = 0x3000; /* mono */
+               src = 0x0030;
+               break;
+       }
+       msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
+       msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
+       msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
+       msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
+       return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency);
+
+       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+               return -EINVAL;
+
+       memset(f, 0, sizeof(*f));
+       f->type = V4L2_TUNER_ANALOG_TV;
+       f->frequency =  av7110->current_freq;
+       return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency);
+
+       if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+               return -EINVAL;
+
+       if (V4L2_TUNER_ANALOG_TV != f->type)
+               return -EINVAL;
+
+       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+
+       /* tune in desired frequency */
+       if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
+               ves1820_set_tv_freq(dev, f->frequency);
+       else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
+               stv0297_set_tv_freq(dev, f->frequency);
+       av7110->current_freq = f->frequency;
+
+       msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
+       msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
+       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
+       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
+       return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+
+       if (av7110->analog_tuner_flags) {
+               if (i->index >= 4)
+                       return -EINVAL;
+       } else {
+               if (i->index != 0)
+                       return -EINVAL;
+       }
+
+       memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+       return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       *input = av7110->current_input;
+       dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+       return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+       if (!av7110->analog_tuner_flags)
+               return input ? -EINVAL : 0;
+
+       if (input >= 4)
+               return -EINVAL;
+
+       av7110->current_input = input;
+       return av7110_dvb_c_switch(fh);
+}
+
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+       dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+       if (a->index != 0)
+               return -EINVAL;
+       *a = msp3400_v4l2_audio;
+       return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+       if (a->index != 0)
+               return -EINVAL;
+       if (av7110->current_input >= 2)
+               return -EINVAL;
+       *a = msp3400_v4l2_audio;
+       return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+       if (av7110->current_input >= 2)
+               return -EINVAL;
+       return a->index ? -EINVAL : 0;
+}
+
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+                                       struct v4l2_sliced_vbi_cap *cap)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+       if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+               return -EINVAL;
+       if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+               cap->service_set = V4L2_SLICED_WSS_625;
+               cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
+       }
+       return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+                                       struct v4l2_format *f)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_G_FMT:\n");
+       if (FW_VERSION(av7110->arm_app) < 0x2623)
+               return -EINVAL;
+       memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+       if (av7110->wssMode) {
+               f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+               f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+               f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+       }
+       return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+                                       struct v4l2_format *f)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+       dprintk(2, "VIDIOC_S_FMT\n");
+       if (FW_VERSION(av7110->arm_app) < 0x2623)
+               return -EINVAL;
+       if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+           f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+               memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+               /* WSS controlled by firmware */
+               av7110->wssMode = 0;
+               av7110->wssData = 0;
+               return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+                                    SetWSSConfig, 1, 0);
+       } else {
+               memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+               f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+               f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+               f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+               /* WSS controlled by userspace */
+               av7110->wssMode = 1;
+               av7110->wssData = 0;
+       }
+       return 0;
+}
+
+static int av7110_vbi_reset(struct file *file)
+{
+       struct saa7146_fh *fh = file->private_data;
+       struct saa7146_dev *dev = fh->dev;
+       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+
+       dprintk(2, "%s\n", __func__);
+       av7110->wssMode = 0;
+       av7110->wssData = 0;
+       if (FW_VERSION(av7110->arm_app) < 0x2623)
+               return 0;
+       else
+               return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
+}
+
+static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
+{
+       struct saa7146_fh *fh = file->private_data;
+       struct saa7146_dev *dev = fh->dev;
+       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+       struct v4l2_sliced_vbi_data d;
+       int rc;
+
+       dprintk(2, "%s\n", __func__);
+       if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
+               return -EINVAL;
+       if (copy_from_user(&d, data, count))
+               return -EFAULT;
+       if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
+               return -EINVAL;
+       if (d.id)
+               av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
+       else
+               av7110->wssData = 0x8000;
+       rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData);
+       return (rc < 0) ? rc : count;
+}
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+static u8 saa7113_init_regs[] = {
+       0x02, 0xd0,
+       0x03, 0x23,
+       0x04, 0x00,
+       0x05, 0x00,
+       0x06, 0xe9,
+       0x07, 0x0d,
+       0x08, 0x98,
+       0x09, 0x02,
+       0x0a, 0x80,
+       0x0b, 0x40,
+       0x0c, 0x40,
+       0x0d, 0x00,
+       0x0e, 0x01,
+       0x0f, 0x7c,
+       0x10, 0x48,
+       0x11, 0x0c,
+       0x12, 0x8b,
+       0x13, 0x1a,
+       0x14, 0x00,
+       0x15, 0x00,
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1b, 0x00,
+       0x1c, 0x00,
+       0x1d, 0x00,
+       0x1e, 0x00,
+
+       0x41, 0x77,
+       0x42, 0x77,
+       0x43, 0x77,
+       0x44, 0x77,
+       0x45, 0x77,
+       0x46, 0x77,
+       0x47, 0x77,
+       0x48, 0x77,
+       0x49, 0x77,
+       0x4a, 0x77,
+       0x4b, 0x77,
+       0x4c, 0x77,
+       0x4d, 0x77,
+       0x4e, 0x77,
+       0x4f, 0x77,
+       0x50, 0x77,
+       0x51, 0x77,
+       0x52, 0x77,
+       0x53, 0x77,
+       0x54, 0x77,
+       0x55, 0x77,
+       0x56, 0x77,
+       0x57, 0xff,
+
+       0xff
+};
+
+
+static struct saa7146_ext_vv av7110_vv_data_st;
+static struct saa7146_ext_vv av7110_vv_data_c;
+
+int av7110_init_analog_module(struct av7110 *av7110)
+{
+       u16 version1, version2;
+
+       if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 &&
+           i2c_writereg(av7110, 0x80, 0x0, 0) == 1) {
+               pr_info("DVB-C analog module @ card %d detected, initializing MSP3400\n",
+                       av7110->dvb_adapter.num);
+               av7110->adac_type = DVB_ADAC_MSP34x0;
+       } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 &&
+                  i2c_writereg(av7110, 0x84, 0x0, 0) == 1) {
+               pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n",
+                       av7110->dvb_adapter.num);
+               av7110->adac_type = DVB_ADAC_MSP34x5;
+       } else
+               return -ENODEV;
+
+       msleep(100); // the probing above resets the msp...
+       msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
+       msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
+       dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n",
+               av7110->dvb_adapter.num, version1, version2);
+       msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
+       msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
+       msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
+       msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
+       msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
+       msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
+       msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
+       msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART
+
+       if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
+               pr_info("saa7113 not accessible\n");
+       } else {
+               u8 *i = saa7113_init_regs;
+
+               if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
+                       /* Fujitsu/Siemens DVB-Cable */
+                       av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
+               } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
+                       /* Hauppauge/TT DVB-C premium */
+                       av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
+               } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
+                       /* Hauppauge/TT DVB-C premium */
+                       av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
+               }
+
+               /* setup for DVB by default */
+               if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+                       if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
+                               dprintk(1, "setting band in demodulator failed\n");
+               } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+                       saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD)
+                       saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF)
+               }
+
+               /* init the saa7113 */
+               while (*i != 0xff) {
+                       if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
+                               dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num);
+                               break;
+                       }
+                       i += 2;
+               }
+               /* setup msp for analog sound: B/G Dual-FM */
+               msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
+               msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
+               msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
+               msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
+               msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
+               msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
+               msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
+       }
+
+       memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
+       /* set dd1 stream a & b */
+       saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
+       saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
+       saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+       return 0;
+}
+
+int av7110_init_v4l(struct av7110 *av7110)
+{
+       struct saa7146_dev* dev = av7110->dev;
+       struct saa7146_ext_vv *vv_data;
+       int ret;
+
+       /* special case DVB-C: these cards have an analog tuner
+          plus need some special handling, so we have separate
+          saa7146_ext_vv data for these... */
+       if (av7110->analog_tuner_flags)
+               vv_data = &av7110_vv_data_c;
+       else
+               vv_data = &av7110_vv_data_st;
+       ret = saa7146_vv_init(dev, vv_data);
+
+       if (ret) {
+               ERR("cannot init capture device. skipping\n");
+               return -ENODEV;
+       }
+       vv_data->vid_ops.vidioc_enum_input = vidioc_enum_input;
+       vv_data->vid_ops.vidioc_g_input = vidioc_g_input;
+       vv_data->vid_ops.vidioc_s_input = vidioc_s_input;
+       vv_data->vid_ops.vidioc_g_tuner = vidioc_g_tuner;
+       vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner;
+       vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency;
+       vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency;
+       vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio;
+       vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio;
+       vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio;
+       vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL;
+
+       vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner;
+       vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner;
+       vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency;
+       vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency;
+       vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL;
+       vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+       vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+       vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
+
+       if (FW_VERSION(av7110->arm_app) < 0x2623)
+               vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
+
+       if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
+               ERR("cannot register capture device. skipping\n");
+               saa7146_vv_release(dev);
+               return -ENODEV;
+       }
+       if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+               if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
+                       ERR("cannot register vbi v4l2 device. skipping\n");
+       }
+       return 0;
+}
+
+int av7110_exit_v4l(struct av7110 *av7110)
+{
+       struct saa7146_dev* dev = av7110->dev;
+
+       saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
+       saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
+
+       saa7146_vv_release(dev);
+
+       return 0;
+}
+
+
+
+/* FIXME: these values are experimental values that look better than the
+   values from the latest "official" driver -- at least for me... (MiHu) */
+static struct saa7146_standard standard[] = {
+       {
+               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
+               .v_offset       = 0x15, .v_field        = 288,
+               .h_offset       = 0x48, .h_pixels       = 708,
+               .v_max_out      = 576,  .h_max_out      = 768,
+       }, {
+               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
+               .v_offset       = 0x10, .v_field        = 244,
+               .h_offset       = 0x40, .h_pixels       = 708,
+               .v_max_out      = 480,  .h_max_out      = 640,
+       }
+};
+
+static struct saa7146_standard analog_standard[] = {
+       {
+               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
+               .v_offset       = 0x1b, .v_field        = 288,
+               .h_offset       = 0x08, .h_pixels       = 708,
+               .v_max_out      = 576,  .h_max_out      = 768,
+       }, {
+               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
+               .v_offset       = 0x10, .v_field        = 244,
+               .h_offset       = 0x40, .h_pixels       = 708,
+               .v_max_out      = 480,  .h_max_out      = 640,
+       }
+};
+
+static struct saa7146_standard dvb_standard[] = {
+       {
+               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
+               .v_offset       = 0x14, .v_field        = 288,
+               .h_offset       = 0x48, .h_pixels       = 708,
+               .v_max_out      = 576,  .h_max_out      = 768,
+       }, {
+               .name   = "NTSC",       .id             = V4L2_STD_NTSC,
+               .v_offset       = 0x10, .v_field        = 244,
+               .h_offset       = 0x40, .h_pixels       = 708,
+               .v_max_out      = 480,  .h_max_out      = 640,
+       }
+};
+
+static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
+{
+       struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+
+       if (std->id & V4L2_STD_PAL) {
+               av7110->vidmode = AV7110_VIDEO_MODE_PAL;
+               av7110_set_vidmode(av7110, av7110->vidmode);
+       }
+       else if (std->id & V4L2_STD_NTSC) {
+               av7110->vidmode = AV7110_VIDEO_MODE_NTSC;
+               av7110_set_vidmode(av7110, av7110->vidmode);
+       }
+       else
+               return -1;
+
+       return 0;
+}
+
+
+static struct saa7146_ext_vv av7110_vv_data_st = {
+       .inputs         = 1,
+       .audios         = 1,
+       .capabilities   = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
+       .flags          = 0,
+
+       .stds           = &standard[0],
+       .num_stds       = ARRAY_SIZE(standard),
+       .std_callback   = &std_callback,
+
+       .vbi_fops.open  = av7110_vbi_reset,
+       .vbi_fops.release = av7110_vbi_reset,
+       .vbi_fops.write = av7110_vbi_write,
+};
+
+static struct saa7146_ext_vv av7110_vv_data_c = {
+       .inputs         = 1,
+       .audios         = 1,
+       .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
+       .flags          = SAA7146_USE_PORT_B_FOR_VBI,
+
+       .stds           = &standard[0],
+       .num_stds       = ARRAY_SIZE(standard),
+       .std_callback   = &std_callback,
+
+       .vbi_fops.open  = av7110_vbi_reset,
+       .vbi_fops.release = av7110_vbi_reset,
+       .vbi_fops.write = av7110_vbi_write,
+};
+
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
new file mode 100644 (file)
index 0000000..12ddb53
--- /dev/null
@@ -0,0 +1,1640 @@
+/*
+ * budget-av.c: driver for the SAA7146 based Budget DVB cards
+ *              with analog video in
+ *
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
+ *                               Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "budget.h"
+#include "stv0299.h"
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+#include "tda8261.h"
+#include "tda8261_cfg.h"
+#include "tda1002x.h"
+#include "tda1004x.h"
+#include "tua6100.h"
+#include "dvb-pll.h"
+#include <media/saa7146_vv.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+
+#include "dvb_ca_en50221.h"
+
+#define DEBICICAM              0x02420000
+
+#define SLOTSTATUS_NONE         1
+#define SLOTSTATUS_PRESENT      2
+#define SLOTSTATUS_RESET        4
+#define SLOTSTATUS_READY        8
+#define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct budget_av {
+       struct budget budget;
+       struct video_device *vd;
+       int cur_input;
+       int has_saa7113;
+       struct tasklet_struct ciintf_irq_tasklet;
+       int slot_status;
+       struct dvb_ca_en50221 ca;
+       u8 reinitialise_demod:1;
+};
+
+static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
+
+
+/* GPIO Connections:
+ * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
+ * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
+ * 2 - CI Card Enable (Active Low)
+ * 3 - CI Card Detect
+ */
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
+{
+       u8 mm1[] = { 0x00 };
+       u8 mm2[] = { 0x00 };
+       struct i2c_msg msgs[2];
+
+       msgs[0].flags = 0;
+       msgs[1].flags = I2C_M_RD;
+       msgs[0].addr = msgs[1].addr = id / 2;
+       mm1[0] = reg;
+       msgs[0].len = 1;
+       msgs[1].len = 1;
+       msgs[0].buf = mm1;
+       msgs[1].buf = mm2;
+
+       i2c_transfer(i2c, msgs, 2);
+
+       return mm2[0];
+}
+
+static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
+{
+       u8 mm1[] = { reg };
+       struct i2c_msg msgs[2] = {
+               {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
+               {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
+       };
+
+       if (i2c_transfer(i2c, msgs, 2) != 2)
+               return -EIO;
+
+       return 0;
+}
+
+static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
+{
+       u8 msg[2] = { reg, val };
+       struct i2c_msg msgs;
+
+       msgs.flags = 0;
+       msgs.addr = id / 2;
+       msgs.len = 2;
+       msgs.buf = msg;
+       return i2c_transfer(i2c, &msgs, 1);
+}
+
+static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       int result;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
+       udelay(1);
+
+       result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
+       if (result == -ETIMEDOUT) {
+               ciintf_slot_shutdown(ca, slot);
+               pr_info("cam ejected 1\n");
+       }
+       return result;
+}
+
+static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       int result;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
+       udelay(1);
+
+       result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
+       if (result == -ETIMEDOUT) {
+               ciintf_slot_shutdown(ca, slot);
+               pr_info("cam ejected 2\n");
+       }
+       return result;
+}
+
+static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       int result;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
+       udelay(1);
+
+       result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
+       if (result == -ETIMEDOUT) {
+               ciintf_slot_shutdown(ca, slot);
+               pr_info("cam ejected 3\n");
+               return -ETIMEDOUT;
+       }
+       return result;
+}
+
+static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       int result;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
+       udelay(1);
+
+       result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
+       if (result == -ETIMEDOUT) {
+               ciintf_slot_shutdown(ca, slot);
+               pr_info("cam ejected 5\n");
+       }
+       return result;
+}
+
+static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       struct saa7146_dev *saa = budget_av->budget.dev;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       dprintk(1, "ciintf_slot_reset\n");
+       budget_av->slot_status = SLOTSTATUS_RESET;
+
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
+
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
+       msleep(2);
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
+       msleep(20); /* 20 ms Vcc settling time */
+
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+       msleep(20);
+
+       /* reinitialise the frontend if necessary */
+       if (budget_av->reinitialise_demod)
+               dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
+
+       return 0;
+}
+
+static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       struct saa7146_dev *saa = budget_av->budget.dev;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       dprintk(1, "ciintf_slot_shutdown\n");
+
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+       budget_av->slot_status = SLOTSTATUS_NONE;
+
+       return 0;
+}
+
+static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       struct saa7146_dev *saa = budget_av->budget.dev;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
+
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
+
+       return 0;
+}
+
+static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       struct budget_av *budget_av = (struct budget_av *) ca->data;
+       struct saa7146_dev *saa = budget_av->budget.dev;
+       int result;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       /* test the card detect line - needs to be done carefully
+        * since it never goes high for some CAMs on this interface (e.g. topuptv) */
+       if (budget_av->slot_status == SLOTSTATUS_NONE) {
+               saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
+               udelay(1);
+               if (saa7146_read(saa, PSR) & MASK_06) {
+                       if (budget_av->slot_status == SLOTSTATUS_NONE) {
+                               budget_av->slot_status = SLOTSTATUS_PRESENT;
+                               pr_info("cam inserted A\n");
+                       }
+               }
+               saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+       }
+
+       /* We also try and read from IO memory to work round the above detection bug. If
+        * there is no CAM, we will get a timeout. Only done if there is no cam
+        * present, since this test actually breaks some cams :(
+        *
+        * if the CI interface is not open, we also do the above test since we
+        * don't care if the cam has problems - we'll be resetting it on open() anyway */
+       if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
+               saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
+               result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
+               if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
+                       budget_av->slot_status = SLOTSTATUS_PRESENT;
+                       pr_info("cam inserted B\n");
+               } else if (result < 0) {
+                       if (budget_av->slot_status != SLOTSTATUS_NONE) {
+                               ciintf_slot_shutdown(ca, slot);
+                               pr_info("cam ejected 5\n");
+                               return 0;
+                       }
+               }
+       }
+
+       /* read from attribute memory in reset/ready state to know when the CAM is ready */
+       if (budget_av->slot_status == SLOTSTATUS_RESET) {
+               result = ciintf_read_attribute_mem(ca, slot, 0);
+               if (result == 0x1d) {
+                       budget_av->slot_status = SLOTSTATUS_READY;
+               }
+       }
+
+       /* work out correct return code */
+       if (budget_av->slot_status != SLOTSTATUS_NONE) {
+               if (budget_av->slot_status & SLOTSTATUS_READY) {
+                       return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+               }
+               return DVB_CA_EN50221_POLL_CAM_PRESENT;
+       }
+       return 0;
+}
+
+static int ciintf_init(struct budget_av *budget_av)
+{
+       struct saa7146_dev *saa = budget_av->budget.dev;
+       int result;
+
+       memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
+
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
+       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+
+       /* Enable DEBI pins */
+       saa7146_write(saa, MC1, MASK_27 | MASK_11);
+
+       /* register CI interface */
+       budget_av->ca.owner = THIS_MODULE;
+       budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
+       budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
+       budget_av->ca.read_cam_control = ciintf_read_cam_control;
+       budget_av->ca.write_cam_control = ciintf_write_cam_control;
+       budget_av->ca.slot_reset = ciintf_slot_reset;
+       budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
+       budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
+       budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
+       budget_av->ca.data = budget_av;
+       budget_av->budget.ci_present = 1;
+       budget_av->slot_status = SLOTSTATUS_NONE;
+
+       if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
+                                         &budget_av->ca, 0, 1)) != 0) {
+               pr_err("ci initialisation failed\n");
+               goto error;
+       }
+
+       pr_info("ci interface initialised\n");
+       return 0;
+
+error:
+       saa7146_write(saa, MC1, MASK_27);
+       return result;
+}
+
+static void ciintf_deinit(struct budget_av *budget_av)
+{
+       struct saa7146_dev *saa = budget_av->budget.dev;
+
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
+       saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
+
+       /* release the CA device */
+       dvb_ca_en50221_release(&budget_av->ca);
+
+       /* disable DEBI pins */
+       saa7146_write(saa, MC1, MASK_27);
+}
+
+
+static const u8 saa7113_tab[] = {
+       0x01, 0x08,
+       0x02, 0xc0,
+       0x03, 0x33,
+       0x04, 0x00,
+       0x05, 0x00,
+       0x06, 0xeb,
+       0x07, 0xe0,
+       0x08, 0x28,
+       0x09, 0x00,
+       0x0a, 0x80,
+       0x0b, 0x47,
+       0x0c, 0x40,
+       0x0d, 0x00,
+       0x0e, 0x01,
+       0x0f, 0x44,
+
+       0x10, 0x08,
+       0x11, 0x0c,
+       0x12, 0x7b,
+       0x13, 0x00,
+       0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
+
+       0x57, 0xff,
+       0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
+       0x5b, 0x83, 0x5e, 0x00,
+       0xff
+};
+
+static int saa7113_init(struct budget_av *budget_av)
+{
+       struct budget *budget = &budget_av->budget;
+       struct saa7146_dev *saa = budget->dev;
+       const u8 *data = saa7113_tab;
+
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
+       msleep(200);
+
+       if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
+               dprintk(1, "saa7113 not found on KNC card\n");
+               return -ENODEV;
+       }
+
+       dprintk(1, "saa7113 detected and initializing\n");
+
+       while (*data != 0xff) {
+               i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
+               data += 2;
+       }
+
+       dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
+
+       return 0;
+}
+
+static int saa7113_setinput(struct budget_av *budget_av, int input)
+{
+       struct budget *budget = &budget_av->budget;
+
+       if (1 != budget_av->has_saa7113)
+               return -ENODEV;
+
+       if (input == 1) {
+               i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
+               i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
+       } else if (input == 0) {
+               i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
+               i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
+       } else
+               return -EINVAL;
+
+       budget_av->cur_input = input;
+       return 0;
+}
+
+
+static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+       u8 m1;
+
+       aclk = 0xb5;
+       if (srate < 2000000)
+               bclk = 0x86;
+       else if (srate < 5000000)
+               bclk = 0x89;
+       else if (srate < 15000000)
+               bclk = 0x8f;
+       else if (srate < 45000000)
+               bclk = 0x95;
+
+       m1 = 0x14;
+       if (srate < 4000000)
+               m1 = 0x10;
+
+       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);
+       stv0299_writereg(fe, 0x0f, 0x80 | m1);
+
+       return 0;
+}
+
+static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 div;
+       u8 buf[4];
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
+
+       if ((c->frequency < 950000) || (c->frequency > 2150000))
+               return -EINVAL;
+
+       div = (c->frequency + (125 - 1)) / 125; /* round correctly */
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       buf[3] = 0x20;
+
+       if (c->symbol_rate < 4000000)
+               buf[3] |= 1;
+
+       if (c->frequency < 1250000)
+               buf[3] |= 0;
+       else if (c->frequency < 1550000)
+               buf[3] |= 0x40;
+       else if (c->frequency < 2050000)
+               buf[3] |= 0x80;
+       else if (c->frequency < 2150000)
+               buf[3] |= 0xC0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static u8 typhoon_cinergy1200s_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,             /* DAC not used, set to high impendance mode */
+       0x07, 0x00,             /* DAC LSB */
+       0x08, 0x40,             /* DiSEqC off */
+       0x09, 0x00,             /* FIFO */
+       0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,             // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,             // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,             // 1/2 threshold
+       0x2a, 0x14,             // 2/3 threshold
+       0x2b, 0x0f,             // 3/4 threshold
+       0x2c, 0x09,             // 5/6 threshold
+       0x2d, 0x05,             // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,             // test all FECs
+       0x32, 0x19,             // viterbi and synchro search
+       0x33, 0xfc,             // rs control
+       0x34, 0x93,             // error control
+       0x0f, 0x92,
+       0xff, 0xff
+};
+
+static struct stv0299_config typhoon_config = {
+       .demod_address = 0x68,
+       .inittab = typhoon_cinergy1200s_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
+};
+
+
+static struct stv0299_config cinergy_1200s_config = {
+       .demod_address = 0x68,
+       .inittab = typhoon_cinergy1200s_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_0,
+       .volt13_op0_op1 = STV0299_VOLT13_OP0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
+};
+
+static struct stv0299_config cinergy_1200s_1894_0010_config = {
+       .demod_address = 0x68,
+       .inittab = typhoon_cinergy1200s_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
+};
+
+static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       u8 buf[6];
+       struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
+       int i;
+
+#define CU1216_IF 36125000
+#define TUNER_MUL 62500
+
+       u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0xce;
+       buf[3] = (c->frequency < 150000000 ? 0x01 :
+                 c->frequency < 445000000 ? 0x02 : 0x04);
+       buf[4] = 0xde;
+       buf[5] = 0x20;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+
+       /* wait for the pll lock */
+       msg.flags = I2C_M_RD;
+       msg.len = 1;
+       for (i = 0; i < 20; i++) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
+                       break;
+               msleep(10);
+       }
+
+       /* switch the charge pump to the lower current */
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = &buf[2];
+       buf[2] &= ~0x40;
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static struct tda1002x_config philips_cu1216_config = {
+       .demod_address = 0x0c,
+       .invert = 1,
+};
+
+static struct tda1002x_config philips_cu1216_config_altaddress = {
+       .demod_address = 0x0d,
+       .invert = 0,
+};
+
+static struct tda10023_config philips_cu1216_tda10023_config = {
+       .demod_address = 0x0c,
+       .invert = 1,
+};
+
+static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
+{
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+       struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
+
+       // setup PLL configuration
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+       msleep(1);
+
+       return 0;
+}
+
+static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       u8 tuner_buf[4];
+       struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
+                       sizeof(tuner_buf) };
+       int tuner_frequency = 0;
+       u8 band, cp, filter;
+
+       // determine charge pump
+       tuner_frequency = c->frequency + 36166000;
+       if (tuner_frequency < 87000000)
+               return -EINVAL;
+       else if (tuner_frequency < 130000000)
+               cp = 3;
+       else if (tuner_frequency < 160000000)
+               cp = 5;
+       else if (tuner_frequency < 200000000)
+               cp = 6;
+       else if (tuner_frequency < 290000000)
+               cp = 3;
+       else if (tuner_frequency < 420000000)
+               cp = 5;
+       else if (tuner_frequency < 480000000)
+               cp = 6;
+       else if (tuner_frequency < 620000000)
+               cp = 3;
+       else if (tuner_frequency < 830000000)
+               cp = 5;
+       else if (tuner_frequency < 895000000)
+               cp = 7;
+       else
+               return -EINVAL;
+
+       // determine band
+       if (c->frequency < 49000000)
+               return -EINVAL;
+       else if (c->frequency < 161000000)
+               band = 1;
+       else if (c->frequency < 444000000)
+               band = 2;
+       else if (c->frequency < 861000000)
+               band = 4;
+       else
+               return -EINVAL;
+
+       // setup PLL filter
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               filter = 0;
+               break;
+
+       case 7000000:
+               filter = 0;
+               break;
+
+       case 8000000:
+               filter = 1;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // calculate divisor
+       // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
+       tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
+
+       // setup tuner buffer
+       tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
+       tuner_buf[1] = tuner_frequency & 0xff;
+       tuner_buf[2] = 0xca;
+       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+
+       msleep(1);
+       return 0;
+}
+
+static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
+                                          const struct firmware **fw, char *name)
+{
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+
+       return request_firmware(fw, name, &budget->dev->pci->dev);
+}
+
+static struct tda1004x_config philips_tu1216_config = {
+
+       .demod_address = 0x8,
+       .invert = 1,
+       .invert_oclk = 1,
+       .xtal_freq = TDA10046_XTAL_4M,
+       .agc_config = TDA10046_AGC_DEFAULT,
+       .if_freq = TDA10046_FREQ_3617,
+       .request_firmware = philips_tu1216_request_firmware,
+};
+
+static u8 philips_sd1878_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,
+       0x05, 0x35,
+       0x06, 0x40,
+       0x07, 0x00,
+       0x08, 0x43,
+       0x09, 0x02,
+       0x0C, 0x51,
+       0x0D, 0x82,
+       0x0E, 0x23,
+       0x10, 0x3f,
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,
+       0x16, 0x19,
+       0x17, 0x8c,
+       0x18, 0x59,
+       0x19, 0xf8,
+       0x1a, 0xfe,
+       0x1c, 0x7f,
+       0x1d, 0x00,
+       0x1e, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,
+       0x29, 0x28,
+       0x2a, 0x14,
+       0x2b, 0x0f,
+       0x2c, 0x09,
+       0x2d, 0x09,
+       0x31, 0x1f,
+       0x32, 0x19,
+       0x33, 0xfc,
+       0x34, 0x93,
+       0xff, 0xff
+};
+
+static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
+               u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+       u8 m1;
+
+       aclk = 0xb5;
+       if (srate < 2000000)
+               bclk = 0x86;
+       else if (srate < 5000000)
+               bclk = 0x89;
+       else if (srate < 15000000)
+               bclk = 0x8f;
+       else if (srate < 45000000)
+               bclk = 0x95;
+
+       m1 = 0x14;
+       if (srate < 4000000)
+               m1 = 0x10;
+
+       stv0299_writereg(fe, 0x0e, 0x23);
+       stv0299_writereg(fe, 0x0f, 0x94);
+       stv0299_writereg(fe, 0x10, 0x39);
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x15, 0xc9);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+       stv0299_writereg(fe, 0x0f, 0x80 | m1);
+
+       return 0;
+}
+
+static struct stv0299_config philips_sd1878_config = {
+       .demod_address = 0x68,
+     .inittab = philips_sd1878_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
+};
+
+/* KNC1 DVB-S (STB0899) Inittab        */
+static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
+
+       { STB0899_DEV_ID                , 0x81 },
+       { STB0899_DISCNTRL1             , 0x32 },
+       { STB0899_DISCNTRL2             , 0x80 },
+       { STB0899_DISRX_ST0             , 0x04 },
+       { STB0899_DISRX_ST1             , 0x00 },
+       { STB0899_DISPARITY             , 0x00 },
+       { STB0899_DISSTATUS             , 0x20 },
+       { STB0899_DISF22                , 0x8c },
+       { STB0899_DISF22RX              , 0x9a },
+       { STB0899_SYSREG                , 0x0b },
+       { STB0899_ACRPRESC              , 0x11 },
+       { STB0899_ACRDIV1               , 0x0a },
+       { STB0899_ACRDIV2               , 0x05 },
+       { STB0899_DACR1                 , 0x00 },
+       { STB0899_DACR2                 , 0x00 },
+       { STB0899_OUTCFG                , 0x00 },
+       { STB0899_MODECFG               , 0x00 },
+       { STB0899_IRQSTATUS_3           , 0x30 },
+       { STB0899_IRQSTATUS_2           , 0x00 },
+       { STB0899_IRQSTATUS_1           , 0x00 },
+       { STB0899_IRQSTATUS_0           , 0x00 },
+       { STB0899_IRQMSK_3              , 0xf3 },
+       { STB0899_IRQMSK_2              , 0xfc },
+       { STB0899_IRQMSK_1              , 0xff },
+       { STB0899_IRQMSK_0              , 0xff },
+       { STB0899_IRQCFG                , 0x00 },
+       { STB0899_I2CCFG                , 0x88 },
+       { STB0899_I2CRPT                , 0x58 }, /* Repeater=8, Stop=disabled */
+       { STB0899_IOPVALUE5             , 0x00 },
+       { STB0899_IOPVALUE4             , 0x20 },
+       { STB0899_IOPVALUE3             , 0xc9 },
+       { STB0899_IOPVALUE2             , 0x90 },
+       { STB0899_IOPVALUE1             , 0x40 },
+       { STB0899_IOPVALUE0             , 0x00 },
+       { STB0899_GPIO00CFG             , 0x82 },
+       { STB0899_GPIO01CFG             , 0x82 },
+       { STB0899_GPIO02CFG             , 0x82 },
+       { STB0899_GPIO03CFG             , 0x82 },
+       { STB0899_GPIO04CFG             , 0x82 },
+       { STB0899_GPIO05CFG             , 0x82 },
+       { STB0899_GPIO06CFG             , 0x82 },
+       { STB0899_GPIO07CFG             , 0x82 },
+       { STB0899_GPIO08CFG             , 0x82 },
+       { STB0899_GPIO09CFG             , 0x82 },
+       { STB0899_GPIO10CFG             , 0x82 },
+       { STB0899_GPIO11CFG             , 0x82 },
+       { STB0899_GPIO12CFG             , 0x82 },
+       { STB0899_GPIO13CFG             , 0x82 },
+       { STB0899_GPIO14CFG             , 0x82 },
+       { STB0899_GPIO15CFG             , 0x82 },
+       { STB0899_GPIO16CFG             , 0x82 },
+       { STB0899_GPIO17CFG             , 0x82 },
+       { STB0899_GPIO18CFG             , 0x82 },
+       { STB0899_GPIO19CFG             , 0x82 },
+       { STB0899_GPIO20CFG             , 0x82 },
+       { STB0899_SDATCFG               , 0xb8 },
+       { STB0899_SCLTCFG               , 0xba },
+       { STB0899_AGCRFCFG              , 0x08 }, /* 0x1c */
+       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
+       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
+       { STB0899_DIRCLKCFG             , 0x82 },
+       { STB0899_CLKOUT27CFG           , 0x7e },
+       { STB0899_STDBYCFG              , 0x82 },
+       { STB0899_CS0CFG                , 0x82 },
+       { STB0899_CS1CFG                , 0x82 },
+       { STB0899_DISEQCOCFG            , 0x20 },
+       { STB0899_GPIO32CFG             , 0x82 },
+       { STB0899_GPIO33CFG             , 0x82 },
+       { STB0899_GPIO34CFG             , 0x82 },
+       { STB0899_GPIO35CFG             , 0x82 },
+       { STB0899_GPIO36CFG             , 0x82 },
+       { STB0899_GPIO37CFG             , 0x82 },
+       { STB0899_GPIO38CFG             , 0x82 },
+       { STB0899_GPIO39CFG             , 0x82 },
+       { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+       { STB0899_FILTCTRL              , 0x00 },
+       { STB0899_SYSCTRL               , 0x00 },
+       { STB0899_STOPCLK1              , 0x20 },
+       { STB0899_STOPCLK2              , 0x00 },
+       { STB0899_INTBUFSTATUS          , 0x00 },
+       { STB0899_INTBUFCTRL            , 0x0a },
+       { 0xffff                        , 0xff },
+};
+
+static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
+       { STB0899_DEMOD                 , 0x00 },
+       { STB0899_RCOMPC                , 0xc9 },
+       { STB0899_AGC1CN                , 0x41 },
+       { STB0899_AGC1REF               , 0x08 },
+       { STB0899_RTC                   , 0x7a },
+       { STB0899_TMGCFG                , 0x4e },
+       { STB0899_AGC2REF               , 0x33 },
+       { STB0899_TLSR                  , 0x84 },
+       { STB0899_CFD                   , 0xee },
+       { STB0899_ACLC                  , 0x87 },
+       { STB0899_BCLC                  , 0x94 },
+       { STB0899_EQON                  , 0x41 },
+       { STB0899_LDT                   , 0xdd },
+       { STB0899_LDT2                  , 0xc9 },
+       { STB0899_EQUALREF              , 0xb4 },
+       { STB0899_TMGRAMP               , 0x10 },
+       { STB0899_TMGTHD                , 0x30 },
+       { STB0899_IDCCOMP               , 0xfb },
+       { STB0899_QDCCOMP               , 0x03 },
+       { STB0899_POWERI                , 0x3b },
+       { STB0899_POWERQ                , 0x3d },
+       { STB0899_RCOMP                 , 0x81 },
+       { STB0899_AGCIQIN               , 0x80 },
+       { STB0899_AGC2I1                , 0x04 },
+       { STB0899_AGC2I2                , 0xf5 },
+       { STB0899_TLIR                  , 0x25 },
+       { STB0899_RTF                   , 0x80 },
+       { STB0899_DSTATUS               , 0x00 },
+       { STB0899_LDI                   , 0xca },
+       { STB0899_CFRM                  , 0xf1 },
+       { STB0899_CFRL                  , 0xf3 },
+       { STB0899_NIRM                  , 0x2a },
+       { STB0899_NIRL                  , 0x05 },
+       { STB0899_ISYMB                 , 0x17 },
+       { STB0899_QSYMB                 , 0xfa },
+       { STB0899_SFRH                  , 0x2f },
+       { STB0899_SFRM                  , 0x68 },
+       { STB0899_SFRL                  , 0x40 },
+       { STB0899_SFRUPH                , 0x2f },
+       { STB0899_SFRUPM                , 0x68 },
+       { STB0899_SFRUPL                , 0x40 },
+       { STB0899_EQUAI1                , 0xfd },
+       { STB0899_EQUAQ1                , 0x04 },
+       { STB0899_EQUAI2                , 0x0f },
+       { STB0899_EQUAQ2                , 0xff },
+       { STB0899_EQUAI3                , 0xdf },
+       { STB0899_EQUAQ3                , 0xfa },
+       { STB0899_EQUAI4                , 0x37 },
+       { STB0899_EQUAQ4                , 0x0d },
+       { STB0899_EQUAI5                , 0xbd },
+       { STB0899_EQUAQ5                , 0xf7 },
+       { STB0899_DSTATUS2              , 0x00 },
+       { STB0899_VSTATUS               , 0x00 },
+       { STB0899_VERROR                , 0xff },
+       { STB0899_IQSWAP                , 0x2a },
+       { STB0899_ECNT1M                , 0x00 },
+       { STB0899_ECNT1L                , 0x00 },
+       { STB0899_ECNT2M                , 0x00 },
+       { STB0899_ECNT2L                , 0x00 },
+       { STB0899_ECNT3M                , 0x00 },
+       { STB0899_ECNT3L                , 0x00 },
+       { STB0899_FECAUTO1              , 0x06 },
+       { STB0899_FECM                  , 0x01 },
+       { STB0899_VTH12                 , 0xf0 },
+       { STB0899_VTH23                 , 0xa0 },
+       { STB0899_VTH34                 , 0x78 },
+       { STB0899_VTH56                 , 0x4e },
+       { STB0899_VTH67                 , 0x48 },
+       { STB0899_VTH78                 , 0x38 },
+       { STB0899_PRVIT                 , 0xff },
+       { STB0899_VITSYNC               , 0x19 },
+       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+       { STB0899_TSULC                 , 0x42 },
+       { STB0899_RSLLC                 , 0x40 },
+       { STB0899_TSLPL                 , 0x12 },
+       { STB0899_TSCFGH                , 0x0c },
+       { STB0899_TSCFGM                , 0x00 },
+       { STB0899_TSCFGL                , 0x0c },
+       { STB0899_TSOUT                 , 0x4d }, /* 0x0d for CAM */
+       { STB0899_RSSYNCDEL             , 0x00 },
+       { STB0899_TSINHDELH             , 0x02 },
+       { STB0899_TSINHDELM             , 0x00 },
+       { STB0899_TSINHDELL             , 0x00 },
+       { STB0899_TSLLSTKM              , 0x00 },
+       { STB0899_TSLLSTKL              , 0x00 },
+       { STB0899_TSULSTKM              , 0x00 },
+       { STB0899_TSULSTKL              , 0xab },
+       { STB0899_PCKLENUL              , 0x00 },
+       { STB0899_PCKLENLL              , 0xcc },
+       { STB0899_RSPCKLEN              , 0xcc },
+       { STB0899_TSSTATUS              , 0x80 },
+       { STB0899_ERRCTRL1              , 0xb6 },
+       { STB0899_ERRCTRL2              , 0x96 },
+       { STB0899_ERRCTRL3              , 0x89 },
+       { STB0899_DMONMSK1              , 0x27 },
+       { STB0899_DMONMSK0              , 0x03 },
+       { STB0899_DEMAPVIT              , 0x5c },
+       { STB0899_PLPARM                , 0x1f },
+       { STB0899_PDELCTRL              , 0x48 },
+       { STB0899_PDELCTRL2             , 0x00 },
+       { STB0899_BBHCTRL1              , 0x00 },
+       { STB0899_BBHCTRL2              , 0x00 },
+       { STB0899_HYSTTHRESH            , 0x77 },
+       { STB0899_MATCSTM               , 0x00 },
+       { STB0899_MATCSTL               , 0x00 },
+       { STB0899_UPLCSTM               , 0x00 },
+       { STB0899_UPLCSTL               , 0x00 },
+       { STB0899_DFLCSTM               , 0x00 },
+       { STB0899_DFLCSTL               , 0x00 },
+       { STB0899_SYNCCST               , 0x00 },
+       { STB0899_SYNCDCSTM             , 0x00 },
+       { STB0899_SYNCDCSTL             , 0x00 },
+       { STB0899_ISI_ENTRY             , 0x00 },
+       { STB0899_ISI_BIT_EN            , 0x00 },
+       { STB0899_MATSTRM               , 0x00 },
+       { STB0899_MATSTRL               , 0x00 },
+       { STB0899_UPLSTRM               , 0x00 },
+       { STB0899_UPLSTRL               , 0x00 },
+       { STB0899_DFLSTRM               , 0x00 },
+       { STB0899_DFLSTRL               , 0x00 },
+       { STB0899_SYNCSTR               , 0x00 },
+       { STB0899_SYNCDSTRM             , 0x00 },
+       { STB0899_SYNCDSTRL             , 0x00 },
+       { STB0899_CFGPDELSTATUS1        , 0x10 },
+       { STB0899_CFGPDELSTATUS2        , 0x00 },
+       { STB0899_BBFERRORM             , 0x00 },
+       { STB0899_BBFERRORL             , 0x00 },
+       { STB0899_UPKTERRORM            , 0x00 },
+       { STB0899_UPKTERRORL            , 0x00 },
+       { 0xffff                        , 0xff },
+};
+
+/* STB0899 demodulator config for the KNC1 and clones */
+static struct stb0899_config knc1_dvbs2_config = {
+       .init_dev               = knc1_stb0899_s1_init_1,
+       .init_s2_demod          = stb0899_s2_init_2,
+       .init_s1_demod          = knc1_stb0899_s1_init_3,
+       .init_s2_fec            = stb0899_s2_init_4,
+       .init_tst               = stb0899_s1_init_5,
+
+       .postproc               = NULL,
+
+       .demod_address          = 0x68,
+//     .ts_output_mode         = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL      */
+       .block_sync_mode        = STB0899_SYNC_FORCED,  /* DSS, SYNC_FORCED/UNSYNCED    */
+//     .ts_pfbit_toggle        = STB0899_MPEG_NORMAL,  /* DirecTV, MPEG toggling seq   */
+
+       .xtal_freq              = 27000000,
+       .inversion              = IQ_SWAP_OFF, /* 1 */
+
+       .lo_clk                 = 76500000,
+       .hi_clk                 = 90000000,
+
+       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
+       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
+       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
+       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
+       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
+       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
+       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
+       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
+       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
+
+       .tuner_get_frequency    = tda8261_get_frequency,
+       .tuner_set_frequency    = tda8261_set_frequency,
+       .tuner_set_bandwidth    = NULL,
+       .tuner_get_bandwidth    = tda8261_get_bandwidth,
+       .tuner_set_rfsiggain    = NULL
+};
+
+/*
+ * SD1878/SHA tuner config
+ * 1F, Single I/P, Horizontal mount, High Sensitivity
+ */
+static const struct tda8261_config sd1878c_config = {
+//     .name           = "SD1878/SHA",
+       .addr           = 0x60,
+       .step_size      = TDA8261_STEP_1000 /* kHz */
+};
+
+static u8 read_pwm(struct budget_av *budget_av)
+{
+       u8 b = 0xff;
+       u8 pwm;
+       struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
+       {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
+       };
+
+       if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
+           || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+#define SUBID_DVBS_KNC1                        0x0010
+#define SUBID_DVBS_KNC1_PLUS           0x0011
+#define SUBID_DVBS_TYPHOON             0x4f56
+#define SUBID_DVBS_CINERGY1200         0x1154
+#define SUBID_DVBS_CYNERGY1200N        0x1155
+#define SUBID_DVBS_TV_STAR             0x0014
+#define SUBID_DVBS_TV_STAR_PLUS_X4     0x0015
+#define SUBID_DVBS_TV_STAR_CI          0x0016
+#define SUBID_DVBS2_KNC1               0x0018
+#define SUBID_DVBS2_KNC1_OEM           0x0019
+#define SUBID_DVBS_EASYWATCH_1         0x001a
+#define SUBID_DVBS_EASYWATCH_2         0x001b
+#define SUBID_DVBS2_EASYWATCH          0x001d
+#define SUBID_DVBS_EASYWATCH           0x001e
+
+#define SUBID_DVBC_EASYWATCH           0x002a
+#define SUBID_DVBC_EASYWATCH_MK3       0x002c
+#define SUBID_DVBC_KNC1                        0x0020
+#define SUBID_DVBC_KNC1_PLUS           0x0021
+#define SUBID_DVBC_KNC1_MK3            0x0022
+#define SUBID_DVBC_KNC1_TDA10024       0x0028
+#define SUBID_DVBC_KNC1_PLUS_MK3       0x0023
+#define SUBID_DVBC_CINERGY1200         0x1156
+#define SUBID_DVBC_CINERGY1200_MK3     0x1176
+
+#define SUBID_DVBT_EASYWATCH           0x003a
+#define SUBID_DVBT_KNC1_PLUS           0x0031
+#define SUBID_DVBT_KNC1                        0x0030
+#define SUBID_DVBT_CINERGY1200         0x1157
+
+static void frontend_init(struct budget_av *budget_av)
+{
+       struct saa7146_dev * saa = budget_av->budget.dev;
+       struct dvb_frontend * fe = NULL;
+
+       /* Enable / PowerON Frontend */
+       saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+
+       /* Wait for PowerON */
+       msleep(100);
+
+       /* additional setup necessary for the PLUS cards */
+       switch (saa->pci->subsystem_device) {
+               case SUBID_DVBS_KNC1_PLUS:
+               case SUBID_DVBC_KNC1_PLUS:
+               case SUBID_DVBT_KNC1_PLUS:
+               case SUBID_DVBC_EASYWATCH:
+               case SUBID_DVBC_KNC1_PLUS_MK3:
+               case SUBID_DVBS2_KNC1:
+               case SUBID_DVBS2_KNC1_OEM:
+               case SUBID_DVBS2_EASYWATCH:
+                       saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
+                       break;
+       }
+
+       switch (saa->pci->subsystem_device) {
+
+       case SUBID_DVBS_KNC1:
+               /*
+                * maybe that setting is needed for other dvb-s cards as well,
+                * but so far it has been only confirmed for this type
+                */
+               budget_av->reinitialise_demod = 1;
+               /* fall through */
+       case SUBID_DVBS_KNC1_PLUS:
+       case SUBID_DVBS_EASYWATCH_1:
+               if (saa->pci->subsystem_vendor == 0x1894) {
+                       fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
+                                            &budget_av->budget.i2c_adap);
+                       if (fe) {
+                               dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
+                       }
+               } else {
+                       fe = dvb_attach(stv0299_attach, &typhoon_config,
+                                            &budget_av->budget.i2c_adap);
+                       if (fe) {
+                               fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
+                       }
+               }
+               break;
+
+       case SUBID_DVBS_TV_STAR:
+       case SUBID_DVBS_TV_STAR_PLUS_X4:
+       case SUBID_DVBS_TV_STAR_CI:
+       case SUBID_DVBS_CYNERGY1200N:
+       case SUBID_DVBS_EASYWATCH:
+       case SUBID_DVBS_EASYWATCH_2:
+               fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
+                               &budget_av->budget.i2c_adap);
+               if (fe) {
+                       dvb_attach(dvb_pll_attach, fe, 0x60,
+                                  &budget_av->budget.i2c_adap,
+                                  DVB_PLL_PHILIPS_SD1878_TDA8261);
+               }
+               break;
+
+       case SUBID_DVBS_TYPHOON:
+               fe = dvb_attach(stv0299_attach, &typhoon_config,
+                                   &budget_av->budget.i2c_adap);
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
+               }
+               break;
+       case SUBID_DVBS2_KNC1:
+       case SUBID_DVBS2_KNC1_OEM:
+       case SUBID_DVBS2_EASYWATCH:
+               budget_av->reinitialise_demod = 1;
+               if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
+                       dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
+
+               break;
+       case SUBID_DVBS_CINERGY1200:
+               fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
+                                   &budget_av->budget.i2c_adap);
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
+               }
+               break;
+
+       case SUBID_DVBC_KNC1:
+       case SUBID_DVBC_KNC1_PLUS:
+       case SUBID_DVBC_CINERGY1200:
+       case SUBID_DVBC_EASYWATCH:
+               budget_av->reinitialise_demod = 1;
+               budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
+               fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
+                                    &budget_av->budget.i2c_adap,
+                                    read_pwm(budget_av));
+               if (fe == NULL)
+                       fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
+                                            &budget_av->budget.i2c_adap,
+                                            read_pwm(budget_av));
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
+               }
+               break;
+
+       case SUBID_DVBC_EASYWATCH_MK3:
+       case SUBID_DVBC_CINERGY1200_MK3:
+       case SUBID_DVBC_KNC1_MK3:
+       case SUBID_DVBC_KNC1_TDA10024:
+       case SUBID_DVBC_KNC1_PLUS_MK3:
+               budget_av->reinitialise_demod = 1;
+               budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
+               fe = dvb_attach(tda10023_attach,
+                       &philips_cu1216_tda10023_config,
+                       &budget_av->budget.i2c_adap,
+                       read_pwm(budget_av));
+               if (fe) {
+                       fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
+               }
+               break;
+
+       case SUBID_DVBT_EASYWATCH:
+       case SUBID_DVBT_KNC1:
+       case SUBID_DVBT_KNC1_PLUS:
+       case SUBID_DVBT_CINERGY1200:
+               budget_av->reinitialise_demod = 1;
+               fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
+                                    &budget_av->budget.i2c_adap);
+               if (fe) {
+                       fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
+                       fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
+               }
+               break;
+       }
+
+       if (fe == NULL) {
+               pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      saa->pci->vendor,
+                      saa->pci->device,
+                      saa->pci->subsystem_vendor,
+                      saa->pci->subsystem_device);
+               return;
+       }
+
+       budget_av->budget.dvb_frontend = fe;
+
+       if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
+                                 budget_av->budget.dvb_frontend)) {
+               pr_err("Frontend registration failed!\n");
+               dvb_frontend_detach(budget_av->budget.dvb_frontend);
+               budget_av->budget.dvb_frontend = NULL;
+       }
+}
+
+
+static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
+{
+       struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
+
+       dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
+
+       if (*isr & MASK_10)
+               ttpci_budget_irq10_handler(dev, isr);
+}
+
+static int budget_av_detach(struct saa7146_dev *dev)
+{
+       struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
+       int err;
+
+       dprintk(2, "dev: %p\n", dev);
+
+       if (1 == budget_av->has_saa7113) {
+               saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
+
+               msleep(200);
+
+               saa7146_unregister_device(&budget_av->vd, dev);
+
+               saa7146_vv_release(dev);
+       }
+
+       if (budget_av->budget.ci_present)
+               ciintf_deinit(budget_av);
+
+       if (budget_av->budget.dvb_frontend != NULL) {
+               dvb_unregister_frontend(budget_av->budget.dvb_frontend);
+               dvb_frontend_detach(budget_av->budget.dvb_frontend);
+       }
+       err = ttpci_budget_deinit(&budget_av->budget);
+
+       kfree(budget_av);
+
+       return err;
+}
+
+#define KNC1_INPUTS 2
+static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
+       { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
+               V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+       { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
+               V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+};
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+       dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
+       if (i->index >= KNC1_INPUTS)
+               return -EINVAL;
+       memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
+       return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+       *i = budget_av->cur_input;
+
+       dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
+       return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+       struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+       struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+       dprintk(1, "VIDIOC_S_INPUT %d\n", input);
+       return saa7113_setinput(budget_av, input);
+}
+
+static struct saa7146_ext_vv vv_data;
+
+static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+       struct budget_av *budget_av;
+       u8 *mac;
+       int err;
+
+       dprintk(2, "dev: %p\n", dev);
+
+       if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
+               return -ENOMEM;
+
+       budget_av->has_saa7113 = 0;
+       budget_av->budget.ci_present = 0;
+
+       dev->ext_priv = budget_av;
+
+       err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
+                               adapter_nr);
+       if (err) {
+               kfree(budget_av);
+               return err;
+       }
+
+       /* knc1 initialization */
+       saa7146_write(dev, DD1_STREAM_B, 0x04000000);
+       saa7146_write(dev, DD1_INIT, 0x07000600);
+       saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
+
+       if (saa7113_init(budget_av) == 0) {
+               budget_av->has_saa7113 = 1;
+
+               if (0 != saa7146_vv_init(dev, &vv_data)) {
+                       /* fixme: proper cleanup here */
+                       ERR("cannot init vv subsystem\n");
+                       return err;
+               }
+               vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
+               vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
+               vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
+
+               if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
+                       /* fixme: proper cleanup here */
+                       ERR("cannot register capture v4l2 device\n");
+                       saa7146_vv_release(dev);
+                       return err;
+               }
+
+               /* beware: this modifies dev->vv ... */
+               saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
+                                               SAA7146_HPS_SYNC_PORT_A);
+
+               saa7113_setinput(budget_av, 0);
+       }
+
+       /* fixme: find some sane values here... */
+       saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
+
+       mac = budget_av->budget.dvb_adapter.proposed_mac;
+       if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
+               pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
+                      budget_av->budget.dvb_adapter.num);
+               memset(mac, 0, 6);
+       } else {
+               pr_info("KNC1-%d: MAC addr = %pM\n",
+                       budget_av->budget.dvb_adapter.num, mac);
+       }
+
+       budget_av->budget.dvb_adapter.priv = budget_av;
+       frontend_init(budget_av);
+       ciintf_init(budget_av);
+
+       ttpci_budget_init_hooks(&budget_av->budget);
+
+       return 0;
+}
+
+static struct saa7146_standard standard[] = {
+       {.name = "PAL",.id = V4L2_STD_PAL,
+        .v_offset = 0x17,.v_field = 288,
+        .h_offset = 0x14,.h_pixels = 680,
+        .v_max_out = 576,.h_max_out = 768 },
+
+       {.name = "NTSC",.id = V4L2_STD_NTSC,
+        .v_offset = 0x16,.v_field = 240,
+        .h_offset = 0x06,.h_pixels = 708,
+        .v_max_out = 480,.h_max_out = 640, },
+};
+
+static struct saa7146_ext_vv vv_data = {
+       .inputs = 2,
+       .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
+       .flags = 0,
+       .stds = &standard[0],
+       .num_stds = ARRAY_SIZE(standard),
+};
+
+static struct saa7146_extension budget_extension;
+
+MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
+MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
+MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
+MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
+MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
+MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
+MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
+MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
+MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
+MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
+MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
+MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
+MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
+MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
+MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
+MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
+MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
+MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
+MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
+MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
+
+static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
+       MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
+       MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
+       MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
+       MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
+       MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
+       MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
+       MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
+       MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
+       MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
+       MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
+       MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
+       MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
+       MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
+       MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
+       MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
+       MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
+       MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
+       MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
+       MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
+       MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
+       MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
+       MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
+       MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
+       MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
+       MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
+       MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
+       MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
+       MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
+       {
+        .vendor = 0,
+       }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+static struct saa7146_extension budget_extension = {
+       .name = "budget_av",
+       .flags = SAA7146_USE_I2C_IRQ,
+
+       .pci_tbl = pci_tbl,
+
+       .module = THIS_MODULE,
+       .attach = budget_av_attach,
+       .detach = budget_av_detach,
+
+       .irq_mask = MASK_10,
+       .irq_func = budget_av_irq,
+};
+
+static int __init budget_av_init(void)
+{
+       return saa7146_register_extension(&budget_extension);
+}
+
+static void __exit budget_av_exit(void)
+{
+       saa7146_unregister_extension(&budget_extension);
+}
+
+module_init(budget_av_init);
+module_exit(budget_av_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
+                  "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
new file mode 100644 (file)
index 0000000..98e5241
--- /dev/null
@@ -0,0 +1,1591 @@
+/*
+ * budget-ci.c: driver for the SAA7146 based Budget DVB cards
+ *
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
+ *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
+ *
+ * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <media/rc-core.h>
+
+#include "budget.h"
+
+#include "dvb_ca_en50221.h"
+#include "stv0299.h"
+#include "stv0297.h"
+#include "tda1004x.h"
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+#include "stb6100.h"
+#include "stb6100_cfg.h"
+#include "lnbp21.h"
+#include "bsbe1.h"
+#include "bsru6.h"
+#include "tda1002x.h"
+#include "tda827x.h"
+#include "bsbe1-d01a.h"
+
+#define MODULE_NAME "budget_ci"
+
+/*
+ * Regarding DEBIADDR_IR:
+ * Some CI modules hang if random addresses are read.
+ * Using address 0x4000 for the IR read means that we
+ * use the same address as for CI version, which should
+ * be a safe default.
+ */
+#define DEBIADDR_IR            0x4000
+#define DEBIADDR_CICONTROL     0x0000
+#define DEBIADDR_CIVERSION     0x4000
+#define DEBIADDR_IO            0x1000
+#define DEBIADDR_ATTR          0x3000
+
+#define CICONTROL_RESET                0x01
+#define CICONTROL_ENABLETS     0x02
+#define CICONTROL_CAMDETECT    0x08
+
+#define DEBICICTL              0x00420000
+#define DEBICICAM              0x02420000
+
+#define SLOTSTATUS_NONE                1
+#define SLOTSTATUS_PRESENT     2
+#define SLOTSTATUS_RESET       4
+#define SLOTSTATUS_READY       8
+#define SLOTSTATUS_OCCUPIED    (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
+
+/* RC5 device wildcard */
+#define IR_DEVICE_ANY          255
+
+static int rc5_device = -1;
+module_param(rc5_device, int, 0644);
+MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
+
+static int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct budget_ci_ir {
+       struct rc_dev *dev;
+       struct tasklet_struct msp430_irq_tasklet;
+       char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
+       char phys[32];
+       int rc5_device;
+       u32 ir_key;
+       bool have_command;
+       bool full_rc5;          /* Outputs a full RC5 code */
+};
+
+struct budget_ci {
+       struct budget budget;
+       struct tasklet_struct ciintf_irq_tasklet;
+       int slot_status;
+       int ci_irq;
+       struct dvb_ca_en50221 ca;
+       struct budget_ci_ir ir;
+       u8 tuner_pll_address; /* used for philips_tdm1316l configs */
+};
+
+static void msp430_ir_interrupt(unsigned long data)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) data;
+       struct rc_dev *dev = budget_ci->ir.dev;
+       u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
+
+       /*
+        * The msp430 chip can generate two different bytes, command and device
+        *
+        * type1: X1CCCCCC, C = command bits (0 - 63)
+        * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
+        *
+        * Each signal from the remote control can generate one or more command
+        * bytes and one or more device bytes. For the repeated bytes, the
+        * highest bit (X) is set. The first command byte is always generated
+        * before the first device byte. Other than that, no specific order
+        * seems to apply. To make life interesting, bytes can also be lost.
+        *
+        * Only when we have a command and device byte, a keypress is
+        * generated.
+        */
+
+       if (ir_debug)
+               printk("budget_ci: received byte 0x%02x\n", command);
+
+       /* Remove repeat bit, we use every command */
+       command = command & 0x7f;
+
+       /* Is this a RC5 command byte? */
+       if (command & 0x40) {
+               budget_ci->ir.have_command = true;
+               budget_ci->ir.ir_key = command & 0x3f;
+               return;
+       }
+
+       /* It's a RC5 device byte */
+       if (!budget_ci->ir.have_command)
+               return;
+       budget_ci->ir.have_command = false;
+
+       if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
+           budget_ci->ir.rc5_device != (command & 0x1f))
+               return;
+
+       if (budget_ci->ir.full_rc5) {
+               rc_keydown(dev,
+                          budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
+                          (command & 0x20) ? 1 : 0);
+               return;
+       }
+
+       /* FIXME: We should generate complete scancodes for all devices */
+       rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
+}
+
+static int msp430_ir_init(struct budget_ci *budget_ci)
+{
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       struct rc_dev *dev;
+       int error;
+
+       dev = rc_allocate_device();
+       if (!dev) {
+               printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
+               return -ENOMEM;
+       }
+
+       snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
+                "Budget-CI dvb ir receiver %s", saa->name);
+       snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
+                "pci-%s/ir0", pci_name(saa->pci));
+
+       dev->driver_name = MODULE_NAME;
+       dev->input_name = budget_ci->ir.name;
+       dev->input_phys = budget_ci->ir.phys;
+       dev->input_id.bustype = BUS_PCI;
+       dev->input_id.version = 1;
+       if (saa->pci->subsystem_vendor) {
+               dev->input_id.vendor = saa->pci->subsystem_vendor;
+               dev->input_id.product = saa->pci->subsystem_device;
+       } else {
+               dev->input_id.vendor = saa->pci->vendor;
+               dev->input_id.product = saa->pci->device;
+       }
+       dev->dev.parent = &saa->pci->dev;
+
+       if (rc5_device < 0)
+               budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+       else
+               budget_ci->ir.rc5_device = rc5_device;
+
+       /* Select keymap and address */
+       switch (budget_ci->budget.dev->pci->subsystem_device) {
+       case 0x100c:
+       case 0x100f:
+       case 0x1011:
+       case 0x1012:
+               /* The hauppauge keymap is a superset of these remotes */
+               dev->map_name = RC_MAP_HAUPPAUGE;
+               budget_ci->ir.full_rc5 = true;
+
+               if (rc5_device < 0)
+                       budget_ci->ir.rc5_device = 0x1f;
+               break;
+       case 0x1010:
+       case 0x1017:
+       case 0x1019:
+       case 0x101a:
+       case 0x101b:
+               /* for the Technotrend 1500 bundled remote */
+               dev->map_name = RC_MAP_TT_1500;
+               break;
+       default:
+               /* unknown remote */
+               dev->map_name = RC_MAP_BUDGET_CI_OLD;
+               break;
+       }
+       if (!budget_ci->ir.full_rc5)
+               dev->scanmask = 0xff;
+
+       error = rc_register_device(dev);
+       if (error) {
+               printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
+               rc_free_device(dev);
+               return error;
+       }
+
+       budget_ci->ir.dev = dev;
+
+       tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
+                    (unsigned long) budget_ci);
+
+       SAA7146_IER_ENABLE(saa, MASK_06);
+       saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
+
+       return 0;
+}
+
+static void msp430_ir_deinit(struct budget_ci *budget_ci)
+{
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+
+       SAA7146_IER_DISABLE(saa, MASK_06);
+       saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
+       tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
+
+       rc_unregister_device(budget_ci->ir.dev);
+}
+
+static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
+                                    DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
+}
+
+static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
+                                     DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
+}
+
+static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
+                                    DEBIADDR_IO | (address & 3), 1, 1, 0);
+}
+
+static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
+                                     DEBIADDR_IO | (address & 3), 1, value, 1, 0);
+}
+
+static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       if (budget_ci->ci_irq) {
+               // trigger on RISING edge during reset so we know when READY is re-asserted
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+       }
+       budget_ci->slot_status = SLOTSTATUS_RESET;
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
+       msleep(1);
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
+                              CICONTROL_RESET, 1, 0);
+
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+       return 0;
+}
+
+static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+       return 0;
+}
+
+static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       int tmp;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
+
+       tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
+                              tmp | CICONTROL_ENABLETS, 1, 0);
+
+       ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
+       return 0;
+}
+
+static void ciintf_interrupt(unsigned long data)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) data;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       unsigned int flags;
+
+       // ensure we don't get spurious IRQs during initialisation
+       if (!budget_ci->budget.ci_present)
+               return;
+
+       // read the CAM status
+       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+       if (flags & CICONTROL_CAMDETECT) {
+
+               // GPIO should be set to trigger on falling edge if a CAM is present
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
+
+               if (budget_ci->slot_status & SLOTSTATUS_NONE) {
+                       // CAM insertion IRQ
+                       budget_ci->slot_status = SLOTSTATUS_PRESENT;
+                       dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
+                                                    DVB_CA_EN50221_CAMCHANGE_INSERTED);
+
+               } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
+                       // CAM ready (reset completed)
+                       budget_ci->slot_status = SLOTSTATUS_READY;
+                       dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
+
+               } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
+                       // FR/DA IRQ
+                       dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
+               }
+       } else {
+
+               // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
+               // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
+               // the CAM might not actually be ready yet.
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+
+               // generate a CAM removal IRQ if we haven't already
+               if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
+                       // CAM removal IRQ
+                       budget_ci->slot_status = SLOTSTATUS_NONE;
+                       dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
+                                                    DVB_CA_EN50221_CAMCHANGE_REMOVED);
+               }
+       }
+}
+
+static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+       unsigned int flags;
+
+       // ensure we don't get spurious IRQs during initialisation
+       if (!budget_ci->budget.ci_present)
+               return -EINVAL;
+
+       // read the CAM status
+       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+       if (flags & CICONTROL_CAMDETECT) {
+               // mark it as present if it wasn't before
+               if (budget_ci->slot_status & SLOTSTATUS_NONE) {
+                       budget_ci->slot_status = SLOTSTATUS_PRESENT;
+               }
+
+               // during a RESET, we check if we can read from IO memory to see when CAM is ready
+               if (budget_ci->slot_status & SLOTSTATUS_RESET) {
+                       if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
+                               budget_ci->slot_status = SLOTSTATUS_READY;
+                       }
+               }
+       } else {
+               budget_ci->slot_status = SLOTSTATUS_NONE;
+       }
+
+       if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+               if (budget_ci->slot_status & SLOTSTATUS_READY) {
+                       return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+               }
+               return DVB_CA_EN50221_POLL_CAM_PRESENT;
+       }
+
+       return 0;
+}
+
+static int ciintf_init(struct budget_ci *budget_ci)
+{
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       int flags;
+       int result;
+       int ci_version;
+       int ca_flags;
+
+       memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
+
+       // enable DEBI pins
+       saa7146_write(saa, MC1, MASK_27 | MASK_11);
+
+       // test if it is there
+       ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
+       if ((ci_version & 0xa0) != 0xa0) {
+               result = -ENODEV;
+               goto error;
+       }
+
+       // determine whether a CAM is present or not
+       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+       budget_ci->slot_status = SLOTSTATUS_NONE;
+       if (flags & CICONTROL_CAMDETECT)
+               budget_ci->slot_status = SLOTSTATUS_PRESENT;
+
+       // version 0xa2 of the CI firmware doesn't generate interrupts
+       if (ci_version == 0xa2) {
+               ca_flags = 0;
+               budget_ci->ci_irq = 0;
+       } else {
+               ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
+                               DVB_CA_EN50221_FLAG_IRQ_FR |
+                               DVB_CA_EN50221_FLAG_IRQ_DA;
+               budget_ci->ci_irq = 1;
+       }
+
+       // register CI interface
+       budget_ci->ca.owner = THIS_MODULE;
+       budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
+       budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
+       budget_ci->ca.read_cam_control = ciintf_read_cam_control;
+       budget_ci->ca.write_cam_control = ciintf_write_cam_control;
+       budget_ci->ca.slot_reset = ciintf_slot_reset;
+       budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
+       budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
+       budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
+       budget_ci->ca.data = budget_ci;
+       if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
+                                         &budget_ci->ca,
+                                         ca_flags, 1)) != 0) {
+               printk("budget_ci: CI interface detected, but initialisation failed.\n");
+               goto error;
+       }
+
+       // Setup CI slot IRQ
+       if (budget_ci->ci_irq) {
+               tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
+               if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
+               } else {
+                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+               }
+               SAA7146_IER_ENABLE(saa, MASK_03);
+       }
+
+       // enable interface
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
+                              CICONTROL_RESET, 1, 0);
+
+       // success!
+       printk("budget_ci: CI interface initialised\n");
+       budget_ci->budget.ci_present = 1;
+
+       // forge a fake CI IRQ so the CAM state is setup correctly
+       if (budget_ci->ci_irq) {
+               flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+               if (budget_ci->slot_status != SLOTSTATUS_NONE)
+                       flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
+               dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
+       }
+
+       return 0;
+
+error:
+       saa7146_write(saa, MC1, MASK_27);
+       return result;
+}
+
+static void ciintf_deinit(struct budget_ci *budget_ci)
+{
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+
+       // disable CI interrupts
+       if (budget_ci->ci_irq) {
+               SAA7146_IER_DISABLE(saa, MASK_03);
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
+               tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+       }
+
+       // reset interface
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
+       msleep(1);
+       ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
+                              CICONTROL_RESET, 1, 0);
+
+       // disable TS data stream to CI interface
+       saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
+
+       // release the CA device
+       dvb_ca_en50221_release(&budget_ci->ca);
+
+       // disable DEBI pins
+       saa7146_write(saa, MC1, MASK_27);
+}
+
+static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
+
+       dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
+
+       if (*isr & MASK_06)
+               tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
+
+       if (*isr & MASK_10)
+               ttpci_budget_irq10_handler(dev, isr);
+
+       if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
+               tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
+}
+
+static u8 philips_su1278_tt_inittab[] = {
+       0x01, 0x0f,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x5b,
+       0x05, 0x85,
+       0x06, 0x02,
+       0x07, 0x00,
+       0x08, 0x02,
+       0x09, 0x00,
+       0x0C, 0x01,
+       0x0D, 0x81,
+       0x0E, 0x44,
+       0x0f, 0x14,
+       0x10, 0x3c,
+       0x11, 0x84,
+       0x12, 0xda,
+       0x13, 0x97,
+       0x14, 0x95,
+       0x15, 0xc9,
+       0x16, 0x19,
+       0x17, 0x8c,
+       0x18, 0x59,
+       0x19, 0xf8,
+       0x1a, 0xfe,
+       0x1c, 0x7f,
+       0x1d, 0x00,
+       0x1e, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,
+       0x29, 0x28,
+       0x2a, 0x14,
+       0x2b, 0x0f,
+       0x2c, 0x09,
+       0x2d, 0x09,
+       0x31, 0x1f,
+       0x32, 0x19,
+       0x33, 0xfc,
+       0x34, 0x93,
+       0xff, 0xff
+};
+
+static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
+{
+       stv0299_writereg(fe, 0x0e, 0x44);
+       if (srate >= 10000000) {
+               stv0299_writereg(fe, 0x13, 0x97);
+               stv0299_writereg(fe, 0x14, 0x95);
+               stv0299_writereg(fe, 0x15, 0xc9);
+               stv0299_writereg(fe, 0x17, 0x8c);
+               stv0299_writereg(fe, 0x1a, 0xfe);
+               stv0299_writereg(fe, 0x1c, 0x7f);
+               stv0299_writereg(fe, 0x2d, 0x09);
+       } else {
+               stv0299_writereg(fe, 0x13, 0x99);
+               stv0299_writereg(fe, 0x14, 0x8d);
+               stv0299_writereg(fe, 0x15, 0xce);
+               stv0299_writereg(fe, 0x17, 0x43);
+               stv0299_writereg(fe, 0x1a, 0x1d);
+               stv0299_writereg(fe, 0x1c, 0x12);
+               stv0299_writereg(fe, 0x2d, 0x05);
+       }
+       stv0299_writereg(fe, 0x0e, 0x23);
+       stv0299_writereg(fe, 0x0f, 0x94);
+       stv0299_writereg(fe, 0x10, 0x39);
+       stv0299_writereg(fe, 0x15, 0xc9);
+
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+
+       return 0;
+}
+
+static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+       u32 div;
+       u8 buf[4];
+       struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
+
+       if ((p->frequency < 950000) || (p->frequency > 2150000))
+               return -EINVAL;
+
+       div = (p->frequency + (500 - 1)) / 500; /* round correctly */
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
+       buf[3] = 0x20;
+
+       if (p->symbol_rate < 4000000)
+               buf[3] |= 1;
+
+       if (p->frequency < 1250000)
+               buf[3] |= 0;
+       else if (p->frequency < 1550000)
+               buf[3] |= 0x40;
+       else if (p->frequency < 2050000)
+               buf[3] |= 0x80;
+       else if (p->frequency < 2150000)
+               buf[3] |= 0xC0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct stv0299_config philips_su1278_tt_config = {
+
+       .demod_address = 0x68,
+       .inittab = philips_su1278_tt_inittab,
+       .mclk = 64000000UL,
+       .invert = 0,
+       .skip_reinit = 1,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 50,
+       .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
+};
+
+
+
+static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+       static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+       static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
+       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
+                       sizeof(td1316_init) };
+
+       // setup PLL configuration
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+       msleep(1);
+
+       // disable the mc44BC374c (do not check for errors)
+       tuner_msg.addr = 0x65;
+       tuner_msg.buf = disable_mc44BC374c;
+       tuner_msg.len = sizeof(disable_mc44BC374c);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
+       }
+
+       return 0;
+}
+
+static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+       u8 tuner_buf[4];
+       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
+       int tuner_frequency = 0;
+       u8 band, cp, filter;
+
+       // determine charge pump
+       tuner_frequency = p->frequency + 36130000;
+       if (tuner_frequency < 87000000)
+               return -EINVAL;
+       else if (tuner_frequency < 130000000)
+               cp = 3;
+       else if (tuner_frequency < 160000000)
+               cp = 5;
+       else if (tuner_frequency < 200000000)
+               cp = 6;
+       else if (tuner_frequency < 290000000)
+               cp = 3;
+       else if (tuner_frequency < 420000000)
+               cp = 5;
+       else if (tuner_frequency < 480000000)
+               cp = 6;
+       else if (tuner_frequency < 620000000)
+               cp = 3;
+       else if (tuner_frequency < 830000000)
+               cp = 5;
+       else if (tuner_frequency < 895000000)
+               cp = 7;
+       else
+               return -EINVAL;
+
+       // determine band
+       if (p->frequency < 49000000)
+               return -EINVAL;
+       else if (p->frequency < 159000000)
+               band = 1;
+       else if (p->frequency < 444000000)
+               band = 2;
+       else if (p->frequency < 861000000)
+               band = 4;
+       else
+               return -EINVAL;
+
+       // setup PLL filter and TDA9889
+       switch (p->bandwidth_hz) {
+       case 6000000:
+               tda1004x_writereg(fe, 0x0C, 0x14);
+               filter = 0;
+               break;
+
+       case 7000000:
+               tda1004x_writereg(fe, 0x0C, 0x80);
+               filter = 0;
+               break;
+
+       case 8000000:
+               tda1004x_writereg(fe, 0x0C, 0x14);
+               filter = 1;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // calculate divisor
+       // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
+       tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
+
+       // setup tuner buffer
+       tuner_buf[0] = tuner_frequency >> 8;
+       tuner_buf[1] = tuner_frequency & 0xff;
+       tuner_buf[2] = 0xca;
+       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+
+       msleep(1);
+       return 0;
+}
+
+static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
+                                            const struct firmware **fw, char *name)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+
+       return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
+}
+
+static struct tda1004x_config philips_tdm1316l_config = {
+
+       .demod_address = 0x8,
+       .invert = 0,
+       .invert_oclk = 0,
+       .xtal_freq = TDA10046_XTAL_4M,
+       .agc_config = TDA10046_AGC_DEFAULT,
+       .if_freq = TDA10046_FREQ_3617,
+       .request_firmware = philips_tdm1316l_request_firmware,
+};
+
+static struct tda1004x_config philips_tdm1316l_config_invert = {
+
+       .demod_address = 0x8,
+       .invert = 1,
+       .invert_oclk = 0,
+       .xtal_freq = TDA10046_XTAL_4M,
+       .agc_config = TDA10046_AGC_DEFAULT,
+       .if_freq = TDA10046_FREQ_3617,
+       .request_firmware = philips_tdm1316l_request_firmware,
+};
+
+static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+       u8 tuner_buf[5];
+       struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
+                                   .flags = 0,
+                                   .buf = tuner_buf,
+                                   .len = sizeof(tuner_buf) };
+       int tuner_frequency = 0;
+       u8 band, cp, filter;
+
+       // determine charge pump
+       tuner_frequency = p->frequency + 36125000;
+       if (tuner_frequency < 87000000)
+               return -EINVAL;
+       else if (tuner_frequency < 130000000) {
+               cp = 3;
+               band = 1;
+       } else if (tuner_frequency < 160000000) {
+               cp = 5;
+               band = 1;
+       } else if (tuner_frequency < 200000000) {
+               cp = 6;
+               band = 1;
+       } else if (tuner_frequency < 290000000) {
+               cp = 3;
+               band = 2;
+       } else if (tuner_frequency < 420000000) {
+               cp = 5;
+               band = 2;
+       } else if (tuner_frequency < 480000000) {
+               cp = 6;
+               band = 2;
+       } else if (tuner_frequency < 620000000) {
+               cp = 3;
+               band = 4;
+       } else if (tuner_frequency < 830000000) {
+               cp = 5;
+               band = 4;
+       } else if (tuner_frequency < 895000000) {
+               cp = 7;
+               band = 4;
+       } else
+               return -EINVAL;
+
+       // assume PLL filter should always be 8MHz for the moment.
+       filter = 1;
+
+       // calculate divisor
+       tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500;
+
+       // setup tuner buffer
+       tuner_buf[0] = tuner_frequency >> 8;
+       tuner_buf[1] = tuner_frequency & 0xff;
+       tuner_buf[2] = 0xc8;
+       tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+       tuner_buf[4] = 0x80;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+
+       msleep(50);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+               return -EIO;
+
+       msleep(1);
+
+       return 0;
+}
+
+static u8 dvbc_philips_tdm1316l_inittab[] = {
+       0x80, 0x01,
+       0x80, 0x00,
+       0x81, 0x01,
+       0x81, 0x00,
+       0x00, 0x09,
+       0x01, 0x69,
+       0x03, 0x00,
+       0x04, 0x00,
+       0x07, 0x00,
+       0x08, 0x00,
+       0x20, 0x00,
+       0x21, 0x40,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x24, 0x40,
+       0x25, 0x88,
+       0x30, 0xff,
+       0x31, 0x00,
+       0x32, 0xff,
+       0x33, 0x00,
+       0x34, 0x50,
+       0x35, 0x7f,
+       0x36, 0x00,
+       0x37, 0x20,
+       0x38, 0x00,
+       0x40, 0x1c,
+       0x41, 0xff,
+       0x42, 0x29,
+       0x43, 0x20,
+       0x44, 0xff,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x49, 0x04,
+       0x4a, 0x00,
+       0x4b, 0x7b,
+       0x52, 0x30,
+       0x55, 0xae,
+       0x56, 0x47,
+       0x57, 0xe1,
+       0x58, 0x3a,
+       0x5a, 0x1e,
+       0x5b, 0x34,
+       0x60, 0x00,
+       0x63, 0x00,
+       0x64, 0x00,
+       0x65, 0x00,
+       0x66, 0x00,
+       0x67, 0x00,
+       0x68, 0x00,
+       0x69, 0x00,
+       0x6a, 0x02,
+       0x6b, 0x00,
+       0x70, 0xff,
+       0x71, 0x00,
+       0x72, 0x00,
+       0x73, 0x00,
+       0x74, 0x0c,
+       0x80, 0x00,
+       0x81, 0x00,
+       0x82, 0x00,
+       0x83, 0x00,
+       0x84, 0x04,
+       0x85, 0x80,
+       0x86, 0x24,
+       0x87, 0x78,
+       0x88, 0x10,
+       0x89, 0x00,
+       0x90, 0x01,
+       0x91, 0x01,
+       0xa0, 0x04,
+       0xa1, 0x00,
+       0xa2, 0x00,
+       0xb0, 0x91,
+       0xb1, 0x0b,
+       0xc0, 0x53,
+       0xc1, 0x70,
+       0xc2, 0x12,
+       0xd0, 0x00,
+       0xd1, 0x00,
+       0xd2, 0x00,
+       0xd3, 0x00,
+       0xd4, 0x00,
+       0xd5, 0x00,
+       0xde, 0x00,
+       0xdf, 0x00,
+       0x61, 0x38,
+       0x62, 0x0a,
+       0x53, 0x13,
+       0x59, 0x08,
+       0xff, 0xff,
+};
+
+static struct stv0297_config dvbc_philips_tdm1316l_config = {
+       .demod_address = 0x1c,
+       .inittab = dvbc_philips_tdm1316l_inittab,
+       .invert = 0,
+       .stop_during_read = 1,
+};
+
+static struct tda10023_config tda10023_config = {
+       .demod_address = 0xc,
+       .invert = 0,
+       .xtal = 16000000,
+       .pll_m = 11,
+       .pll_p = 3,
+       .pll_n = 1,
+       .deltaf = 0xa511,
+};
+
+static struct tda827x_config tda827x_config = {
+       .config = 0,
+};
+
+/* TT S2-3200 DVB-S (STB0899) Inittab */
+static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
+
+       { STB0899_DEV_ID                , 0x81 },
+       { STB0899_DISCNTRL1             , 0x32 },
+       { STB0899_DISCNTRL2             , 0x80 },
+       { STB0899_DISRX_ST0             , 0x04 },
+       { STB0899_DISRX_ST1             , 0x00 },
+       { STB0899_DISPARITY             , 0x00 },
+       { STB0899_DISSTATUS             , 0x20 },
+       { STB0899_DISF22                , 0x8c },
+       { STB0899_DISF22RX              , 0x9a },
+       { STB0899_SYSREG                , 0x0b },
+       { STB0899_ACRPRESC              , 0x11 },
+       { STB0899_ACRDIV1               , 0x0a },
+       { STB0899_ACRDIV2               , 0x05 },
+       { STB0899_DACR1                 , 0x00 },
+       { STB0899_DACR2                 , 0x00 },
+       { STB0899_OUTCFG                , 0x00 },
+       { STB0899_MODECFG               , 0x00 },
+       { STB0899_IRQSTATUS_3           , 0x30 },
+       { STB0899_IRQSTATUS_2           , 0x00 },
+       { STB0899_IRQSTATUS_1           , 0x00 },
+       { STB0899_IRQSTATUS_0           , 0x00 },
+       { STB0899_IRQMSK_3              , 0xf3 },
+       { STB0899_IRQMSK_2              , 0xfc },
+       { STB0899_IRQMSK_1              , 0xff },
+       { STB0899_IRQMSK_0              , 0xff },
+       { STB0899_IRQCFG                , 0x00 },
+       { STB0899_I2CCFG                , 0x88 },
+       { STB0899_I2CRPT                , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
+       { STB0899_IOPVALUE5             , 0x00 },
+       { STB0899_IOPVALUE4             , 0x20 },
+       { STB0899_IOPVALUE3             , 0xc9 },
+       { STB0899_IOPVALUE2             , 0x90 },
+       { STB0899_IOPVALUE1             , 0x40 },
+       { STB0899_IOPVALUE0             , 0x00 },
+       { STB0899_GPIO00CFG             , 0x82 },
+       { STB0899_GPIO01CFG             , 0x82 },
+       { STB0899_GPIO02CFG             , 0x82 },
+       { STB0899_GPIO03CFG             , 0x82 },
+       { STB0899_GPIO04CFG             , 0x82 },
+       { STB0899_GPIO05CFG             , 0x82 },
+       { STB0899_GPIO06CFG             , 0x82 },
+       { STB0899_GPIO07CFG             , 0x82 },
+       { STB0899_GPIO08CFG             , 0x82 },
+       { STB0899_GPIO09CFG             , 0x82 },
+       { STB0899_GPIO10CFG             , 0x82 },
+       { STB0899_GPIO11CFG             , 0x82 },
+       { STB0899_GPIO12CFG             , 0x82 },
+       { STB0899_GPIO13CFG             , 0x82 },
+       { STB0899_GPIO14CFG             , 0x82 },
+       { STB0899_GPIO15CFG             , 0x82 },
+       { STB0899_GPIO16CFG             , 0x82 },
+       { STB0899_GPIO17CFG             , 0x82 },
+       { STB0899_GPIO18CFG             , 0x82 },
+       { STB0899_GPIO19CFG             , 0x82 },
+       { STB0899_GPIO20CFG             , 0x82 },
+       { STB0899_SDATCFG               , 0xb8 },
+       { STB0899_SCLTCFG               , 0xba },
+       { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
+       { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
+       { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
+       { STB0899_DIRCLKCFG             , 0x82 },
+       { STB0899_CLKOUT27CFG           , 0x7e },
+       { STB0899_STDBYCFG              , 0x82 },
+       { STB0899_CS0CFG                , 0x82 },
+       { STB0899_CS1CFG                , 0x82 },
+       { STB0899_DISEQCOCFG            , 0x20 },
+       { STB0899_GPIO32CFG             , 0x82 },
+       { STB0899_GPIO33CFG             , 0x82 },
+       { STB0899_GPIO34CFG             , 0x82 },
+       { STB0899_GPIO35CFG             , 0x82 },
+       { STB0899_GPIO36CFG             , 0x82 },
+       { STB0899_GPIO37CFG             , 0x82 },
+       { STB0899_GPIO38CFG             , 0x82 },
+       { STB0899_GPIO39CFG             , 0x82 },
+       { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+       { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+       { STB0899_FILTCTRL              , 0x00 },
+       { STB0899_SYSCTRL               , 0x00 },
+       { STB0899_STOPCLK1              , 0x20 },
+       { STB0899_STOPCLK2              , 0x00 },
+       { STB0899_INTBUFSTATUS          , 0x00 },
+       { STB0899_INTBUFCTRL            , 0x0a },
+       { 0xffff                        , 0xff },
+};
+
+static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
+       { STB0899_DEMOD                 , 0x00 },
+       { STB0899_RCOMPC                , 0xc9 },
+       { STB0899_AGC1CN                , 0x41 },
+       { STB0899_AGC1REF               , 0x10 },
+       { STB0899_RTC                   , 0x7a },
+       { STB0899_TMGCFG                , 0x4e },
+       { STB0899_AGC2REF               , 0x34 },
+       { STB0899_TLSR                  , 0x84 },
+       { STB0899_CFD                   , 0xc7 },
+       { STB0899_ACLC                  , 0x87 },
+       { STB0899_BCLC                  , 0x94 },
+       { STB0899_EQON                  , 0x41 },
+       { STB0899_LDT                   , 0xdd },
+       { STB0899_LDT2                  , 0xc9 },
+       { STB0899_EQUALREF              , 0xb4 },
+       { STB0899_TMGRAMP               , 0x10 },
+       { STB0899_TMGTHD                , 0x30 },
+       { STB0899_IDCCOMP               , 0xfb },
+       { STB0899_QDCCOMP               , 0x03 },
+       { STB0899_POWERI                , 0x3b },
+       { STB0899_POWERQ                , 0x3d },
+       { STB0899_RCOMP                 , 0x81 },
+       { STB0899_AGCIQIN               , 0x80 },
+       { STB0899_AGC2I1                , 0x04 },
+       { STB0899_AGC2I2                , 0xf5 },
+       { STB0899_TLIR                  , 0x25 },
+       { STB0899_RTF                   , 0x80 },
+       { STB0899_DSTATUS               , 0x00 },
+       { STB0899_LDI                   , 0xca },
+       { STB0899_CFRM                  , 0xf1 },
+       { STB0899_CFRL                  , 0xf3 },
+       { STB0899_NIRM                  , 0x2a },
+       { STB0899_NIRL                  , 0x05 },
+       { STB0899_ISYMB                 , 0x17 },
+       { STB0899_QSYMB                 , 0xfa },
+       { STB0899_SFRH                  , 0x2f },
+       { STB0899_SFRM                  , 0x68 },
+       { STB0899_SFRL                  , 0x40 },
+       { STB0899_SFRUPH                , 0x2f },
+       { STB0899_SFRUPM                , 0x68 },
+       { STB0899_SFRUPL                , 0x40 },
+       { STB0899_EQUAI1                , 0xfd },
+       { STB0899_EQUAQ1                , 0x04 },
+       { STB0899_EQUAI2                , 0x0f },
+       { STB0899_EQUAQ2                , 0xff },
+       { STB0899_EQUAI3                , 0xdf },
+       { STB0899_EQUAQ3                , 0xfa },
+       { STB0899_EQUAI4                , 0x37 },
+       { STB0899_EQUAQ4                , 0x0d },
+       { STB0899_EQUAI5                , 0xbd },
+       { STB0899_EQUAQ5                , 0xf7 },
+       { STB0899_DSTATUS2              , 0x00 },
+       { STB0899_VSTATUS               , 0x00 },
+       { STB0899_VERROR                , 0xff },
+       { STB0899_IQSWAP                , 0x2a },
+       { STB0899_ECNT1M                , 0x00 },
+       { STB0899_ECNT1L                , 0x00 },
+       { STB0899_ECNT2M                , 0x00 },
+       { STB0899_ECNT2L                , 0x00 },
+       { STB0899_ECNT3M                , 0x00 },
+       { STB0899_ECNT3L                , 0x00 },
+       { STB0899_FECAUTO1              , 0x06 },
+       { STB0899_FECM                  , 0x01 },
+       { STB0899_VTH12                 , 0xf0 },
+       { STB0899_VTH23                 , 0xa0 },
+       { STB0899_VTH34                 , 0x78 },
+       { STB0899_VTH56                 , 0x4e },
+       { STB0899_VTH67                 , 0x48 },
+       { STB0899_VTH78                 , 0x38 },
+       { STB0899_PRVIT                 , 0xff },
+       { STB0899_VITSYNC               , 0x19 },
+       { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+       { STB0899_TSULC                 , 0x42 },
+       { STB0899_RSLLC                 , 0x40 },
+       { STB0899_TSLPL                 , 0x12 },
+       { STB0899_TSCFGH                , 0x0c },
+       { STB0899_TSCFGM                , 0x00 },
+       { STB0899_TSCFGL                , 0x0c },
+       { STB0899_TSOUT                 , 0x4d }, /* 0x0d for CAM */
+       { STB0899_RSSYNCDEL             , 0x00 },
+       { STB0899_TSINHDELH             , 0x02 },
+       { STB0899_TSINHDELM             , 0x00 },
+       { STB0899_TSINHDELL             , 0x00 },
+       { STB0899_TSLLSTKM              , 0x00 },
+       { STB0899_TSLLSTKL              , 0x00 },
+       { STB0899_TSULSTKM              , 0x00 },
+       { STB0899_TSULSTKL              , 0xab },
+       { STB0899_PCKLENUL              , 0x00 },
+       { STB0899_PCKLENLL              , 0xcc },
+       { STB0899_RSPCKLEN              , 0xcc },
+       { STB0899_TSSTATUS              , 0x80 },
+       { STB0899_ERRCTRL1              , 0xb6 },
+       { STB0899_ERRCTRL2              , 0x96 },
+       { STB0899_ERRCTRL3              , 0x89 },
+       { STB0899_DMONMSK1              , 0x27 },
+       { STB0899_DMONMSK0              , 0x03 },
+       { STB0899_DEMAPVIT              , 0x5c },
+       { STB0899_PLPARM                , 0x1f },
+       { STB0899_PDELCTRL              , 0x48 },
+       { STB0899_PDELCTRL2             , 0x00 },
+       { STB0899_BBHCTRL1              , 0x00 },
+       { STB0899_BBHCTRL2              , 0x00 },
+       { STB0899_HYSTTHRESH            , 0x77 },
+       { STB0899_MATCSTM               , 0x00 },
+       { STB0899_MATCSTL               , 0x00 },
+       { STB0899_UPLCSTM               , 0x00 },
+       { STB0899_UPLCSTL               , 0x00 },
+       { STB0899_DFLCSTM               , 0x00 },
+       { STB0899_DFLCSTL               , 0x00 },
+       { STB0899_SYNCCST               , 0x00 },
+       { STB0899_SYNCDCSTM             , 0x00 },
+       { STB0899_SYNCDCSTL             , 0x00 },
+       { STB0899_ISI_ENTRY             , 0x00 },
+       { STB0899_ISI_BIT_EN            , 0x00 },
+       { STB0899_MATSTRM               , 0x00 },
+       { STB0899_MATSTRL               , 0x00 },
+       { STB0899_UPLSTRM               , 0x00 },
+       { STB0899_UPLSTRL               , 0x00 },
+       { STB0899_DFLSTRM               , 0x00 },
+       { STB0899_DFLSTRL               , 0x00 },
+       { STB0899_SYNCSTR               , 0x00 },
+       { STB0899_SYNCDSTRM             , 0x00 },
+       { STB0899_SYNCDSTRL             , 0x00 },
+       { STB0899_CFGPDELSTATUS1        , 0x10 },
+       { STB0899_CFGPDELSTATUS2        , 0x00 },
+       { STB0899_BBFERRORM             , 0x00 },
+       { STB0899_BBFERRORL             , 0x00 },
+       { STB0899_UPKTERRORM            , 0x00 },
+       { STB0899_UPKTERRORL            , 0x00 },
+       { 0xffff                        , 0xff },
+};
+
+static struct stb0899_config tt3200_config = {
+       .init_dev               = tt3200_stb0899_s1_init_1,
+       .init_s2_demod          = stb0899_s2_init_2,
+       .init_s1_demod          = tt3200_stb0899_s1_init_3,
+       .init_s2_fec            = stb0899_s2_init_4,
+       .init_tst               = stb0899_s1_init_5,
+
+       .postproc               = NULL,
+
+       .demod_address          = 0x68,
+
+       .xtal_freq              = 27000000,
+       .inversion              = IQ_SWAP_ON, /* 1 */
+
+       .lo_clk                 = 76500000,
+       .hi_clk                 = 99000000,
+
+       .esno_ave               = STB0899_DVBS2_ESNO_AVE,
+       .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
+       .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
+       .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
+       .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
+       .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+       .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+       .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
+       .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+       .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
+       .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+       .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
+       .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
+
+       .tuner_get_frequency    = stb6100_get_frequency,
+       .tuner_set_frequency    = stb6100_set_frequency,
+       .tuner_set_bandwidth    = stb6100_set_bandwidth,
+       .tuner_get_bandwidth    = stb6100_get_bandwidth,
+       .tuner_set_rfsiggain    = NULL
+};
+
+static struct stb6100_config tt3200_stb6100_config = {
+       .tuner_address  = 0x60,
+       .refclock       = 27000000,
+};
+
+static void frontend_init(struct budget_ci *budget_ci)
+{
+       switch (budget_ci->budget.dev->pci->subsystem_device) {
+       case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
+               budget_ci->budget.dvb_frontend =
+                       dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
+                       budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
+                       break;
+               }
+               break;
+
+       case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
+               budget_ci->budget.dvb_frontend =
+                       dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1010:            // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
+               budget_ci->tuner_pll_address = 0x61;
+               budget_ci->budget.dvb_frontend =
+                       dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+               budget_ci->tuner_pll_address = 0x63;
+               budget_ci->budget.dvb_frontend =
+                       dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1012:            // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
+               budget_ci->tuner_pll_address = 0x60;
+               budget_ci->budget.dvb_frontend =
+                       dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1017:            // TT S-1500 PCI
+               budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
+                       budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
+
+                       budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
+                       if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
+                               printk("%s: No LNBP21 found!\n", __func__);
+                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                               budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+               break;
+
+       case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
+               budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
+               if (budget_ci->budget.dvb_frontend) {
+                       if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
+                               printk(KERN_ERR "%s: No tda827x found!\n", __func__);
+                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                               budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+               break;
+
+       case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
+               budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
+                               if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
+                                       printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
+                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                                       budget_ci->budget.dvb_frontend = NULL;
+                               }
+                       } else {
+                               printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
+                               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                               budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+               break;
+
+       case 0x1019:            // TT S2-3200 PCI
+               /*
+                * NOTE! on some STB0899 versions, the internal PLL takes a longer time
+                * to settle, aka LOCK. On the older revisions of the chip, we don't see
+                * this, as a result on the newer chips the entire clock tree, will not
+                * be stable after a freshly POWER 'ed up situation.
+                * In this case, we should RESET the STB0899 (Active LOW) and wait for
+                * PLL stabilization.
+                *
+                * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
+                * connected to the SAA7146 GPIO, GPIO2, Pin 142
+                */
+               /* Reset Demodulator */
+               saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
+               /* Wait for everything to die */
+               msleep(50);
+               /* Pull it up out of Reset state */
+               saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
+               /* Wait for PLL to stabilize */
+               msleep(250);
+               /*
+                * PLL state should be stable now. Ideally, we should check
+                * for PLL LOCK status. But well, never mind!
+                */
+               budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
+                               if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
+                                       printk("%s: No LNBP21 found!\n", __func__);
+                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                                       budget_ci->budget.dvb_frontend = NULL;
+                               }
+                       } else {
+                                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                                       budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+               break;
+
+       }
+
+       if (budget_ci->budget.dvb_frontend == NULL) {
+               printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      budget_ci->budget.dev->pci->vendor,
+                      budget_ci->budget.dev->pci->device,
+                      budget_ci->budget.dev->pci->subsystem_vendor,
+                      budget_ci->budget.dev->pci->subsystem_device);
+       } else {
+               if (dvb_register_frontend
+                   (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
+                       printk("budget-ci: Frontend registration failed!\n");
+                       dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+                       budget_ci->budget.dvb_frontend = NULL;
+               }
+       }
+}
+
+static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+       struct budget_ci *budget_ci;
+       int err;
+
+       budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
+       if (!budget_ci) {
+               err = -ENOMEM;
+               goto out1;
+       }
+
+       dprintk(2, "budget_ci: %p\n", budget_ci);
+
+       dev->ext_priv = budget_ci;
+
+       err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
+                               adapter_nr);
+       if (err)
+               goto out2;
+
+       err = msp430_ir_init(budget_ci);
+       if (err)
+               goto out3;
+
+       ciintf_init(budget_ci);
+
+       budget_ci->budget.dvb_adapter.priv = budget_ci;
+       frontend_init(budget_ci);
+
+       ttpci_budget_init_hooks(&budget_ci->budget);
+
+       return 0;
+
+out3:
+       ttpci_budget_deinit(&budget_ci->budget);
+out2:
+       kfree(budget_ci);
+out1:
+       return err;
+}
+
+static int budget_ci_detach(struct saa7146_dev *dev)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       int err;
+
+       if (budget_ci->budget.ci_present)
+               ciintf_deinit(budget_ci);
+       msp430_ir_deinit(budget_ci);
+       if (budget_ci->budget.dvb_frontend) {
+               dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
+               dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+       }
+       err = ttpci_budget_deinit(&budget_ci->budget);
+
+       // disable frontend and CI interface
+       saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
+
+       kfree(budget_ci);
+
+       return err;
+}
+
+static struct saa7146_extension budget_extension;
+
+MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
+MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T         PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
+
+static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
+       MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
+       MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
+       MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
+       MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
+       MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
+       MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
+       MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
+       MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
+       {
+        .vendor = 0,
+        }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+static struct saa7146_extension budget_extension = {
+       .name = "budget_ci dvb",
+       .flags = SAA7146_USE_I2C_IRQ,
+
+       .module = THIS_MODULE,
+       .pci_tbl = &pci_tbl[0],
+       .attach = budget_ci_attach,
+       .detach = budget_ci_detach,
+
+       .irq_mask = MASK_03 | MASK_06 | MASK_10,
+       .irq_func = budget_ci_irq,
+};
+
+static int __init budget_ci_init(void)
+{
+       return saa7146_register_extension(&budget_extension);
+}
+
+static void __exit budget_ci_exit(void)
+{
+       saa7146_unregister_extension(&budget_extension);
+}
+
+module_init(budget_ci_init);
+module_exit(budget_ci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
+                  "budget PCI DVB cards w/ CI-module produced by "
+                  "Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c
new file mode 100644 (file)
index 0000000..37d02fe
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * budget-core.c: driver for the SAA7146 based Budget DVB cards
+ *
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                      & Marcus Metzler for convergence integrated media GmbH
+ *
+ * 26feb2004 Support for FS Activy Card (Grundig tuner) by
+ *          Michael Dreher <michael@5dot1.de>,
+ *          Oliver Endriss <o.endriss@gmx.de>,
+ *          Andreas 'randy' Weinberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+
+#include "budget.h"
+#include "ttpci-eeprom.h"
+
+#define TS_WIDTH               (2 * TS_SIZE)
+#define TS_WIDTH_ACTIVY                TS_SIZE
+#define TS_WIDTH_DVBC          TS_SIZE
+#define TS_HEIGHT_MASK         0xf00
+#define TS_HEIGHT_MASK_ACTIVY  0xc00
+#define TS_HEIGHT_MASK_DVBC    0xe00
+#define TS_MIN_BUFSIZE_K       188
+#define TS_MAX_BUFSIZE_K       1410
+#define TS_MAX_BUFSIZE_K_ACTIVY        564
+#define TS_MAX_BUFSIZE_K_DVBC  1316
+#define BUFFER_WARNING_WAIT    (30*HZ)
+
+int budget_debug;
+static int dma_buffer_size = TS_MIN_BUFSIZE_K;
+module_param_named(debug, budget_debug, int, 0644);
+module_param_named(bufsize, dma_buffer_size, int, 0444);
+MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
+MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)");
+
+/****************************************************************************
+ * TT budget / WinTV Nova
+ ****************************************************************************/
+
+static int stop_ts_capture(struct budget *budget)
+{
+       dprintk(2, "budget: %p\n", budget);
+
+       saa7146_write(budget->dev, MC1, MASK_20);       // DMA3 off
+       SAA7146_IER_DISABLE(budget->dev, MASK_10);
+       return 0;
+}
+
+static int start_ts_capture(struct budget *budget)
+{
+       struct saa7146_dev *dev = budget->dev;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       if (!budget->feeding || !budget->fe_synced)
+               return 0;
+
+       saa7146_write(dev, MC1, MASK_20);       // DMA3 off
+
+       memset(budget->grabbing, 0x00, budget->buffer_size);
+
+       saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
+
+       budget->ttbp = 0;
+
+       /*
+        *  Signal path on the Activy:
+        *
+        *  tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory
+        *
+        *  Since the tuner feeds 204 bytes packets into the SAA7146,
+        *  DMA3 is configured to strip the trailing 16 FEC bytes:
+        *      Pitch: 188, NumBytes3: 188, NumLines3: 1024
+        */
+
+       switch(budget->card->type) {
+       case BUDGET_FS_ACTIVY:
+               saa7146_write(dev, DD1_INIT, 0x04000000);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25));
+               saa7146_write(dev, BRS_CTRL, 0x00000000);
+               break;
+       case BUDGET_PATCH:
+               saa7146_write(dev, DD1_INIT, 0x00000200);
+               saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+               saa7146_write(dev, BRS_CTRL, 0x60000000);
+               break;
+       case BUDGET_CIN1200C_MK3:
+       case BUDGET_KNC1C_MK3:
+       case BUDGET_KNC1C_TDA10024:
+       case BUDGET_KNC1CP_MK3:
+               if (budget->video_port == BUDGET_VIDEO_PORTA) {
+                       saa7146_write(dev, DD1_INIT, 0x06000200);
+                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+                       saa7146_write(dev, BRS_CTRL, 0x00000000);
+               } else {
+                       saa7146_write(dev, DD1_INIT, 0x00000600);
+                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+                       saa7146_write(dev, BRS_CTRL, 0x60000000);
+               }
+               break;
+       default:
+               if (budget->video_port == BUDGET_VIDEO_PORTA) {
+                       saa7146_write(dev, DD1_INIT, 0x06000200);
+                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+                       saa7146_write(dev, BRS_CTRL, 0x00000000);
+               } else {
+                       saa7146_write(dev, DD1_INIT, 0x02000600);
+                       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+                       saa7146_write(dev, BRS_CTRL, 0x60000000);
+               }
+       }
+
+       saa7146_write(dev, MC2, (MASK_08 | MASK_24));
+       mdelay(10);
+
+       saa7146_write(dev, BASE_ODD3, 0);
+       if (budget->buffer_size > budget->buffer_height * budget->buffer_width) {
+               // using odd/even buffers
+               saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width);
+       } else {
+               // using a single buffer
+               saa7146_write(dev, BASE_EVEN3, 0);
+       }
+       saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
+       saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
+
+       saa7146_write(dev, PITCH3, budget->buffer_width);
+       saa7146_write(dev, NUM_LINE_BYTE3,
+                       (budget->buffer_height << 16) | budget->buffer_width);
+
+       saa7146_write(dev, MC2, (MASK_04 | MASK_20));
+
+       SAA7146_ISR_CLEAR(budget->dev, MASK_10);        /* VPE */
+       SAA7146_IER_ENABLE(budget->dev, MASK_10);       /* VPE */
+       saa7146_write(dev, MC1, (MASK_04 | MASK_20));   /* DMA3 on */
+
+       return 0;
+}
+
+static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct budget *budget = (struct budget *) fe->dvb->priv;
+       int synced;
+       int ret;
+
+       if (budget->read_fe_status)
+               ret = budget->read_fe_status(fe, status);
+       else
+               ret = -EINVAL;
+
+       if (!ret) {
+               synced = (*status & FE_HAS_LOCK);
+               if (synced != budget->fe_synced) {
+                       budget->fe_synced = synced;
+                       spin_lock(&budget->feedlock);
+                       if (synced)
+                               start_ts_capture(budget);
+                       else
+                               stop_ts_capture(budget);
+                       spin_unlock(&budget->feedlock);
+               }
+       }
+       return ret;
+}
+
+static void vpeirq(unsigned long data)
+{
+       struct budget *budget = (struct budget *) data;
+       u8 *mem = (u8 *) (budget->grabbing);
+       u32 olddma = budget->ttbp;
+       u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
+       u32 count;
+
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
+       /* nearest lower position divisible by 188 */
+       newdma -= newdma % 188;
+
+       if (newdma >= budget->buffer_size)
+               return;
+
+       budget->ttbp = newdma;
+
+       if (budget->feeding == 0 || newdma == olddma)
+               return;
+
+       if (newdma > olddma) {  /* no wraparound, dump olddma..newdma */
+               count = newdma - olddma;
+               dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
+       } else {                /* wraparound, dump olddma..buflen and 0..newdma */
+               count = budget->buffer_size - olddma;
+               dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
+               count += newdma;
+               dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
+       }
+
+       if (count > budget->buffer_warning_threshold)
+               budget->buffer_warnings++;
+
+       if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) {
+               printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n",
+                       budget->dev->name, __func__, budget->buffer_warnings, count);
+               budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT;
+               budget->buffer_warnings = 0;
+       }
+}
+
+
+int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
+                         int uselocks, int nobusyloop)
+{
+       struct saa7146_dev *saa = budget->dev;
+       int result = 0;
+       unsigned long flags = 0;
+
+       if (count > 4 || count <= 0)
+               return 0;
+
+       if (uselocks)
+               spin_lock_irqsave(&budget->debilock, flags);
+
+       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
+               if (uselocks)
+                       spin_unlock_irqrestore(&budget->debilock, flags);
+               return result;
+       }
+
+       saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
+       saa7146_write(saa, DEBI_CONFIG, config);
+       saa7146_write(saa, DEBI_PAGE, 0);
+       saa7146_write(saa, MC2, (2 << 16) | 2);
+
+       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
+               if (uselocks)
+                       spin_unlock_irqrestore(&budget->debilock, flags);
+               return result;
+       }
+
+       result = saa7146_read(saa, DEBI_AD);
+       result &= (0xffffffffUL >> ((4 - count) * 8));
+
+       if (uselocks)
+               spin_unlock_irqrestore(&budget->debilock, flags);
+
+       return result;
+}
+
+int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr,
+                          int count, u32 value, int uselocks, int nobusyloop)
+{
+       struct saa7146_dev *saa = budget->dev;
+       unsigned long flags = 0;
+       int result;
+
+       if (count > 4 || count <= 0)
+               return 0;
+
+       if (uselocks)
+               spin_lock_irqsave(&budget->debilock, flags);
+
+       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
+               if (uselocks)
+                       spin_unlock_irqrestore(&budget->debilock, flags);
+               return result;
+       }
+
+       saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff));
+       saa7146_write(saa, DEBI_CONFIG, config);
+       saa7146_write(saa, DEBI_PAGE, 0);
+       saa7146_write(saa, DEBI_AD, value);
+       saa7146_write(saa, MC2, (2 << 16) | 2);
+
+       if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
+               if (uselocks)
+                       spin_unlock_irqrestore(&budget->debilock, flags);
+               return result;
+       }
+
+       if (uselocks)
+               spin_unlock_irqrestore(&budget->debilock, flags);
+       return 0;
+}
+
+
+/****************************************************************************
+ * DVB API SECTION
+ ****************************************************************************/
+
+static int budget_start_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct budget *budget = (struct budget *) demux->priv;
+       int status = 0;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       if (!demux->dmx.frontend)
+               return -EINVAL;
+
+       spin_lock(&budget->feedlock);
+       feed->pusi_seen = 0; /* have a clean section start */
+       if (budget->feeding++ == 0)
+               status = start_ts_capture(budget);
+       spin_unlock(&budget->feedlock);
+       return status;
+}
+
+static int budget_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct dvb_demux *demux = feed->demux;
+       struct budget *budget = (struct budget *) demux->priv;
+       int status = 0;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       spin_lock(&budget->feedlock);
+       if (--budget->feeding == 0)
+               status = stop_ts_capture(budget);
+       spin_unlock(&budget->feedlock);
+       return status;
+}
+
+static int budget_register(struct budget *budget)
+{
+       struct dvb_demux *dvbdemux = &budget->demux;
+       int ret;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       dvbdemux->priv = (void *) budget;
+
+       dvbdemux->filternum = 256;
+       dvbdemux->feednum = 256;
+       dvbdemux->start_feed = budget_start_feed;
+       dvbdemux->stop_feed = budget_stop_feed;
+       dvbdemux->write_to_decoder = NULL;
+
+       dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+                                     DMX_MEMORY_BASED_FILTERING);
+
+       dvb_dmx_init(&budget->demux);
+
+       budget->dmxdev.filternum = 256;
+       budget->dmxdev.demux = &dvbdemux->dmx;
+       budget->dmxdev.capabilities = 0;
+
+       dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter);
+
+       budget->hw_frontend.source = DMX_FRONTEND_0;
+
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+
+       if (ret < 0)
+               return ret;
+
+       budget->mem_frontend.source = DMX_MEMORY_FE;
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
+       if (ret < 0)
+               return ret;
+
+       ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+       if (ret < 0)
+               return ret;
+
+       dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
+
+       return 0;
+}
+
+static void budget_unregister(struct budget *budget)
+{
+       struct dvb_demux *dvbdemux = &budget->demux;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       dvb_net_release(&budget->dvb_net);
+
+       dvbdemux->dmx.close(&dvbdemux->dmx);
+       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+       dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
+
+       dvb_dmxdev_release(&budget->dmxdev);
+       dvb_dmx_release(&budget->demux);
+}
+
+int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
+                     struct saa7146_pci_extension_data *info,
+                     struct module *owner, short *adapter_nums)
+{
+       int ret = 0;
+       struct budget_info *bi = info->ext_priv;
+       int max_bufsize;
+       int height_mask;
+
+       memset(budget, 0, sizeof(struct budget));
+
+       dprintk(2, "dev: %p, budget: %p\n", dev, budget);
+
+       budget->card = bi;
+       budget->dev = (struct saa7146_dev *) dev;
+
+       switch(budget->card->type) {
+       case BUDGET_FS_ACTIVY:
+               budget->buffer_width = TS_WIDTH_ACTIVY;
+               max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
+               height_mask = TS_HEIGHT_MASK_ACTIVY;
+               break;
+
+       case BUDGET_KNC1C:
+       case BUDGET_KNC1CP:
+       case BUDGET_CIN1200C:
+       case BUDGET_KNC1C_MK3:
+       case BUDGET_KNC1C_TDA10024:
+       case BUDGET_KNC1CP_MK3:
+       case BUDGET_CIN1200C_MK3:
+               budget->buffer_width = TS_WIDTH_DVBC;
+               max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
+               height_mask = TS_HEIGHT_MASK_DVBC;
+               break;
+
+       default:
+               budget->buffer_width = TS_WIDTH;
+               max_bufsize = TS_MAX_BUFSIZE_K;
+               height_mask = TS_HEIGHT_MASK;
+       }
+
+       if (dma_buffer_size < TS_MIN_BUFSIZE_K)
+               dma_buffer_size = TS_MIN_BUFSIZE_K;
+       else if (dma_buffer_size > max_bufsize)
+               dma_buffer_size = max_bufsize;
+
+       budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
+       if (budget->buffer_height > 0xfff) {
+               budget->buffer_height /= 2;
+               budget->buffer_height &= height_mask;
+               budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
+       } else {
+               budget->buffer_height &= height_mask;
+               budget->buffer_size = budget->buffer_height * budget->buffer_width;
+       }
+       budget->buffer_warning_threshold = budget->buffer_size * 80/100;
+       budget->buffer_warnings = 0;
+       budget->buffer_warning_time = jiffies;
+
+       dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
+               budget->dev->name,
+               budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
+               budget->buffer_width, budget->buffer_height);
+       printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
+
+       ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name,
+                                  owner, &budget->dev->pci->dev, adapter_nums);
+       if (ret < 0)
+               return ret;
+
+       /* set dd1 stream a & b */
+       saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+       saa7146_write(dev, MC2, (MASK_09 | MASK_25));
+       saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+       saa7146_write(dev, DD1_INIT, 0x02000000);
+       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+       if (bi->type != BUDGET_FS_ACTIVY)
+               budget->video_port = BUDGET_VIDEO_PORTB;
+       else
+               budget->video_port = BUDGET_VIDEO_PORTA;
+       spin_lock_init(&budget->feedlock);
+       spin_lock_init(&budget->debilock);
+
+       /* the Siemens DVB needs this if you want to have the i2c chips
+          get recognized before the main driver is loaded */
+       if (bi->type != BUDGET_FS_ACTIVY)
+               saa7146_write(dev, GPIO_CTRL, 0x500000);        /* GPIO 3 = 1 */
+
+       strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
+
+       saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
+       strcpy(budget->i2c_adap.name, budget->card->name);
+
+       if (i2c_add_adapter(&budget->i2c_adap) < 0) {
+               ret = -ENOMEM;
+               goto err_dvb_unregister;
+       }
+
+       ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
+
+       budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+       if (NULL == budget->grabbing) {
+               ret = -ENOMEM;
+               goto err_del_i2c;
+       }
+
+       saa7146_write(dev, PCI_BT_V1, 0x001c0000);
+       /* upload all */
+       saa7146_write(dev, GPIO_CTRL, 0x000000);
+
+       tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
+
+       /* frontend power on */
+       if (bi->type != BUDGET_FS_ACTIVY)
+               saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
+
+       if ((ret = budget_register(budget)) == 0)
+               return 0; /* Everything OK */
+
+       /* An error occurred, cleanup resources */
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+
+err_del_i2c:
+       i2c_del_adapter(&budget->i2c_adap);
+
+err_dvb_unregister:
+       dvb_unregister_adapter(&budget->dvb_adapter);
+
+       return ret;
+}
+
+void ttpci_budget_init_hooks(struct budget *budget)
+{
+       if (budget->dvb_frontend && !budget->read_fe_status) {
+               budget->read_fe_status = budget->dvb_frontend->ops.read_status;
+               budget->dvb_frontend->ops.read_status = budget_read_fe_status;
+       }
+}
+
+int ttpci_budget_deinit(struct budget *budget)
+{
+       struct saa7146_dev *dev = budget->dev;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       budget_unregister(budget);
+
+       tasklet_kill(&budget->vpe_tasklet);
+
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+
+       i2c_del_adapter(&budget->i2c_adap);
+
+       dvb_unregister_adapter(&budget->dvb_adapter);
+
+       return 0;
+}
+
+void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr)
+{
+       struct budget *budget = (struct budget *) dev->ext_priv;
+
+       dprintk(8, "dev: %p, budget: %p\n", dev, budget);
+
+       if (*isr & MASK_10)
+               tasklet_schedule(&budget->vpe_tasklet);
+}
+
+void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
+{
+       struct budget *budget = (struct budget *) dev->ext_priv;
+
+       spin_lock(&budget->feedlock);
+       budget->video_port = video_port;
+       if (budget->feeding) {
+               stop_ts_capture(budget);
+               start_ts_capture(budget);
+       }
+       spin_unlock(&budget->feedlock);
+}
+
+EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
+EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
+EXPORT_SYMBOL_GPL(ttpci_budget_init);
+EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks);
+EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
+EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
+EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
+EXPORT_SYMBOL_GPL(budget_debug);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c
new file mode 100644 (file)
index 0000000..2cb35c2
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * budget-patch.c: driver for Budget Patch,
+ * hardware modification of DVB-S cards enabling full TS
+ *
+ * Written by Emard <emard@softhome.net>
+ *
+ * Original idea by Roberto Deza <rdeza@unav.es>
+ *
+ * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
+ * and Metzlerbros
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#include "av7110.h"
+#include "av7110_hw.h"
+#include "budget.h"
+#include "stv0299.h"
+#include "ves1x93.h"
+#include "tda8083.h"
+
+#include "bsru6.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define budget_patch budget
+
+static struct saa7146_extension budget_extension;
+
+MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
+//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
+
+static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
+//        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
+       {
+               .vendor    = 0,
+       }
+};
+
+/* those lines are for budget-patch to be tried
+** on a true budget card and observe the
+** behaviour of VSYNC generated by rps1.
+** this code was shamelessly copy/pasted from budget.c
+*/
+static void gpio_Set22K (struct budget *budget, int state)
+{
+       struct saa7146_dev *dev=budget->dev;
+       dprintk(2, "budget: %p\n", budget);
+       saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+   Ralph Metzler <rjkm@metzlerbros.de> */
+
+static void DiseqcSendBit (struct budget *budget, int data)
+{
+       struct saa7146_dev *dev=budget->dev;
+       dprintk(2, "budget: %p\n", budget);
+
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+       udelay(data ? 500 : 1000);
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       udelay(data ? 1000 : 500);
+}
+
+static void DiseqcSendByte (struct budget *budget, int data)
+{
+       int i, par=1, d;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       for (i=7; i>=0; i--) {
+               d = (data>>i)&1;
+               par ^= d;
+               DiseqcSendBit(budget, d);
+       }
+
+       DiseqcSendBit(budget, par);
+}
+
+static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
+{
+       struct saa7146_dev *dev=budget->dev;
+       int i;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       mdelay(16);
+
+       for (i=0; i<len; i++)
+               DiseqcSendByte(budget, msg[i]);
+
+       mdelay(16);
+
+       if (burst!=-1) {
+               if (burst)
+                       DiseqcSendByte(budget, 0xff);
+               else {
+                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+                       mdelay(12);
+                       udelay(500);
+                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+               }
+               msleep(20);
+       }
+
+       return 0;
+}
+
+/* shamelessly copy/pasted from budget.c
+*/
+static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               gpio_Set22K (budget, 1);
+               break;
+
+       case SEC_TONE_OFF:
+               gpio_Set22K (budget, 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+
+       return 0;
+}
+
+static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       SendDiSEqCMsg (budget, 0, NULL, minicmd);
+
+       return 0;
+}
+
+static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
+{
+       int i;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       for (i = 2; i < length; i++)
+       {
+                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
+                 msleep(5);
+       }
+       if (length)
+                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
+       else
+                 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
+       msleep(5);
+       ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
+       msleep(5);
+       return 0;
+}
+
+static void av7110_set22k(struct budget_patch *budget, int state)
+{
+       u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
+
+       dprintk(2, "budget: %p\n", budget);
+       budget_av7110_send_fw_cmd(budget, buf, 2);
+}
+
+static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
+{
+       int i;
+       u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
+               16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+       dprintk(2, "budget: %p\n", budget);
+
+       if (len>10)
+               len=10;
+
+       buf[1] = len+2;
+       buf[2] = len;
+
+       if (burst != -1)
+               buf[3]=burst ? 0x01 : 0x00;
+       else
+               buf[3]=0xffff;
+
+       for (i=0; i<len; i++)
+               buf[i+4]=msg[i];
+
+       budget_av7110_send_fw_cmd(budget, buf, 18);
+       return 0;
+}
+
+static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               av7110_set22k (budget, 1);
+               break;
+
+       case SEC_TONE_OFF:
+               av7110_set22k (budget, 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
+
+       av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
+
+       return 0;
+}
+
+static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
+
+       av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
+
+       return 0;
+}
+
+static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
+       u8 pwr = 0;
+       u8 buf[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       u32 div = (p->frequency + 479500) / 125;
+
+       if (p->frequency > 2000000)
+               pwr = 3;
+       else if (p->frequency > 1800000)
+               pwr = 2;
+       else if (p->frequency > 1600000)
+               pwr = 1;
+       else if (p->frequency > 1200000)
+               pwr = 0;
+       else if (p->frequency >= 1100000)
+               pwr = 1;
+       else pwr = 2;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = ((div & 0x18000) >> 10) | 0x95;
+       buf[3] = (pwr << 6) | 0x30;
+
+       // NOTE: since we're using a prescaler of 2, we set the
+       // divisor frequency to 62.5kHz and divide by 125 above
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct ves1x93_config alps_bsrv2_config = {
+       .demod_address = 0x08,
+       .xin = 90100000UL,
+       .invert_pwm = 0,
+};
+
+static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = p->frequency / 125;
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x8e;
+       data[3] = 0x00;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct tda8083_config grundig_29504_451_config = {
+       .demod_address = 0x68,
+};
+
+static void frontend_init(struct budget_patch* budget)
+{
+       switch(budget->dev->pci->subsystem_device) {
+       case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
+       case 0x1013: // SATELCO Multimedia PCI
+
+               // try the ALPS BSRV2 first of all
+               budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
+                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
+                       budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
+                       budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
+                       break;
+               }
+
+               // try the ALPS BSRU6 now
+               budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
+                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+
+                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
+                       break;
+               }
+
+               // Try the grundig 29504-451
+               budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
+                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
+                       break;
+               }
+               break;
+       }
+
+       if (budget->dvb_frontend == NULL) {
+               printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      budget->dev->pci->vendor,
+                      budget->dev->pci->device,
+                      budget->dev->pci->subsystem_vendor,
+                      budget->dev->pci->subsystem_device);
+       } else {
+               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
+                       printk("budget-av: Frontend registration failed!\n");
+                       dvb_frontend_detach(budget->dvb_frontend);
+                       budget->dvb_frontend = NULL;
+               }
+       }
+}
+
+/* written by Emard */
+static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
+{
+       struct budget_patch *budget;
+       int err;
+       int count = 0;
+       int detected = 0;
+
+#define PATCH_RESET 0
+#define RPS_IRQ 0
+#define HPS_SETUP 0
+#if PATCH_RESET
+       saa7146_write(dev, MC1, MASK_31);
+       msleep(40);
+#endif
+#if HPS_SETUP
+       // initialize registers. Better to have it like this
+       // than leaving something unconfigured
+       saa7146_write(dev, DD1_STREAM_B, 0);
+       // port B VSYNC at rising edge
+       saa7146_write(dev, DD1_INIT, 0x00000200);  // have this in budget-core too!
+       saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
+
+       // debi config
+       // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
+
+       // zero all HPS registers
+       saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
+       saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
+       saa7146_write(dev, BCS_CTRL, 0);                        // r70
+       saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
+       saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
+       saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
+       saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
+       // Set HPS prescaler for port B input
+       saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
+       saa7146_write(dev, MC2,
+         0 * (MASK_08 | MASK_24)  |   // BRS control
+         0 * (MASK_09 | MASK_25)  |   // a
+         0 * (MASK_10 | MASK_26)  |   // b
+         1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
+         1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
+         0 * (MASK_01 | MASK_15)      // DEBI
+          );
+#endif
+       // Disable RPS1 and RPS0
+       saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
+       // RPS1 timeout disable
+       saa7146_write(dev, RPS_TOV1, 0);
+
+       // code for autodetection
+       // will wait for VBI_B event (vertical blank at port B)
+       // and will reset GPIO3 after VBI_B is detected.
+       // (GPIO3 should be raised high by CPU to
+       // test if GPIO3 will generate vertical blank signal
+       // in budget patch GPIO3 is connected to VSYNC_B
+       count = 0;
+#if 0
+       WRITE_RPS1(CMD_UPLOAD |
+         MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
+#endif
+       WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
+       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+       WRITE_RPS1(GPIO3_MSK);
+       WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+#if RPS_IRQ
+       // issue RPS1 interrupt to increment counter
+       WRITE_RPS1(CMD_INTERRUPT);
+       // at least a NOP is neede between two interrupts
+       WRITE_RPS1(CMD_NOP);
+       // interrupt again
+       WRITE_RPS1(CMD_INTERRUPT);
+#endif
+       WRITE_RPS1(CMD_STOP);
+
+#if RPS_IRQ
+       // set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+       // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+       // use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+       saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+       // set event counter 1 threshold to maximum allowed value        (rEC p55)
+       saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+       // Fix VSYNC level
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       // Set RPS1 Address register to point to RPS code               (r108 p42)
+       saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+       // Enable RPS1,                                                 (rFC p33)
+       saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
+
+
+       mdelay(50);
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+       mdelay(150);
+
+
+       if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
+               detected = 1;
+
+#if RPS_IRQ
+       printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+#endif
+       // Disable RPS1
+       saa7146_write(dev, MC1, ( MASK_29 ));
+
+       if(detected == 0)
+               printk("budget-patch not detected or saa7146 in non-default state.\n"
+                      "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
+
+       else
+               printk("BUDGET-PATCH DETECTED.\n");
+
+
+/*      OLD (Original design by Roberto Deza):
+**      This code will setup the SAA7146_RPS1 to generate a square
+**      wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
+**      TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
+**      then, this GPIO3 output which is connected to the D1B_VSYNC
+**      input, will trigger the acquisition of the alternate field
+**      and so on.
+**      Currently, the TT_budget / WinTV_Nova cards have two ICs
+**      (74HCT4040, LVC74) for the generation of this VSYNC signal,
+**      which seems that can be done perfectly without this :-)).
+*/
+
+/*      New design (By Emard)
+**      this rps1 code will copy internal HS event to GPIO3 pin.
+**      GPIO3 is in budget-patch hardware connected to port B VSYNC
+
+**      HS is an internal event of 7146, accessible with RPS
+**      and temporarily raised high every n lines
+**      (n in defined in the RPS_THRESH1 counter threshold)
+**      I think HS is raised high on the beginning of the n-th line
+**      and remains high until this n-th line that triggered
+**      it is completely received. When the reception of n-th line
+**      ends, HS is lowered.
+
+**      To transmit data over DMA, 7146 needs changing state at
+**      port B VSYNC pin. Any changing of port B VSYNC will
+**      cause some DMA data transfer, with more or less packets loss.
+**      It depends on the phase and frequency of VSYNC and
+**      the way of 7146 is instructed to trigger on port B (defined
+**      in DD1_INIT register, 3rd nibble from the right valid
+**      numbers are 0-7, see datasheet)
+**
+**      The correct triggering can minimize packet loss,
+**      dvbtraffic should give this stable bandwidths:
+**        22k transponder = 33814 kbit/s
+**      27.5k transponder = 38045 kbit/s
+**      by experiment it is found that the best results
+**      (stable bandwidths and almost no packet loss)
+**      are obtained using DD1_INIT triggering number 2
+**      (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
+**      and a VSYNC phase that occurs in the middle of DMA transfer
+**      (about byte 188*512=96256 in the DMA window).
+**
+**      Phase of HS is still not clear to me how to control,
+**      It just happens to be so. It can be seen if one enables
+**      RPS_IRQ and print Event Counter 1 in vpeirq(). Every
+**      time RPS_INTERRUPT is called, the Event Counter 1 will
+**      increment. That's how the 7146 is programmed to do event
+**      counting in this budget-patch.c
+**      I *think* HPS setting has something to do with the phase
+**      of HS but I can't be 100% sure in that.
+
+**      hardware debug note: a working budget card (including budget patch)
+**      with vpeirq() interrupt setup in mode "0x90" (every 64K) will
+**      generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
+**      and that means 3*25=75 Hz of interrupt frequency, as seen by
+**      watch cat /proc/interrupts
+**
+**      If this frequency is 3x lower (and data received in the DMA
+**      buffer don't start with 0x47, but in the middle of packets,
+**      whose lengths appear to be like 188 292 188 104 etc.
+**      this means VSYNC line is not connected in the hardware.
+**      (check soldering pcb and pins)
+**      The same behaviour of missing VSYNC can be duplicated on budget
+**      cards, by setting DD1_INIT trigger mode 7 in 3rd nibble.
+*/
+
+       // Setup RPS1 "program" (p35)
+       count = 0;
+
+
+       // Wait Source Line Counter Threshold                           (p36)
+       WRITE_RPS1(CMD_PAUSE | EVT_HS);
+       // Set GPIO3=1                                                  (p42)
+       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+       WRITE_RPS1(GPIO3_MSK);
+       WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
+#if RPS_IRQ
+       // issue RPS1 interrupt
+       WRITE_RPS1(CMD_INTERRUPT);
+#endif
+       // Wait reset Source Line Counter Threshold                     (p36)
+       WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
+       // Set GPIO3=0                                                  (p42)
+       WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+       WRITE_RPS1(GPIO3_MSK);
+       WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+#if RPS_IRQ
+       // issue RPS1 interrupt
+       WRITE_RPS1(CMD_INTERRUPT);
+#endif
+       // Jump to begin of RPS program                                 (p37)
+       WRITE_RPS1(CMD_JUMP);
+       WRITE_RPS1(dev->d_rps1.dma_handle);
+
+       // Fix VSYNC level
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       // Set RPS1 Address register to point to RPS code               (r108 p42)
+       saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+
+       if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
+               return -ENOMEM;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
+       if (err) {
+               kfree(budget);
+               return err;
+       }
+
+       // Set Source Line Counter Threshold, using BRS                 (rCC p43)
+       // It generates HS event every TS_HEIGHT lines
+       // this is related to TS_WIDTH set in register
+       // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
+       // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
+       //,then RPS_THRESH1
+       // should be set to trigger every TS_HEIGHT (512) lines.
+       //
+       saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
+
+       // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
+       // Enable RPS1                                                  (rFC p33)
+       saa7146_write(dev, MC1, (MASK_13 | MASK_29));
+
+
+       dev->ext_priv = budget;
+
+       budget->dvb_adapter.priv = budget;
+       frontend_init(budget);
+
+       ttpci_budget_init_hooks(budget);
+
+       return 0;
+}
+
+static int budget_patch_detach (struct saa7146_dev* dev)
+{
+       struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
+       int err;
+
+       if (budget->dvb_frontend) {
+               dvb_unregister_frontend(budget->dvb_frontend);
+               dvb_frontend_detach(budget->dvb_frontend);
+       }
+       err = ttpci_budget_deinit (budget);
+
+       kfree (budget);
+
+       return err;
+}
+
+static int __init budget_patch_init(void)
+{
+       return saa7146_register_extension(&budget_extension);
+}
+
+static void __exit budget_patch_exit(void)
+{
+       saa7146_unregister_extension(&budget_extension);
+}
+
+static struct saa7146_extension budget_extension = {
+       .name           = "budget_patch dvb",
+       .flags          = 0,
+
+       .module         = THIS_MODULE,
+       .pci_tbl        = pci_tbl,
+       .attach         = budget_patch_attach,
+       .detach         = budget_patch_detach,
+
+       .irq_mask       = MASK_10,
+       .irq_func       = ttpci_budget_irq10_handler,
+};
+
+module_init(budget_patch_init);
+module_exit(budget_patch_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
+MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
+                  "based so-called Budget Patch cards");
diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c
new file mode 100644 (file)
index 0000000..7e6e43a
--- /dev/null
@@ -0,0 +1,871 @@
+/*
+ * budget.c: driver for the SAA7146 based Budget DVB cards
+ *
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ *
+ * 26feb2004 Support for FS Activy Card (Grundig tuner) by
+ *           Michael Dreher <michael@5dot1.de>,
+ *           Oliver Endriss <o.endriss@gmx.de> and
+ *           Andreas 'randy' Weinberger
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/ 
+ */
+
+#include "budget.h"
+#include "stv0299.h"
+#include "ves1x93.h"
+#include "ves1820.h"
+#include "l64781.h"
+#include "tda8083.h"
+#include "s5h1420.h"
+#include "tda10086.h"
+#include "tda826x.h"
+#include "lnbp21.h"
+#include "bsru6.h"
+#include "bsbe1.h"
+#include "tdhd1.h"
+#include "stv6110x.h"
+#include "stv090x.h"
+#include "isl6423.h"
+#include "lnbh24.h"
+
+
+static int diseqc_method;
+module_param(diseqc_method, int, 0444);
+MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static void Set22K (struct budget *budget, int state)
+{
+       struct saa7146_dev *dev=budget->dev;
+       dprintk(2, "budget: %p\n", budget);
+       saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+   Ralph Metzler <rjkm@metzlerbros.de> */
+
+static void DiseqcSendBit (struct budget *budget, int data)
+{
+       struct saa7146_dev *dev=budget->dev;
+       dprintk(2, "budget: %p\n", budget);
+
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+       udelay(data ? 500 : 1000);
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       udelay(data ? 1000 : 500);
+}
+
+static void DiseqcSendByte (struct budget *budget, int data)
+{
+       int i, par=1, d;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       for (i=7; i>=0; i--) {
+               d = (data>>i)&1;
+               par ^= d;
+               DiseqcSendBit(budget, d);
+       }
+
+       DiseqcSendBit(budget, par);
+}
+
+static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
+{
+       struct saa7146_dev *dev=budget->dev;
+       int i;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+       mdelay(16);
+
+       for (i=0; i<len; i++)
+               DiseqcSendByte(budget, msg[i]);
+
+       mdelay(16);
+
+       if (burst!=-1) {
+               if (burst)
+                       DiseqcSendByte(budget, 0xff);
+               else {
+                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+                       mdelay(12);
+                       udelay(500);
+                       saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+               }
+               msleep(20);
+       }
+
+       return 0;
+}
+
+/*
+ *   Routines for the Fujitsu Siemens Activy budget card
+ *   22 kHz tone and DiSEqC are handled by the frontend.
+ *   Voltage must be set here.
+ *   GPIO 1: LNBP EN, GPIO 2: LNBP VSEL
+ */
+static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
+{
+       struct saa7146_dev *dev=budget->dev;
+
+       dprintk(2, "budget: %p\n", budget);
+
+       switch (voltage) {
+               case SEC_VOLTAGE_13:
+                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
+                       saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
+                       break;
+               case SEC_VOLTAGE_18:
+                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
+                       saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
+                       break;
+               case SEC_VOLTAGE_OFF:
+                       saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       return SetVoltage_Activy (budget, voltage);
+}
+
+static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               Set22K (budget, 1);
+               break;
+
+       case SEC_TONE_OFF:
+               Set22K (budget, 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+
+       return 0;
+}
+
+static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+
+       SendDiSEqCMsg (budget, 0, NULL, minicmd);
+
+       return 0;
+}
+
+static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+       u8 pwr = 0;
+       u8 buf[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       u32 div = (c->frequency + 479500) / 125;
+
+       if (c->frequency > 2000000)
+               pwr = 3;
+       else if (c->frequency > 1800000)
+               pwr = 2;
+       else if (c->frequency > 1600000)
+               pwr = 1;
+       else if (c->frequency > 1200000)
+               pwr = 0;
+       else if (c->frequency >= 1100000)
+               pwr = 1;
+       else pwr = 2;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = ((div & 0x18000) >> 10) | 0x95;
+       buf[3] = (pwr << 6) | 0x30;
+
+       // NOTE: since we're using a prescaler of 2, we set the
+       // divisor frequency to 62.5kHz and divide by 125 above
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct ves1x93_config alps_bsrv2_config =
+{
+       .demod_address = 0x08,
+       .xin = 90100000UL,
+       .invert_pwm = 0,
+};
+
+static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = (c->frequency + 35937500 + 31250) / 62500;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x85 | ((div >> 10) & 0x60);
+       data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct ves1820_config alps_tdbe2_config = {
+       .demod_address = 0x09,
+       .xin = 57840000UL,
+       .invert = 1,
+       .selagc = VES1820_SELAGC_SIGNAMPERR,
+};
+
+static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget *budget = fe->dvb->priv;
+       u8 *tuner_addr = fe->tuner_priv;
+       u32 div;
+       u8 cfg, cpump, band_select;
+       u8 data[4];
+       struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) };
+
+       if (tuner_addr)
+               msg.addr = *tuner_addr;
+       else
+               msg.addr = 0x61;
+
+       div = (36125000 + c->frequency) / 166666;
+
+       cfg = 0x88;
+
+       if (c->frequency < 175000000)
+               cpump = 2;
+       else if (c->frequency < 390000000)
+               cpump = 1;
+       else if (c->frequency < 470000000)
+               cpump = 2;
+       else if (c->frequency < 750000000)
+               cpump = 1;
+       else
+               cpump = 3;
+
+       if (c->frequency < 175000000)
+               band_select = 0x0e;
+       else if (c->frequency < 470000000)
+               band_select = 0x05;
+       else
+               band_select = 0x03;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = ((div >> 10) & 0x60) | cfg;
+       data[3] = (cpump << 6) | band_select;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct l64781_config grundig_29504_401_config = {
+       .demod_address = 0x55,
+};
+
+static struct l64781_config grundig_29504_401_config_activy = {
+       .demod_address = 0x54,
+};
+
+static u8 tuner_address_grundig_29504_401_activy = 0x60;
+
+static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = c->frequency / 125;
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x8e;
+       data[3] = 0x00;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct tda8083_config grundig_29504_451_config = {
+       .demod_address = 0x68,
+};
+
+static int s5h1420_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct budget* budget = (struct budget*) fe->dvb->priv;
+       u32 div;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       div = c->frequency / 1000;
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0xc2;
+
+       if (div < 1450)
+               data[3] = 0x00;
+       else if (div < 1850)
+               data[3] = 0x40;
+       else if (div < 2000)
+               data[3] = 0x80;
+       else
+               data[3] = 0xc0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+       return 0;
+}
+
+static struct s5h1420_config s5h1420_config = {
+       .demod_address = 0x53,
+       .invert = 1,
+       .cdclk_polarity = 1,
+};
+
+static struct tda10086_config tda10086_config = {
+       .demod_address = 0x0e,
+       .invert = 0,
+       .diseqc_tone = 1,
+       .xtal_freq = TDA10086_XTAL_16M,
+};
+
+static struct stv0299_config alps_bsru6_config_activy = {
+       .demod_address = 0x68,
+       .inittab = alps_bsru6_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .op0_off = 1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsru6_set_symbol_rate,
+};
+
+static struct stv0299_config alps_bsbe1_config_activy = {
+       .demod_address = 0x68,
+       .inittab = alps_bsbe1_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .op0_off = 1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
+};
+
+static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
+{
+       struct budget *budget = (struct budget *)fe->dvb->priv;
+
+       return request_firmware(fw, name, &budget->dev->pci->dev);
+}
+
+
+static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg)
+{
+       u8 val;
+       struct i2c_msg msg[] = {
+               { .addr = adr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+       };
+
+       return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val;
+}
+
+static u8 read_pwm(struct budget* budget)
+{
+       u8 b = 0xff;
+       u8 pwm;
+       struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
+                                { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
+
+       if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+static struct stv090x_config tt1600_stv090x_config = {
+       .device                 = STV0903,
+       .demod_mode             = STV090x_SINGLE,
+       .clk_mode               = STV090x_CLK_EXT,
+
+       .xtal                   = 13500000,
+       .address                = 0x68,
+
+       .ts1_mode               = STV090x_TSMODE_DVBCI,
+       .ts2_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
+
+       .repeater_level         = STV090x_RPTLEVEL_16,
+
+       .tuner_init             = NULL,
+       .tuner_sleep            = NULL,
+       .tuner_set_mode         = NULL,
+       .tuner_set_frequency    = NULL,
+       .tuner_get_frequency    = NULL,
+       .tuner_set_bandwidth    = NULL,
+       .tuner_get_bandwidth    = NULL,
+       .tuner_set_bbgain       = NULL,
+       .tuner_get_bbgain       = NULL,
+       .tuner_set_refclk       = NULL,
+       .tuner_get_status       = NULL,
+};
+
+static struct stv6110x_config tt1600_stv6110x_config = {
+       .addr                   = 0x60,
+       .refclk                 = 27000000,
+       .clk_div                = 2,
+};
+
+static struct isl6423_config tt1600_isl6423_config = {
+       .current_max            = SEC_CURRENT_515m,
+       .curlim                 = SEC_CURRENT_LIM_ON,
+       .mod_extern             = 1,
+       .addr                   = 0x08,
+};
+
+static void frontend_init(struct budget *budget)
+{
+       (void)alps_bsbe1_config; /* avoid warning */
+
+       switch(budget->dev->pci->subsystem_device) {
+       case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
+       case 0x1013:
+               // try the ALPS BSRV2 first of all
+               budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
+                       budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+                       budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+                       budget->dvb_frontend->ops.set_tone = budget_set_tone;
+                       break;
+               }
+
+               // try the ALPS BSRU6 now
+               budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
+                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+                       if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) {
+                               budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+                               budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+                               budget->dvb_frontend->ops.set_tone = budget_set_tone;
+                       }
+                       break;
+               }
+               break;
+
+       case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
+
+               budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
+
+               budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+                       budget->dvb_frontend->tuner_priv = NULL;
+                       break;
+               }
+               break;
+
+       case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */
+       {
+               int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67);
+
+               if (subtype < 0)
+                       break;
+               /* fixme: find a better way to identify the card */
+               if (subtype < 0x36) {
+                       /* assume ALPS BSRU6 */
+                       budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap);
+                       if (budget->dvb_frontend) {
+                               printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n");
+                               budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
+                               budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+                               budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
+                               budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
+                               break;
+                       }
+               } else {
+                       /* assume ALPS BSBE1 */
+                       /* reset tuner */
+                       saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO);
+                       msleep(50);
+                       saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI);
+                       msleep(250);
+                       budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap);
+                       if (budget->dvb_frontend) {
+                               printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n");
+                               budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
+                               budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+                               budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
+                               budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
+                               break;
+                       }
+               }
+               break;
+       }
+
+       case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
+               budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
+                       budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage;
+                       budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
+               }
+               break;
+
+       case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */
+               budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params;
+                       budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+               }
+               break;
+
+       case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */
+               budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy;
+                       budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+               }
+               break;
+
+       case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
+               budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params;
+                       if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
+                               printk("%s: No LNBP21 found!\n", __func__);
+                               goto error_out;
+                       }
+                       break;
+               }
+
+       case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262)
+               // gpio2 is connected to CLB - reset it + leave it high
+               saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+               msleep(1);
+               saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+               msleep(1);
+
+               budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap);
+               if (budget->dvb_frontend) {
+                       if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL)
+                               printk("%s: No tda826x found!\n", __func__);
+                       if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) {
+                               printk("%s: No LNBP21 found!\n", __func__);
+                               goto error_out;
+                       }
+                       break;
+               }
+
+       case 0x101c: { /* TT S2-1600 */
+                       struct stv6110x_devctl *ctl;
+                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+                       msleep(50);
+                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+                       msleep(250);
+
+                       budget->dvb_frontend = dvb_attach(stv090x_attach,
+                                                         &tt1600_stv090x_config,
+                                                         &budget->i2c_adap,
+                                                         STV090x_DEMODULATOR_0);
+
+                       if (budget->dvb_frontend) {
+
+                               ctl = dvb_attach(stv6110x_attach,
+                                                budget->dvb_frontend,
+                                                &tt1600_stv6110x_config,
+                                                &budget->i2c_adap);
+
+                               if (ctl) {
+                                       tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
+                                       tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
+                                       tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
+                                       tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+                                       tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+                                       tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+                                       tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+                                       tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
+                                       tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
+                                       tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
+                                       tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
+
+                                       /* call the init function once to initialize
+                                          tuner's clock output divider and demod's
+                                          master clock */
+                                       if (budget->dvb_frontend->ops.init)
+                                               budget->dvb_frontend->ops.init(budget->dvb_frontend);
+
+                                       if (dvb_attach(isl6423_attach,
+                                                      budget->dvb_frontend,
+                                                      &budget->i2c_adap,
+                                                      &tt1600_isl6423_config) == NULL) {
+                                               printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__);
+                                               goto error_out;
+                                       }
+                               } else {
+                                       printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
+                                       goto error_out;
+                               }
+                       }
+               }
+               break;
+
+       case 0x1020: { /* Omicom S2 */
+                       struct stv6110x_devctl *ctl;
+                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+                       msleep(50);
+                       saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+                       msleep(250);
+
+                       budget->dvb_frontend = dvb_attach(stv090x_attach,
+                                                         &tt1600_stv090x_config,
+                                                         &budget->i2c_adap,
+                                                         STV090x_DEMODULATOR_0);
+
+                       if (budget->dvb_frontend) {
+                               printk(KERN_INFO "budget: Omicom S2 detected\n");
+
+                               ctl = dvb_attach(stv6110x_attach,
+                                                budget->dvb_frontend,
+                                                &tt1600_stv6110x_config,
+                                                &budget->i2c_adap);
+
+                               if (ctl) {
+                                       tt1600_stv090x_config.tuner_init          = ctl->tuner_init;
+                                       tt1600_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
+                                       tt1600_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
+                                       tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+                                       tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+                                       tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+                                       tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+                                       tt1600_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
+                                       tt1600_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
+                                       tt1600_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
+                                       tt1600_stv090x_config.tuner_get_status    = ctl->tuner_get_status;
+
+                                       /* call the init function once to initialize
+                                          tuner's clock output divider and demod's
+                                          master clock */
+                                       if (budget->dvb_frontend->ops.init)
+                                               budget->dvb_frontend->ops.init(budget->dvb_frontend);
+
+                                       if (dvb_attach(lnbh24_attach,
+                                                       budget->dvb_frontend,
+                                                       &budget->i2c_adap,
+                                                       LNBH24_PCL | LNBH24_TTX,
+                                                       LNBH24_TEN, 0x14>>1) == NULL) {
+                                               printk(KERN_ERR
+                                               "No LNBH24 found!\n");
+                                               goto error_out;
+                                       }
+                               } else {
+                                       printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
+                                       goto error_out;
+                               }
+                       }
+               }
+               break;
+       }
+
+       if (budget->dvb_frontend == NULL) {
+               printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+                      budget->dev->pci->vendor,
+                      budget->dev->pci->device,
+                      budget->dev->pci->subsystem_vendor,
+                      budget->dev->pci->subsystem_device);
+       } else {
+               if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
+                       goto error_out;
+       }
+       return;
+
+error_out:
+       printk("budget: Frontend registration failed!\n");
+       dvb_frontend_detach(budget->dvb_frontend);
+       budget->dvb_frontend = NULL;
+       return;
+}
+
+static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
+{
+       struct budget *budget = NULL;
+       int err;
+
+       budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
+       if( NULL == budget ) {
+               return -ENOMEM;
+       }
+
+       dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
+
+       dev->ext_priv = budget;
+
+       err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
+       if (err) {
+               printk("==> failed\n");
+               kfree (budget);
+               return err;
+       }
+
+       budget->dvb_adapter.priv = budget;
+       frontend_init(budget);
+
+       ttpci_budget_init_hooks(budget);
+
+       return 0;
+}
+
+static int budget_detach (struct saa7146_dev* dev)
+{
+       struct budget *budget = (struct budget*) dev->ext_priv;
+       int err;
+
+       if (budget->dvb_frontend) {
+               dvb_unregister_frontend(budget->dvb_frontend);
+               dvb_frontend_detach(budget->dvb_frontend);
+       }
+
+       err = ttpci_budget_deinit (budget);
+
+       kfree (budget);
+       dev->ext_priv = NULL;
+
+       return err;
+}
+
+static struct saa7146_extension budget_extension;
+
+MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S  PCI",  BUDGET_TT);
+MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C  PCI",  BUDGET_TT);
+MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
+MAKE_BUDGET_INFO(satel,        "SATELCO Multimedia PCI",       BUDGET_TT_HW_DISEQC);
+MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
+MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
+MAKE_BUDGET_INFO(fsact,         "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
+MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY);
+MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT);
+
+static struct pci_device_id pci_tbl[] = {
+       MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
+       MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
+       MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
+       MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
+       MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1016),
+       MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
+       MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c),
+       MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
+       MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
+       MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
+       MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61),
+       MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020),
+       {
+               .vendor    = 0,
+       }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+static struct saa7146_extension budget_extension = {
+       .name           = "budget dvb",
+       .flags          = SAA7146_USE_I2C_IRQ,
+
+       .module         = THIS_MODULE,
+       .pci_tbl        = pci_tbl,
+       .attach         = budget_attach,
+       .detach         = budget_detach,
+
+       .irq_mask       = MASK_10,
+       .irq_func       = ttpci_budget_irq10_handler,
+};
+
+static int __init budget_init(void)
+{
+       return saa7146_register_extension(&budget_extension);
+}
+
+static void __exit budget_exit(void)
+{
+       saa7146_unregister_extension(&budget_extension);
+}
+
+module_init(budget_init);
+module_exit(budget_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
+                  "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
new file mode 100644 (file)
index 0000000..3d8a806
--- /dev/null
@@ -0,0 +1,124 @@
+
+#ifndef __BUDGET_DVB__
+#define __BUDGET_DVB__
+
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include <media/saa7146.h>
+
+extern int budget_debug;
+
+#ifdef dprintk
+#undef dprintk
+#endif
+
+#define dprintk(level,args...) \
+           do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0)
+
+struct budget_info {
+       char *name;
+       int type;
+};
+
+/* place to store all the necessary device information */
+struct budget {
+
+       /* devices */
+       struct dvb_device dvb_dev;
+       struct dvb_net dvb_net;
+
+       struct saa7146_dev *dev;
+
+       struct i2c_adapter i2c_adap;
+       struct budget_info *card;
+
+       unsigned char *grabbing;
+       struct saa7146_pgtable pt;
+
+       struct tasklet_struct fidb_tasklet;
+       struct tasklet_struct vpe_tasklet;
+
+       struct dmxdev dmxdev;
+       struct dvb_demux demux;
+
+       struct dmx_frontend hw_frontend;
+       struct dmx_frontend mem_frontend;
+
+       int ci_present;
+       int video_port;
+
+       u32 buffer_width;
+       u32 buffer_height;
+       u32 buffer_size;
+       u32 buffer_warning_threshold;
+       u32 buffer_warnings;
+       unsigned long buffer_warning_time;
+
+       u32 ttbp;
+       int feeding;
+
+       spinlock_t feedlock;
+
+       spinlock_t debilock;
+
+       struct dvb_adapter dvb_adapter;
+       struct dvb_frontend *dvb_frontend;
+       int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status);
+       int fe_synced;
+
+       void *priv;
+};
+
+#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \
+static struct budget_info x_var ## _info = { \
+       .name=x_name,   \
+       .type=x_type }; \
+static struct saa7146_pci_extension_data x_var = { \
+       .ext_priv = &x_var ## _info, \
+       .ext = &budget_extension };
+
+#define BUDGET_TT                 0
+#define BUDGET_TT_HW_DISEQC       1
+#define BUDGET_PATCH              3
+#define BUDGET_FS_ACTIVY          4
+#define BUDGET_CIN1200S                   5
+#define BUDGET_CIN1200C                   6
+#define BUDGET_CIN1200T                   7
+#define BUDGET_KNC1S              8
+#define BUDGET_KNC1C              9
+#define BUDGET_KNC1T              10
+#define BUDGET_KNC1SP             11
+#define BUDGET_KNC1CP             12
+#define BUDGET_KNC1TP             13
+#define BUDGET_TVSTAR             14
+#define BUDGET_CIN1200C_MK3       15
+#define BUDGET_KNC1C_MK3          16
+#define BUDGET_KNC1CP_MK3         17
+#define BUDGET_KNC1S2              18
+#define BUDGET_KNC1C_TDA10024     19
+
+#define BUDGET_VIDEO_PORTA         0
+#define BUDGET_VIDEO_PORTB         1
+
+extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
+                            struct saa7146_pci_extension_data *info,
+                            struct module *owner, short *adapter_nums);
+extern void ttpci_budget_init_hooks(struct budget *budget);
+extern int ttpci_budget_deinit(struct budget *budget);
+extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
+extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port);
+extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
+                                int uselocks, int nobusyloop);
+extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value,
+                                 int uselocks, int nobusyloop);
+
+#endif
diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.c b/drivers/media/pci/ttpci/ttpci-eeprom.c
new file mode 100644 (file)
index 0000000..32d4315
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+    Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,
+    decode it and store it in the associated adapter struct for
+    use by dvb_net.c
+
+    This card appear to have the 24C16 write protect held to ground,
+    thus permitting normal read/write operation. Theoretically it
+    would be possible to write routines to burn a different (encoded)
+    MAC address into the EEPROM.
+
+    Robert Schlabbach  GMX
+    Michael Glaum      KVH Industries
+    Holger Waechtler   Convergence
+
+    Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
+                           Metzler Brothers Systementwicklung GbR
+
+    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/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/i2c.h>
+
+#include "ttpci-eeprom.h"
+
+#if 1
+#define dprintk(x...) do { printk(x); } while (0)
+#else
+#define dprintk(x...) do { } while (0)
+#endif
+
+
+static int check_mac_tt(u8 *buf)
+{
+       int i;
+       u16 tmp = 0xffff;
+
+       for (i = 0; i < 8; i++) {
+               tmp  = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
+               tmp ^= (tmp >> 4) & 0x0f;
+               tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
+       }
+       tmp ^= 0xffff;
+       return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
+}
+
+static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
+{
+       u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
+                      0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
+                      0x1d, 0x36, 0x64, 0x78};
+       u8 data[20];
+       int i;
+
+       /* In case there is a sig check failure have the orig contents available */
+       memcpy(data, encodedMAC, 20);
+
+       for (i = 0; i < 20; i++)
+               data[i] ^= xor[i];
+       for (i = 0; i < 10; i++)
+               data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
+                       >> ((data[2 * i + 1] >> 6) & 3);
+
+       if (check_mac_tt(data))
+               return -ENODEV;
+
+       decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];
+       decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];
+       return 0;
+}
+
+int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC)
+{
+       u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
+                      0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
+                      0x1d, 0x36, 0x64, 0x78};
+       u8 data[20];
+       int i;
+
+       memcpy(data, encodedMAC, 20);
+
+       for (i = 0; i < 20; i++)
+               data[i] ^= xor[i];
+       for (i = 0; i < 10; i++)
+               data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
+                       >> ((data[2 * i + 1] >> 6) & 3);
+
+       if (check_mac_tt(data))
+               return -ENODEV;
+
+       decodedMAC[0] = data[2];
+       decodedMAC[1] = data[1];
+       decodedMAC[2] = data[0];
+       decodedMAC[3] = data[6];
+       decodedMAC[4] = data[5];
+       decodedMAC[5] = data[4];
+       return 0;
+}
+EXPORT_SYMBOL(ttpci_eeprom_decode_mac);
+
+static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
+{
+       int ret;
+       u8 b0[] = { 0xcc };
+
+       struct i2c_msg msg[] = {
+               { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },
+               { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 }
+       };
+
+       /* dprintk("%s\n", __func__); */
+
+       ret = i2c_transfer(adapter, msg, 2);
+
+       if (ret != 2)           /* Assume EEPROM isn't there */
+               return (-ENODEV);
+
+       return 0;
+}
+
+
+int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)
+{
+       int ret, i;
+       u8 encodedMAC[20];
+       u8 decodedMAC[6];
+
+       ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);
+
+       if (ret != 0) {         /* Will only be -ENODEV */
+               dprintk("Couldn't read from EEPROM: not there?\n");
+               memset(proposed_mac, 0, 6);
+               return ret;
+       }
+
+       ret = getmac_tt(decodedMAC, encodedMAC);
+       if( ret != 0 ) {
+               dprintk("adapter failed MAC signature check\n");
+               dprintk("encoded MAC from EEPROM was " );
+               for(i=0; i<19; i++) {
+                       dprintk( "%.2x:", encodedMAC[i]);
+               }
+               dprintk("%.2x\n", encodedMAC[19]);
+               memset(proposed_mac, 0, 6);
+               return ret;
+       }
+
+       memcpy(proposed_mac, decodedMAC, 6);
+       dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+               decodedMAC[0], decodedMAC[1], decodedMAC[2],
+               decodedMAC[3], decodedMAC[4], decodedMAC[5]);
+       return 0;
+}
+
+EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
+MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "
+               "made by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.h b/drivers/media/pci/ttpci/ttpci-eeprom.h
new file mode 100644 (file)
index 0000000..dcc33d5
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+    Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
+    decode it and store it in associated adapter net device
+
+    Robert Schlabbach  GMX
+    Michael Glaum      KVH Industries
+    Holger Waechtler   Convergence
+
+    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 __TTPCI_EEPROM_H__
+#define __TTPCI_EEPROM_H__
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+extern int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC);
+extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac);
+
+#endif
index a5630e30eadcfe23739045ebf3fba5bb02fea108..94bdf4d51712257649f5ff1b5e866d77043a6fd3 100644 (file)
@@ -79,4 +79,4 @@ ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
 # due to tuner-xc3028
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
+ccflags-y += -I$(srctree)/drivers/media/pci/ttpci