]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
[media] dvb-usb: move it to drivers/media/usb/dvb-usb
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 14 Jun 2012 19:35:56 +0000 (16:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:26:31 +0000 (23:26 -0300)
As media/dvb will be removed, move it to a proper place.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
263 files changed:
Documentation/dvb/README.dvb-usb
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/dvb/Kconfig
drivers/media/dvb/Makefile
drivers/media/dvb/dvb-usb-v2/Kconfig [deleted file]
drivers/media/dvb/dvb-usb-v2/Makefile [deleted file]
drivers/media/dvb/dvb-usb-v2/af9015.c [deleted file]
drivers/media/dvb/dvb-usb-v2/af9015.h [deleted file]
drivers/media/dvb/dvb-usb-v2/af9035.c [deleted file]
drivers/media/dvb/dvb-usb-v2/af9035.h [deleted file]
drivers/media/dvb/dvb-usb-v2/anysee.c [deleted file]
drivers/media/dvb/dvb-usb-v2/anysee.h [deleted file]
drivers/media/dvb/dvb-usb-v2/au6610.c [deleted file]
drivers/media/dvb/dvb-usb-v2/au6610.h [deleted file]
drivers/media/dvb/dvb-usb-v2/az6007.c [deleted file]
drivers/media/dvb/dvb-usb-v2/ce6230.c [deleted file]
drivers/media/dvb/dvb-usb-v2/ce6230.h [deleted file]
drivers/media/dvb/dvb-usb-v2/cypress_firmware.c [deleted file]
drivers/media/dvb/dvb-usb-v2/cypress_firmware.h [deleted file]
drivers/media/dvb/dvb-usb-v2/dvb_usb.h [deleted file]
drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h [deleted file]
drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c [deleted file]
drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c [deleted file]
drivers/media/dvb/dvb-usb-v2/ec168.c [deleted file]
drivers/media/dvb/dvb-usb-v2/ec168.h [deleted file]
drivers/media/dvb/dvb-usb-v2/gl861.c [deleted file]
drivers/media/dvb/dvb-usb-v2/gl861.h [deleted file]
drivers/media/dvb/dvb-usb-v2/it913x.c [deleted file]
drivers/media/dvb/dvb-usb-v2/lmedm04.c [deleted file]
drivers/media/dvb/dvb-usb-v2/lmedm04.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf.c [deleted file]
drivers/media/dvb/dvb-usb-v2/mxl111sf.h [deleted file]
drivers/media/dvb/dvb-usb-v2/rtl28xxu.c [deleted file]
drivers/media/dvb/dvb-usb-v2/rtl28xxu.h [deleted file]
drivers/media/dvb/dvb-usb-v2/usb_urb.c [deleted file]
drivers/media/dvb/dvb-usb/Kconfig [deleted file]
drivers/media/dvb/dvb-usb/Makefile [deleted file]
drivers/media/dvb/dvb-usb/a800.c [deleted file]
drivers/media/dvb/dvb-usb/af9005-fe.c [deleted file]
drivers/media/dvb/dvb-usb/af9005-remote.c [deleted file]
drivers/media/dvb/dvb-usb/af9005-script.h [deleted file]
drivers/media/dvb/dvb-usb/af9005.c [deleted file]
drivers/media/dvb/dvb-usb/af9005.h [deleted file]
drivers/media/dvb/dvb-usb/az6027.c [deleted file]
drivers/media/dvb/dvb-usb/az6027.h [deleted file]
drivers/media/dvb/dvb-usb/cinergyT2-core.c [deleted file]
drivers/media/dvb/dvb-usb/cinergyT2-fe.c [deleted file]
drivers/media/dvb/dvb-usb/cinergyT2.h [deleted file]
drivers/media/dvb/dvb-usb/cxusb.c [deleted file]
drivers/media/dvb/dvb-usb/cxusb.h [deleted file]
drivers/media/dvb/dvb-usb/dib0700.h [deleted file]
drivers/media/dvb/dvb-usb/dib0700_core.c [deleted file]
drivers/media/dvb/dvb-usb/dib0700_devices.c [deleted file]
drivers/media/dvb/dvb-usb/dib07x0.h [deleted file]
drivers/media/dvb/dvb-usb/dibusb-common.c [deleted file]
drivers/media/dvb/dvb-usb/dibusb-mb.c [deleted file]
drivers/media/dvb/dvb-usb/dibusb-mc.c [deleted file]
drivers/media/dvb/dvb-usb/dibusb.h [deleted file]
drivers/media/dvb/dvb-usb/digitv.c [deleted file]
drivers/media/dvb/dvb-usb/digitv.h [deleted file]
drivers/media/dvb/dvb-usb/dtt200u-fe.c [deleted file]
drivers/media/dvb/dvb-usb/dtt200u.c [deleted file]
drivers/media/dvb/dvb-usb/dtt200u.h [deleted file]
drivers/media/dvb/dvb-usb/dtv5100.c [deleted file]
drivers/media/dvb/dvb-usb/dtv5100.h [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-common.h [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-firmware.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-i2c.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-init.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-remote.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb-urb.c [deleted file]
drivers/media/dvb/dvb-usb/dvb-usb.h [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_dvb.c [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_remote.c [deleted file]
drivers/media/dvb/dvb-usb/dw2102.c [deleted file]
drivers/media/dvb/dvb-usb/dw2102.h [deleted file]
drivers/media/dvb/dvb-usb/friio-fe.c [deleted file]
drivers/media/dvb/dvb-usb/friio.c [deleted file]
drivers/media/dvb/dvb-usb/friio.h [deleted file]
drivers/media/dvb/dvb-usb/gp8psk-fe.c [deleted file]
drivers/media/dvb/dvb-usb/gp8psk.c [deleted file]
drivers/media/dvb/dvb-usb/gp8psk.h [deleted file]
drivers/media/dvb/dvb-usb/m920x.c [deleted file]
drivers/media/dvb/dvb-usb/m920x.h [deleted file]
drivers/media/dvb/dvb-usb/nova-t-usb2.c [deleted file]
drivers/media/dvb/dvb-usb/opera1.c [deleted file]
drivers/media/dvb/dvb-usb/pctv452e.c [deleted file]
drivers/media/dvb/dvb-usb/technisat-usb2.c [deleted file]
drivers/media/dvb/dvb-usb/ttusb2.c [deleted file]
drivers/media/dvb/dvb-usb/ttusb2.h [deleted file]
drivers/media/dvb/dvb-usb/umt-010.c [deleted file]
drivers/media/dvb/dvb-usb/usb-urb.c [deleted file]
drivers/media/dvb/dvb-usb/vp702x-fe.c [deleted file]
drivers/media/dvb/dvb-usb/vp702x.c [deleted file]
drivers/media/dvb/dvb-usb/vp702x.h [deleted file]
drivers/media/dvb/dvb-usb/vp7045-fe.c [deleted file]
drivers/media/dvb/dvb-usb/vp7045.c [deleted file]
drivers/media/dvb/dvb-usb/vp7045.h [deleted file]
drivers/media/dvb/siano/Kconfig [deleted file]
drivers/media/dvb/siano/Makefile [deleted file]
drivers/media/dvb/siano/sms-cards.c [deleted file]
drivers/media/dvb/siano/sms-cards.h [deleted file]
drivers/media/dvb/siano/smscoreapi.c [deleted file]
drivers/media/dvb/siano/smscoreapi.h [deleted file]
drivers/media/dvb/siano/smsdvb.c [deleted file]
drivers/media/dvb/siano/smsendian.c [deleted file]
drivers/media/dvb/siano/smsendian.h [deleted file]
drivers/media/dvb/siano/smsir.c [deleted file]
drivers/media/dvb/siano/smsir.h [deleted file]
drivers/media/dvb/siano/smssdio.c [deleted file]
drivers/media/dvb/siano/smsusb.c [deleted file]
drivers/media/dvb/ttusb-budget/Kconfig [deleted file]
drivers/media/dvb/ttusb-budget/Makefile [deleted file]
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c [deleted file]
drivers/media/dvb/ttusb-dec/Kconfig [deleted file]
drivers/media/dvb/ttusb-dec/Makefile [deleted file]
drivers/media/dvb/ttusb-dec/ttusb_dec.c [deleted file]
drivers/media/dvb/ttusb-dec/ttusbdecfe.c [deleted file]
drivers/media/dvb/ttusb-dec/ttusbdecfe.h [deleted file]
drivers/media/usb/Kconfig [new file with mode: 0644]
drivers/media/usb/Makefile [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/Kconfig [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/Makefile [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/af9015.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/af9015.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/af9035.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/af9035.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/anysee.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/anysee.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/au6610.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/au6610.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/az6007.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/ce6230.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/ce6230.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/cypress_firmware.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/cypress_firmware.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/dvb_usb.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/dvb_usb_common.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/ec168.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/ec168.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/gl861.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/gl861.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/it913x.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/lmedm04.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/lmedm04.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/mxl111sf.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/rtl28xxu.c [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/rtl28xxu.h [new file with mode: 0644]
drivers/media/usb/dvb-usb-v2/usb_urb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/Kconfig [new file with mode: 0644]
drivers/media/usb/dvb-usb/Makefile [new file with mode: 0644]
drivers/media/usb/dvb-usb/a800.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005-remote.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005-script.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/az6027.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/az6027.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/cinergyT2-core.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/cinergyT2-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/cinergyT2.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/cxusb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/cxusb.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dib0700.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dib0700_core.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dib0700_devices.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dib07x0.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dibusb-common.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dibusb-mb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dibusb-mc.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dibusb.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/digitv.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/digitv.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dtt200u-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dtt200u.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dtt200u.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dtv5100.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dtv5100.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-common.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-dvb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-firmware.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-i2c.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-init.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-remote.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb-urb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb-usb.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb_usb_dvb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dvb_usb_remote.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dw2102.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/dw2102.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/friio-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/friio.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/friio.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/gp8psk-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/gp8psk.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/gp8psk.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/m920x.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/m920x.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/nova-t-usb2.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/opera1.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/pctv452e.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/technisat-usb2.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/ttusb2.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/ttusb2.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/umt-010.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/usb-urb.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp702x-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp702x.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp702x.h [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp7045-fe.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp7045.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/vp7045.h [new file with mode: 0644]
drivers/media/usb/siano/Kconfig [new file with mode: 0644]
drivers/media/usb/siano/Makefile [new file with mode: 0644]
drivers/media/usb/siano/sms-cards.c [new file with mode: 0644]
drivers/media/usb/siano/sms-cards.h [new file with mode: 0644]
drivers/media/usb/siano/smscoreapi.c [new file with mode: 0644]
drivers/media/usb/siano/smscoreapi.h [new file with mode: 0644]
drivers/media/usb/siano/smsdvb.c [new file with mode: 0644]
drivers/media/usb/siano/smsendian.c [new file with mode: 0644]
drivers/media/usb/siano/smsendian.h [new file with mode: 0644]
drivers/media/usb/siano/smsir.c [new file with mode: 0644]
drivers/media/usb/siano/smsir.h [new file with mode: 0644]
drivers/media/usb/siano/smssdio.c [new file with mode: 0644]
drivers/media/usb/siano/smsusb.c [new file with mode: 0644]
drivers/media/usb/ttusb-budget/Kconfig [new file with mode: 0644]
drivers/media/usb/ttusb-budget/Makefile [new file with mode: 0644]
drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c [new file with mode: 0644]
drivers/media/usb/ttusb-dec/Kconfig [new file with mode: 0644]
drivers/media/usb/ttusb-dec/Makefile [new file with mode: 0644]
drivers/media/usb/ttusb-dec/ttusb_dec.c [new file with mode: 0644]
drivers/media/usb/ttusb-dec/ttusbdecfe.c [new file with mode: 0644]
drivers/media/usb/ttusb-dec/ttusbdecfe.h [new file with mode: 0644]
drivers/media/video/cx231xx/Makefile
drivers/staging/media/go7007/Makefile

index c4d963a67d6ffc1ec7e54b8d31cc7d9b41537796..8eb92264ee047163caa25738a30c09ad04d20fcc 100644 (file)
@@ -30,7 +30,7 @@ with the device via the bus. The connection between the DVB-API-functionality
 is done via callbacks, assigned in a static device-description (struct
 dvb_usb_device) each device-driver has to have.
 
-For an example have a look in drivers/media/dvb/dvb-usb/vp7045*.
+For an example have a look in drivers/media/usb/dvb-usb/vp7045*.
 
 Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
 ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
index b7d2802e6a3f2d4cc53e791b10e8f2a3a1c2234d..26da8b8721d56a3285402fe68ac0fa51b2c54e9d 100644 (file)
@@ -163,6 +163,7 @@ source "drivers/media/radio/Kconfig"
 
 source "drivers/media/dvb-core/Kconfig"
 source "drivers/media/dvb/Kconfig"
+source "drivers/media/usb/Kconfig"
 
 comment "Supported FireWire (IEEE 1394) Adapters"
        depends on DVB_CORE && FIREWIRE
index 37e448cafb7554daafc6ae5b8428f8cee88453a6..46a8dc3337b375fed6d196e7c7a82e34b31d30fd 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/
+obj-$(CONFIG_DVB_CORE)  += dvb-core/ dvb/ dvb-frontends/ usb/
 obj-$(CONFIG_DVB_FIREDTV) += firewire/
index b4665460c74d051210024a36c61452bcf8522d32..e2565a45de9b1e9826b42e94354dbe19110831fb 100644 (file)
@@ -15,14 +15,6 @@ comment "Supported SAA7146 based PCI Adapters"
        depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/ttpci/Kconfig"
 
-comment "Supported USB Adapters"
-       depends on DVB_CORE && USB && I2C
-source "drivers/media/dvb/dvb-usb/Kconfig"
-source "drivers/media/dvb/dvb-usb-v2/Kconfig"
-source "drivers/media/dvb/ttusb-budget/Kconfig"
-source "drivers/media/dvb/ttusb-dec/Kconfig"
-source "drivers/media/dvb/siano/Kconfig"
-
 comment "Supported FlexCopII (B2C2) Adapters"
        depends on DVB_CORE && (PCI || USB) && I2C
 source "drivers/media/dvb/b2c2/Kconfig"
index fc248268cb5aadee3f660a816b7b4bdbcebb878d..c5fa43a275aee4de5f95ea136d5a1d06f1b23713 100644 (file)
@@ -3,14 +3,9 @@
 #
 
 obj-y        :=        ttpci/          \
-               ttusb-dec/      \
-               ttusb-budget/   \
                b2c2/           \
                bt8xx/          \
-               dvb-usb/        \
-               dvb-usb-v2/     \
                pluto2/         \
-               siano/          \
                dm1105/         \
                pt1/            \
                mantis/         \
diff --git a/drivers/media/dvb/dvb-usb-v2/Kconfig b/drivers/media/dvb/dvb-usb-v2/Kconfig
deleted file mode 100644 (file)
index 276374f..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-config DVB_USB_V2
-       tristate "Support for various USB DVB devices v2"
-       depends on DVB_CORE && USB && I2C && RC_CORE
-       help
-         By enabling this you will be able to choose the various supported
-         USB1.1 and USB2.0 DVB devices.
-
-         Almost every USB device needs a firmware, please look into
-         <file:Documentation/dvb/README.dvb-usb>.
-
-         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
-         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
-
-         Say Y if you own a USB DVB device.
-
-config DVB_USB_CYPRESS_FIRMWARE
-       tristate "Cypress firmware helper routines"
-       depends on DVB_USB_V2
-
-config DVB_USB_AF9015
-       tristate "Afatech AF9015 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_AF9013
-       select DVB_PLL              if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
-
-config DVB_USB_AF9035
-       tristate "Afatech AF9035 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_AF9033
-       select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Afatech AF9035 based DVB USB receiver.
-
-config DVB_USB_ANYSEE
-       tristate "Anysee DVB-T/C USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
-       select DVB_CX24116 if !DVB_FE_CUSTOMISE
-       select DVB_STV0900 if !DVB_FE_CUSTOMISE
-       select DVB_STV6110 if !DVB_FE_CUSTOMISE
-       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
-       select DVB_CXD2820R if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Anysee E30, Anysee E30 Plus or
-         Anysee E30 C Plus DVB USB2.0 receiver.
-
-config DVB_USB_AU6610
-       tristate "Alcor Micro AU6610 USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
-
-config DVB_USB_AZ6007
-       tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_USB_CYPRESS_FIRMWARE
-       select DVB_DRXK if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the AZ6007 receivers like Terratec H7.
-
-config DVB_USB_CE6230
-       tristate "Intel CE6230 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
-
-config DVB_USB_EC168
-       tristate "E3C EC168 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_EC100
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
-
-config DVB_USB_GL861
-       tristate "Genesys Logic GL861 USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
-         receiver with USB ID 0db0:5581.
-
-config DVB_USB_IT913X
-       tristate "ITE IT913X DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_IT913X_FE
-       help
-         Say Y here to support the ITE IT913X DVB-T USB2.0
-
-config DVB_USB_LME2510
-       tristate "LME DM04/QQBOX DVB-S USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
-       select DVB_TDA826X if !DVB_FE_CUSTOMISE
-       select DVB_STV0288 if !DVB_FE_CUSTOMISE
-       select DVB_IX2505V if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the LME DM04/QQBOX DVB-S USB2.0
-
-config DVB_USB_MXL111SF
-       tristate "MxL111SF DTV USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
-       select DVB_LG2160 if !DVB_FE_CUSTOMISE
-       select VIDEO_TVEEPROM
-       help
-         Say Y here to support the MxL111SF USB2.0 DTV receiver.
-
-config DVB_USB_RTL28XXU
-       tristate "Realtek RTL28xxU DVB USB support"
-       depends on DVB_USB_V2 && EXPERIMENTAL
-       select DVB_RTL2830
-       select DVB_RTL2832
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Realtek RTL28xxU DVB USB receiver.
-
diff --git a/drivers/media/dvb/dvb-usb-v2/Makefile b/drivers/media/dvb/dvb-usb-v2/Makefile
deleted file mode 100644 (file)
index 24248b3..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o
-obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o
-
-dvb_usb_cypress_firmware-objs = cypress_firmware.o
-obj-$(CONFIG_DVB_USB_CYPRESS_FIRMWARE) += dvb_usb_cypress_firmware.o
-
-dvb-usb-af9015-objs = af9015.o
-obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
-
-dvb-usb-af9035-objs = af9035.o
-obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
-
-dvb-usb-anysee-objs = anysee.o
-obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
-
-dvb-usb-au6610-objs = au6610.o
-obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
-
-dvb-usb-az6007-objs = az6007.o
-obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
-
-dvb-usb-ce6230-objs = ce6230.o
-obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
-
-dvb-usb-ec168-objs = ec168.o
-obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
-
-dvb-usb-it913x-objs = it913x.o
-obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
-
-dvb-usb-lmedm04-objs = lmedm04.o
-obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
-
-dvb-usb-gl861-objs = gl861.o
-obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
-
-dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
-
-dvb-usb-rtl28xxu-objs = rtl28xxu.o
-obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
-
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-
diff --git a/drivers/media/dvb/dvb-usb-v2/af9015.c b/drivers/media/dvb/dvb-usb-v2/af9015.c
deleted file mode 100644 (file)
index e77429b..0000000
+++ /dev/null
@@ -1,1434 +0,0 @@
-/*
- * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- *    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 "af9015.h"
-
-static int dvb_usb_af9015_debug;
-module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-static int dvb_usb_af9015_remote;
-module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
-MODULE_PARM_DESC(remote, "select remote");
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
-{
-#define BUF_LEN 63
-#define REQ_HDR_LEN 8 /* send header size */
-#define ACK_HDR_LEN 2 /* rece header size */
-       struct af9015_state *state = d_to_priv(d);
-       int ret, wlen, rlen;
-       u8 buf[BUF_LEN];
-       u8 write = 1;
-
-       buf[0] = req->cmd;
-       buf[1] = state->seq++;
-       buf[2] = req->i2c_addr;
-       buf[3] = req->addr >> 8;
-       buf[4] = req->addr & 0xff;
-       buf[5] = req->mbox;
-       buf[6] = req->addr_len;
-       buf[7] = req->data_len;
-
-       switch (req->cmd) {
-       case GET_CONFIG:
-       case READ_MEMORY:
-       case RECONNECT_USB:
-               write = 0;
-               break;
-       case READ_I2C:
-               write = 0;
-               buf[2] |= 0x01; /* set I2C direction */
-       case WRITE_I2C:
-               buf[0] = READ_WRITE_I2C;
-               break;
-       case WRITE_MEMORY:
-               if (((req->addr & 0xff00) == 0xff00) ||
-                   ((req->addr & 0xff00) == 0xae00))
-                       buf[0] = WRITE_VIRTUAL_MEMORY;
-       case WRITE_VIRTUAL_MEMORY:
-       case COPY_FIRMWARE:
-       case DOWNLOAD_FIRMWARE:
-       case BOOT:
-               break;
-       default:
-               err("unknown command:%d", req->cmd);
-               ret = -1;
-               goto error;
-       }
-
-       /* buffer overflow check */
-       if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
-               (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
-               err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* write receives seq + status = 2 bytes
-          read receives seq + status + data = 2 + N bytes */
-       wlen = REQ_HDR_LEN;
-       rlen = ACK_HDR_LEN;
-       if (write) {
-               wlen += req->data_len;
-               memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
-       } else {
-               rlen += req->data_len;
-       }
-
-       /* no ack for these packets */
-       if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
-               rlen = 0;
-
-       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
-       if (ret)
-               goto error;
-
-       /* check status */
-       if (rlen && buf[1]) {
-               err("command failed:%d", buf[1]);
-               ret = -1;
-               goto error;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (!write)
-               memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
-error:
-       return ret;
-}
-
-static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
-       u8 len)
-{
-       struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-               val};
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
-{
-       struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-               val};
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
-{
-       return af9015_write_regs(d, addr, &val, 1);
-}
-
-static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
-{
-       return af9015_read_regs(d, addr, val, 1);
-}
-
-static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-       u8 val)
-{
-       struct af9015_state *state = d_to_priv(d);
-       struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
-
-       if (addr == state->af9013_config[0].i2c_addr ||
-           addr == state->af9013_config[1].i2c_addr)
-               req.addr_len = 3;
-
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-       u8 *val)
-{
-       struct af9015_state *state = d_to_priv(d);
-       struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
-
-       if (addr == state->af9013_config[0].i2c_addr ||
-           addr == state->af9013_config[1].i2c_addr)
-               req.addr_len = 3;
-
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
-{
-       int ret;
-       u8 val, mask = 0x01;
-
-       ret = af9015_read_reg(d, addr, &val);
-       if (ret)
-               return ret;
-
-       mask <<= bit;
-       if (op) {
-               /* set bit */
-               val |= mask;
-       } else {
-               /* clear bit */
-               mask ^= 0xff;
-               val &= mask;
-       }
-
-       return af9015_write_reg(d, addr, val);
-}
-
-static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-       return af9015_do_reg_bit(d, addr, bit, 1);
-}
-
-static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-       return af9015_do_reg_bit(d, addr, bit, 0);
-}
-
-static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct af9015_state *state = d_to_priv(d);
-       int ret = 0, i = 0;
-       u16 addr;
-       u8 uninitialized_var(mbox), addr_len;
-       struct req_t req;
-
-/*
-The bus lock is needed because there is two tuners both using same I2C-address.
-Due to that the only way to select correct tuner is use demodulator I2C-gate.
-
-................................................
-. AF9015 includes integrated AF9013 demodulator.
-. ____________                   ____________  .                ____________
-.|     uC     |                 |   demod    | .               |    tuner   |
-.|------------|                 |------------| .               |------------|
-.|   AF9015   |                 |  AF9013/5  | .               |   MXL5003  |
-.|            |--+----I2C-------|-----/ -----|-.-----I2C-------|            |
-.|            |  |              | addr 0x38  | .               |  addr 0xc6 |
-.|____________|  |              |____________| .               |____________|
-.................|..............................
-                |               ____________                   ____________
-                |              |   demod    |                 |    tuner   |
-                |              |------------|                 |------------|
-                |              |   AF9013   |                 |   MXL5003  |
-                +----I2C-------|-----/ -----|-------I2C-------|            |
-                               | addr 0x3a  |                 |  addr 0xc6 |
-                               |____________|                 |____________|
-*/
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (msg[i].addr == state->af9013_config[0].i2c_addr ||
-                   msg[i].addr == state->af9013_config[1].i2c_addr) {
-                       addr = msg[i].buf[0] << 8;
-                       addr += msg[i].buf[1];
-                       mbox = msg[i].buf[2];
-                       addr_len = 3;
-               } else {
-                       addr = msg[i].buf[0];
-                       addr_len = 1;
-                       /* mbox is don't care in that case */
-               }
-
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].len > 3 || msg[i+1].len > 61) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
-                               req.cmd = READ_MEMORY;
-                       else
-                               req.cmd = READ_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i+1].len;
-                       req.data = &msg[i+1].buf[0];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 2;
-               } else if (msg[i].flags & I2C_M_RD) {
-                       if (msg[i].len > 61) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       req.cmd = READ_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i].len;
-                       req.data = &msg[i].buf[0];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 1;
-               } else {
-                       if (msg[i].len > 21) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
-                               req.cmd = WRITE_MEMORY;
-                       else
-                               req.cmd = WRITE_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i].len-addr_len;
-                       req.data = &msg[i].buf[addr_len];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 1;
-               }
-               if (ret)
-                       goto error;
-
-       }
-       ret = i;
-
-error:
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 af9015_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9015_i2c_algo = {
-       .master_xfer = af9015_i2c_xfer,
-       .functionality = af9015_i2c_func,
-};
-
-static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 reply;
-       struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
-
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               return ret;
-
-       deb_info("%s: reply:%02x\n", __func__, reply);
-       if (reply == 0x02)
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-}
-
-static int af9015_download_firmware(struct dvb_usb_device *d,
-       const struct firmware *fw)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int i, len, remaining, ret;
-       struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
-       u16 checksum = 0;
-
-       deb_info("%s:\n", __func__);
-
-       /* calc checksum */
-       for (i = 0; i < fw->size; i++)
-               checksum += fw->data[i];
-
-       state->firmware_size = fw->size;
-       state->firmware_checksum = checksum;
-
-       #define FW_ADDR 0x5100 /* firmware start address */
-       #define LEN_MAX 55 /* max packet size */
-       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-               len = remaining;
-               if (len > LEN_MAX)
-                       len = LEN_MAX;
-
-               req.data_len = len;
-               req.data = (u8 *) &fw->data[fw->size - remaining];
-               req.addr = FW_ADDR + fw->size - remaining;
-
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret) {
-                       err("firmware download failed:%d", ret);
-                       goto error;
-               }
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = BOOT;
-       req.data_len = 0;
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret) {
-               err("firmware boot failed:%d", ret);
-               goto error;
-       }
-
-error:
-       return ret;
-}
-
-/* hash (and dump) eeprom */
-static int af9015_eeprom_hash(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       static const unsigned int eeprom_size = 256;
-       unsigned int reg;
-       u8 val, *eeprom;
-       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
-       eeprom = kmalloc(eeprom_size, GFP_KERNEL);
-       if (eeprom == NULL)
-               return -ENOMEM;
-
-       for (reg = 0; reg < eeprom_size; reg++) {
-               req.addr = reg;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto free;
-
-               eeprom[reg] = val;
-       }
-
-       if (dvb_usb_af9015_debug & 0x01)
-               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
-                               eeprom_size);
-
-       BUG_ON(eeprom_size % 4);
-
-       state->eeprom_sum = 0;
-       for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
-               state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
-               state->eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
-       }
-
-       deb_info("%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum);
-
-       ret = 0;
-free:
-       kfree(eeprom);
-       return ret;
-}
-
-static int af9015_read_config(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 val, i, offset = 0;
-       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
-       deb_info("%s:\n", __func__);
-
-       /* IR remote controller */
-       req.addr = AF9015_EEPROM_IR_MODE;
-       /* first message will timeout often due to possible hw bug */
-       for (i = 0; i < 4; i++) {
-               ret = af9015_ctrl_msg(d, &req);
-               if (!ret)
-                       break;
-       }
-       if (ret)
-               goto error;
-
-       ret = af9015_eeprom_hash(d);
-       if (ret)
-               goto error;
-
-       deb_info("%s: IR mode=%d\n", __func__, val);
-       state->ir_mode = val;
-
-       /* TS mode - one or two receivers */
-       req.addr = AF9015_EEPROM_TS_MODE;
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       state->dual_mode = val;
-       deb_info("%s: TS mode=%d\n", __func__, state->dual_mode);
-
-       /* disable 2nd adapter because we don't have PID-filters */
-       if (d->udev->speed == USB_SPEED_FULL)
-               state->dual_mode = 0;
-
-       if (state->dual_mode) {
-               /* read 2nd demodulator I2C address */
-               req.addr = AF9015_EEPROM_DEMOD2_I2C;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[1].i2c_addr = val;
-       }
-
-       for (i = 0; i < state->dual_mode + 1; i++) {
-               if (i == 1)
-                       offset = AF9015_EEPROM_OFFSET;
-               /* xtal */
-               req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               switch (val) {
-               case 0:
-                       state->af9013_config[i].clock = 28800000;
-                       break;
-               case 1:
-                       state->af9013_config[i].clock = 20480000;
-                       break;
-               case 2:
-                       state->af9013_config[i].clock = 28000000;
-                       break;
-               case 3:
-                       state->af9013_config[i].clock = 25000000;
-                       break;
-               };
-               deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
-                               val, state->af9013_config[i].clock);
-
-               /* IF frequency */
-               req.addr = AF9015_EEPROM_IF1H + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[i].if_frequency = val << 8;
-
-               req.addr = AF9015_EEPROM_IF1L + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[i].if_frequency += val;
-               state->af9013_config[i].if_frequency *= 1000;
-               deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
-                               state->af9013_config[i].if_frequency);
-
-               /* MT2060 IF1 */
-               req.addr = AF9015_EEPROM_MT2060_IF1H  + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               state->mt2060_if1[i] = val << 8;
-               req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               state->mt2060_if1[i] += val;
-               deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
-                               state->mt2060_if1[i]);
-
-               /* tuner */
-               req.addr =  AF9015_EEPROM_TUNER_ID1 + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               switch (val) {
-               case AF9013_TUNER_ENV77H11D5:
-               case AF9013_TUNER_MT2060:
-               case AF9013_TUNER_QT1010:
-               case AF9013_TUNER_UNKNOWN:
-               case AF9013_TUNER_MT2060_2:
-               case AF9013_TUNER_TDA18271:
-               case AF9013_TUNER_QT1010A:
-               case AF9013_TUNER_TDA18218:
-                       state->af9013_config[i].spec_inv = 1;
-                       break;
-               case AF9013_TUNER_MXL5003D:
-               case AF9013_TUNER_MXL5005D:
-               case AF9013_TUNER_MXL5005R:
-               case AF9013_TUNER_MXL5007T:
-                       state->af9013_config[i].spec_inv = 0;
-                       break;
-               case AF9013_TUNER_MC44S803:
-                       state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
-                       state->af9013_config[i].spec_inv = 1;
-                       break;
-               default:
-                       warn("tuner id=%d not supported, please report!", val);
-                       return -ENODEV;
-               };
-
-               state->af9013_config[i].tuner = val;
-               deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
-       }
-
-error:
-       if (ret)
-               err("eeprom read failed=%d", ret);
-
-       /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
-          content :-( Override some wrong values here. Ditto for the
-          AVerTV Red HD+ (A850T) device. */
-       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
-               ((le16_to_cpu(d->udev->descriptor.idProduct) ==
-                       USB_PID_AVERMEDIA_A850) ||
-               (le16_to_cpu(d->udev->descriptor.idProduct) ==
-                       USB_PID_AVERMEDIA_A850T))) {
-               deb_info("%s: AverMedia A850: overriding config\n", __func__);
-               /* disable dual mode */
-               state->dual_mode = 0;
-
-               /* set correct IF */
-               state->af9013_config[0].if_frequency = 4570000;
-       }
-
-       return ret;
-}
-
-static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
-
-       if (fe_to_d(fe)->udev->speed == USB_SPEED_FULL)
-               stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
-
-       return 0;
-}
-
-static int af9015_get_adapter_count(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       return state->dual_mode + 1;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->set_frontend[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_read_status(struct dvb_frontend *fe,
-       fe_status_t *status)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->read_status[fe_to_adap(fe)->id](fe, status);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->init[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->sleep[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->tuner_init[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-static int af9015_copy_firmware(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 fw_params[4];
-       u8 val, i;
-       struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
-               fw_params };
-       deb_info("%s:\n", __func__);
-
-       fw_params[0] = state->firmware_size >> 8;
-       fw_params[1] = state->firmware_size & 0xff;
-       fw_params[2] = state->firmware_checksum >> 8;
-       fw_params[3] = state->firmware_checksum & 0xff;
-
-       /* wait 2nd demodulator ready */
-       msleep(100);
-
-       ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                       0x98be, &val);
-       if (ret)
-               goto error;
-       else
-               deb_info("%s: firmware status:%02x\n", __func__, val);
-
-       if (val == 0x0c) /* fw is running, no need for download */
-               goto exit;
-
-       /* set I2C master clock to fast (to speed up firmware copy) */
-       ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
-       if (ret)
-               goto error;
-
-       msleep(50);
-
-       /* copy firmware */
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               err("firmware copy cmd failed:%d", ret);
-       deb_info("%s: firmware copy done\n", __func__);
-
-       /* set I2C master clock back to normal */
-       ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
-       if (ret)
-               goto error;
-
-       /* request boot firmware */
-       ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                       0xe205, 1);
-       deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
-       if (ret)
-               goto error;
-
-       for (i = 0; i < 15; i++) {
-               msleep(100);
-
-               /* check firmware status */
-               ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                               0x98be, &val);
-               deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
-                       __func__, ret, val);
-               if (ret)
-                       goto error;
-
-               if (val == 0x0c || val == 0x04) /* success or fail */
-                       break;
-       }
-
-       if (val == 0x04) {
-               err("firmware did not run");
-               ret = -1;
-       } else if (val != 0x0c) {
-               err("firmware boot timeout");
-               ret = -1;
-       }
-
-error:
-exit:
-       return ret;
-}
-
-static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct af9015_state *state = adap_to_priv(adap);
-
-       if (adap->id == 0) {
-               state->af9013_config[0].ts_mode = AF9013_TS_USB;
-               memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
-               state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
-               state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
-       } else if (adap->id == 1) {
-               state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
-               memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
-               state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
-               state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
-
-               /* copy firmware to 2nd demodulator */
-               if (state->dual_mode) {
-                       ret = af9015_copy_firmware(adap_to_d(adap));
-                       if (ret) {
-                               err("firmware copy to 2nd frontend " \
-                                       "failed, will disable it");
-                               state->dual_mode = 0;
-                               return -ENODEV;
-                       }
-               } else {
-                       return -ENODEV;
-               }
-       }
-
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(af9013_attach,
-               &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
-
-       /*
-        * AF9015 firmware does not like if it gets interrupted by I2C adapter
-        * request on some critical phases. During normal operation I2C adapter
-        * is used only 2nd demodulator and tuner on dual tuner devices.
-        * Override demodulator callbacks and use mutex for limit access to
-        * those "critical" paths to keep AF9015 happy.
-        */
-       if (adap->fe[0]) {
-               state->set_frontend[adap->id] =
-                       adap->fe[0]->ops.set_frontend;
-               adap->fe[0]->ops.set_frontend =
-                       af9015_af9013_set_frontend;
-
-               state->read_status[adap->id] =
-                       adap->fe[0]->ops.read_status;
-               adap->fe[0]->ops.read_status =
-                       af9015_af9013_read_status;
-
-               state->init[adap->id] = adap->fe[0]->ops.init;
-               adap->fe[0]->ops.init = af9015_af9013_init;
-
-               state->sleep[adap->id] = adap->fe[0]->ops.sleep;
-               adap->fe[0]->ops.sleep = af9015_af9013_sleep;
-       }
-
-       return adap->fe[0] == NULL ? -ENODEV : 0;
-}
-
-static struct mt2060_config af9015_mt2060_config = {
-       .i2c_address = 0xc0,
-       .clock_out = 0,
-};
-
-static struct qt1010_config af9015_qt1010_config = {
-       .i2c_address = 0xc4,
-};
-
-static struct tda18271_config af9015_tda18271_config = {
-       .gate = TDA18271_GATE_DIGITAL,
-       .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
-};
-
-static struct mxl5005s_config af9015_mxl5003_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_DEFAULT,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static struct mxl5005s_config af9015_mxl5005_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_OFF,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static struct mc44s803_config af9015_mc44s803_config = {
-       .i2c_address = 0xc0,
-       .dig_out = 1,
-};
-
-static struct tda18218_config af9015_tda18218_config = {
-       .i2c_address = 0xc0,
-       .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
-};
-
-static struct mxl5007t_config af9015_mxl5007t_config = {
-       .xtal_freq_hz = MxL_XTAL_24_MHZ,
-       .if_freq_hz = MxL_IF_4_57_MHZ,
-};
-
-static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct af9015_state *state = adap_to_priv(adap);
-       int ret;
-       deb_info("%s:\n", __func__);
-
-       switch (state->af9013_config[adap->id].tuner) {
-       case AF9013_TUNER_MT2060:
-       case AF9013_TUNER_MT2060_2:
-               ret = dvb_attach(mt2060_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
-                       state->mt2060_if1[adap->id])
-                       == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_QT1010:
-       case AF9013_TUNER_QT1010A:
-               ret = dvb_attach(qt1010_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_qt1010_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_TDA18271:
-               ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_tda18271_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_TDA18218:
-               ret = dvb_attach(tda18218_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_tda18218_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5003D:
-               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5005D:
-       case AF9013_TUNER_MXL5005R:
-               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_ENV77H11D5:
-               ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
-                       &adap_to_d(adap)->i2c_adap,
-                       DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MC44S803:
-               ret = dvb_attach(mc44s803_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5007T:
-               ret = dvb_attach(mxl5007t_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_UNKNOWN:
-       default:
-               ret = -ENODEV;
-               err("Unknown tuner id:%d",
-                       state->af9013_config[adap->id].tuner);
-       }
-
-       if (adap->fe[0]->ops.tuner_ops.init) {
-               state->tuner_init[adap->id] =
-                       adap->fe[0]->ops.tuner_ops.init;
-               adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
-       }
-
-       if (adap->fe[0]->ops.tuner_ops.sleep) {
-               state->tuner_sleep[adap->id] =
-                       adap->fe[0]->ops.tuner_ops.sleep;
-               adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
-       }
-
-       return ret;
-}
-
-static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-       deb_info("%s: onoff:%d\n", __func__, onoff);
-
-       if (onoff)
-               ret = af9015_set_reg_bit(adap_to_d(adap), 0xd503, 0);
-       else
-               ret = af9015_clear_reg_bit(adap_to_d(adap), 0xd503, 0);
-
-       return ret;
-}
-
-static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-       int onoff)
-{
-       int ret;
-       u8 idx;
-
-       deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
-               __func__, index, pid, onoff);
-
-       ret = af9015_write_reg(adap_to_d(adap), 0xd505, (pid & 0xff));
-       if (ret)
-               goto error;
-
-       ret = af9015_write_reg(adap_to_d(adap), 0xd506, (pid >> 8));
-       if (ret)
-               goto error;
-
-       idx = ((index & 0x1f) | (1 << 5));
-       ret = af9015_write_reg(adap_to_d(adap), 0xd504, idx);
-
-error:
-       return ret;
-}
-
-static int af9015_init_endpoint(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u16 frame_size;
-       u8  packet_size;
-       deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
-
-       if (d->udev->speed == USB_SPEED_FULL) {
-               frame_size = TS_USB11_FRAME_SIZE/4;
-               packet_size = TS_USB11_MAX_PACKET_SIZE/4;
-       } else {
-               frame_size = TS_USB20_FRAME_SIZE/4;
-               packet_size = TS_USB20_MAX_PACKET_SIZE/4;
-       }
-
-       ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
-       if (ret)
-               goto error;
-       ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
-       if (ret)
-               goto error;
-       ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
-               if (ret)
-                       goto error;
-       }
-       ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
-               if (ret)
-                       goto error;
-       }
-       /* EP4 xfer length */
-       ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
-       if (ret)
-               goto error;
-       /* EP5 xfer length */
-       ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
-               if (ret)
-                       goto error;
-       }
-
-       /* enable / disable mp2if2 */
-       if (state->dual_mode)
-               ret = af9015_set_reg_bit(d, 0xd50b, 0);
-       else
-               ret = af9015_clear_reg_bit(d, 0xd50b, 0);
-
-error:
-       if (ret)
-               err("endpoint init failed:%d", ret);
-       return ret;
-}
-
-static int af9015_init(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       deb_info("%s:\n", __func__);
-
-       mutex_init(&state->fe_mutex);
-
-       /* init RC canary */
-       ret = af9015_write_reg(d, 0x98e9, 0xff);
-       if (ret)
-               goto error;
-
-       ret = af9015_init_endpoint(d);
-       if (ret)
-               goto error;
-
-error:
-       return ret;
-}
-
-struct af9015_rc_setup {
-       unsigned int id;
-       char *rc_codes;
-};
-
-static char *af9015_rc_setup_match(unsigned int id,
-       const struct af9015_rc_setup *table)
-{
-       for (; table->rc_codes; table++)
-               if (table->id == id)
-                       return table->rc_codes;
-       return NULL;
-}
-
-static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
-       { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
-       { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
-       { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
-       { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
-       { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
-       { }
-};
-
-static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
-       { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
-       { 0xa3703d00, RC_MAP_ALINK_DTU_M },
-       { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
-       { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
-       { }
-};
-
-static int af9015_rc_query(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 buf[17];
-
-       deb_info("%s:\n", __func__);
-
-       /* read registers needed to detect remote controller code */
-       ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       /* If any of these are non-zero, assume invalid data */
-       if (buf[1] || buf[2] || buf[3])
-               return ret;
-
-       /* Check for repeat of previous code */
-       if ((state->rc_repeat != buf[6] || buf[0]) &&
-                       !memcmp(&buf[12], state->rc_last, 4)) {
-               deb_rc("%s: key repeated\n", __func__);
-               rc_keydown(d->rc_dev, state->rc_keycode, 0);
-               state->rc_repeat = buf[6];
-               return ret;
-       }
-
-       /* Only process key if canary killed */
-       if (buf[16] != 0xff && buf[0] != 0x01) {
-               deb_rc("%s: key pressed %*ph\n", __func__, 4, buf + 12);
-
-               /* Reset the canary */
-               ret = af9015_write_reg(d, 0x98e9, 0xff);
-               if (ret)
-                       goto error;
-
-               /* Remember this key */
-               memcpy(state->rc_last, &buf[12], 4);
-               if (buf[14] == (u8) ~buf[15]) {
-                       if (buf[12] == (u8) ~buf[13]) {
-                               /* NEC */
-                               state->rc_keycode = buf[12] << 8 | buf[14];
-                       } else {
-                               /* NEC extended*/
-                               state->rc_keycode = buf[12] << 16 |
-                                       buf[13] << 8 | buf[14];
-                       }
-               } else {
-                       /* 32 bit NEC */
-                       state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
-                                       buf[14] << 8 | buf[15];
-               }
-               rc_keydown(d->rc_dev, state->rc_keycode, 0);
-       } else {
-               deb_rc("%s: no key press\n", __func__);
-               /* Invalidate last keypress */
-               /* Not really needed, but helps with debug */
-               state->rc_last[2] = state->rc_last[3];
-       }
-
-       state->rc_repeat = buf[6];
-       state->rc_failed = false;
-
-error:
-       if (ret) {
-               err("%s: failed:%d", __func__, ret);
-
-               /* allow random errors as dvb-usb will stop polling on error */
-               if (!state->rc_failed)
-                       ret = 0;
-
-               state->rc_failed = true;
-       }
-
-       return ret;
-}
-
-static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       struct af9015_state *state = d_to_priv(d);
-       u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
-
-       if (state->ir_mode == AF9015_IR_MODE_DISABLED)
-               return 0;
-
-       /* try to load remote based module param */
-       if (!rc->map_name)
-               rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
-                               af9015_rc_setup_modparam);
-
-       /* try to load remote based eeprom hash */
-       if (!rc->map_name)
-               rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
-                               af9015_rc_setup_hashes);
-
-       /* try to load remote based USB iManufacturer string */
-       if (!rc->map_name && vid == USB_VID_AFATECH) {
-               /* Check USB manufacturer and product strings and try
-                  to determine correct remote in case of chip vendor
-                  reference IDs are used.
-                  DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
-               char manufacturer[10];
-               memset(manufacturer, 0, sizeof(manufacturer));
-               usb_string(d->udev, d->udev->descriptor.iManufacturer,
-                       manufacturer, sizeof(manufacturer));
-               if (!strcmp("MSI", manufacturer)) {
-                       /* iManufacturer 1 MSI
-                          iProduct      2 MSI K-VOX */
-                       rc->map_name = af9015_rc_setup_match(
-                                       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
-                                       af9015_rc_setup_modparam);
-               }
-       }
-
-       /* load empty to enable rc */
-       if (!rc->map_name)
-               rc->map_name = RC_MAP_EMPTY;
-
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query = af9015_rc_query;
-       rc->interval = 500;
-
-       return 0;
-}
-
-/* interface 0 is used by DVB-T receiver and
-   interface 1 is for remote controller (HID) */
-static struct dvb_usb_device_properties af9015_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct af9015_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9015_identify_state,
-       .firmware = "dvb-usb-af9015.fw",
-       .download_firmware = af9015_download_firmware,
-
-       .i2c_algo = &af9015_i2c_algo,
-       .read_config = af9015_read_config,
-       .frontend_attach = af9015_af9013_frontend_attach,
-       .tuner_attach = af9015_tuner_attach,
-       .init = af9015_init,
-       .get_rc_config = af9015_get_rc_config,
-       .get_stream_config = af9015_get_stream_config,
-
-       .get_adapter_count = af9015_get_adapter_count,
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = af9015_pid_filter,
-                       .pid_filter_ctrl = af9015_pid_filter_ctrl,
-
-                       .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
-               },
-       },
-};
-
-static const struct usb_device_id af9015_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
-               &af9015_props, "Afatech AF9015 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
-               &af9015_props, "Afatech AF9015 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
-               &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
-       { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
-               &af9015_props, "Pinnacle PCTV 71e", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
-               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
-               &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
-       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
-               &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
-               &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
-               &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
-               &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
-       { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
-               &af9015_props, "Xtensions XD-380", NULL) },
-       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
-               &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
-               &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TELESTAR,  USB_PID_TELESTAR_STARSTICK_2,
-               &af9015_props, "Telestar Starstick 2", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
-               &af9015_props, "AVerMedia A309", NULL) },
-       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
-               &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
-               &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
-               &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
-               &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
-               &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
-               &af9015_props, "KWorld Digial MC-810", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
-               &af9015_props, "Genius TVGo DVB-T03", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
-               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
-               &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
-               &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
-               &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
-       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
-               &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
-               &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
-               &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
-               &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
-               &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
-               &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
-               &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
-               &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, af9015_id_table);
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver af9015_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = af9015_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(af9015_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9015 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/af9015.h b/drivers/media/dvb/dvb-usb-v2/af9015.h
deleted file mode 100644 (file)
index c6b304d..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- *    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 AF9015_H
-#define AF9015_H
-
-#include <linux/hash.h>
-#include "dvb_usb.h"
-#include "af9013.h"
-#include "dvb-pll.h"
-#include "mt2060.h"
-#include "qt1010.h"
-#include "tda18271.h"
-#include "mxl5005s.h"
-#include "mc44s803.h"
-#include "tda18218.h"
-#include "mxl5007t.h"
-
-#define DVB_USB_LOG_PREFIX "af9015"
-
-#ifdef CONFIG_DVB_USB_DEBUG
-#define dprintk(var, level, args...) \
-       do { if ((var & level)) printk(args); } while (0)
-#define DVB_USB_DEBUG_STATUS
-#else
-#define dprintk(args...)
-#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
-#endif
-
-#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
-#define deb_rc(args...)   dprintk(dvb_usb_af9015_debug, 0x02, args)
-
-#undef err
-#define err(format, arg...) \
-       printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) \
-       printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-
-/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
-   We use smaller - about 1/4 from the original, 5 and 87. */
-#define TS_PACKET_SIZE            188
-
-#define TS_USB20_PACKET_COUNT      87
-#define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
-
-#define TS_USB11_PACKET_COUNT       5
-#define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
-
-#define TS_USB20_MAX_PACKET_SIZE  512
-#define TS_USB11_MAX_PACKET_SIZE   64
-
-#define AF9015_I2C_EEPROM  0xa0
-#define AF9015_I2C_DEMOD   0x38
-#define AF9015_USB_TIMEOUT 2000
-
-/* EEPROM locations */
-#define AF9015_EEPROM_IR_MODE        0x18
-#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
-#define AF9015_EEPROM_TS_MODE        0x31
-#define AF9015_EEPROM_DEMOD2_I2C     0x32
-
-#define AF9015_EEPROM_SAW_BW1        0x35
-#define AF9015_EEPROM_XTAL_TYPE1     0x36
-#define AF9015_EEPROM_SPEC_INV1      0x37
-#define AF9015_EEPROM_IF1L           0x38
-#define AF9015_EEPROM_IF1H           0x39
-#define AF9015_EEPROM_MT2060_IF1L    0x3a
-#define AF9015_EEPROM_MT2060_IF1H    0x3b
-#define AF9015_EEPROM_TUNER_ID1      0x3c
-
-#define AF9015_EEPROM_SAW_BW2        0x45
-#define AF9015_EEPROM_XTAL_TYPE2     0x46
-#define AF9015_EEPROM_SPEC_INV2      0x47
-#define AF9015_EEPROM_IF2L           0x48
-#define AF9015_EEPROM_IF2H           0x49
-#define AF9015_EEPROM_MT2060_IF2L    0x4a
-#define AF9015_EEPROM_MT2060_IF2H    0x4b
-#define AF9015_EEPROM_TUNER_ID2      0x4c
-
-#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
-
-struct req_t {
-       u8  cmd;       /* [0] */
-       /*  seq */     /* [1] */
-       u8  i2c_addr;  /* [2] */
-       u16 addr;      /* [3|4] */
-       u8  mbox;      /* [5] */
-       u8  addr_len;  /* [6] */
-       u8  data_len;  /* [7] */
-       u8  *data;
-};
-
-enum af9015_cmd {
-       GET_CONFIG           = 0x10,
-       DOWNLOAD_FIRMWARE    = 0x11,
-       BOOT                 = 0x13,
-       READ_MEMORY          = 0x20,
-       WRITE_MEMORY         = 0x21,
-       READ_WRITE_I2C       = 0x22,
-       COPY_FIRMWARE        = 0x23,
-       RECONNECT_USB        = 0x5a,
-       WRITE_VIRTUAL_MEMORY = 0x26,
-       GET_IR_CODE          = 0x27,
-       READ_I2C,
-       WRITE_I2C,
-};
-
-enum af9015_ir_mode {
-       AF9015_IR_MODE_DISABLED = 0,
-       AF9015_IR_MODE_HID,
-       AF9015_IR_MODE_RLC,
-       AF9015_IR_MODE_RC6,
-       AF9015_IR_MODE_POLLING, /* just guess */
-};
-
-struct af9015_state {
-       u8 ir_mode;
-       u8 rc_repeat;
-       u32 rc_keycode;
-       u8 rc_last[4];
-       bool rc_failed;
-       u8 dual_mode;
-       u8 seq; /* packet sequence number */
-       u16 mt2060_if1[2];
-       u16 firmware_size;
-       u16 firmware_checksum;
-       u32 eeprom_sum;
-       struct af9013_config af9013_config[2];
-
-       /* for demod callback override */
-       int (*set_frontend[2]) (struct dvb_frontend *fe);
-       int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
-       int (*init[2]) (struct dvb_frontend *fe);
-       int (*sleep[2]) (struct dvb_frontend *fe);
-       int (*tuner_init[2]) (struct dvb_frontend *fe);
-       int (*tuner_sleep[2]) (struct dvb_frontend *fe);
-       struct mutex fe_mutex;
-};
-
-enum af9015_remote {
-       AF9015_REMOTE_NONE                    = 0,
-/* 1 */        AF9015_REMOTE_A_LINK_DTU_M,
-       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
-       AF9015_REMOTE_MYGICTV_U718,
-       AF9015_REMOTE_DIGITTRADE_DVB_T,
-/* 5 */        AF9015_REMOTE_AVERMEDIA_KS,
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/af9035.c b/drivers/media/dvb/dvb-usb-v2/af9035.c
deleted file mode 100644 (file)
index bb90b87..0000000
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * Afatech AF9035 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "af9035.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static u16 af9035_checksum(const u8 *buf, size_t len)
-{
-       size_t i;
-       u16 checksum = 0;
-
-       for (i = 1; i < len; i++) {
-               if (i % 2)
-                       checksum += buf[i] << 8;
-               else
-                       checksum += buf[i];
-       }
-       checksum = ~checksum;
-
-       return checksum;
-}
-
-static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
-{
-#define BUF_LEN 64
-#define REQ_HDR_LEN 4 /* send header size */
-#define ACK_HDR_LEN 3 /* rece header size */
-#define CHECKSUM_LEN 2
-#define USB_TIMEOUT 2000
-       struct state *state = d_to_priv(d);
-       int ret, wlen, rlen;
-       u8 buf[BUF_LEN];
-       u16 checksum, tmp_checksum;
-
-       /* buffer overflow check */
-       if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
-               req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
-               pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
-                               req->wlen, req->rlen);
-               return -EINVAL;
-       }
-
-       buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
-       buf[1] = req->mbox;
-       buf[2] = req->cmd;
-       buf[3] = state->seq++;
-       memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
-
-       wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
-       rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
-
-       /* calc and add checksum */
-       checksum = af9035_checksum(buf, buf[0] - 1);
-       buf[buf[0] - 1] = (checksum >> 8);
-       buf[buf[0] - 0] = (checksum & 0xff);
-
-       /* no ack for these packets */
-       if (req->cmd == CMD_FW_DL)
-               rlen = 0;
-
-       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
-       if (ret)
-               goto err;
-
-       /* no ack for those packets */
-       if (req->cmd == CMD_FW_DL)
-               goto exit;
-
-       /* verify checksum */
-       checksum = af9035_checksum(buf, rlen - 2);
-       tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
-       if (tmp_checksum != checksum) {
-               pr_err("%s: command=%02x checksum mismatch (%04x != %04x)\n",
-                               KBUILD_MODNAME, req->cmd, tmp_checksum,
-                               checksum);
-               ret = -EIO;
-               goto err;
-       }
-
-       /* check status */
-       if (buf[2]) {
-               pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
-                               req->cmd, buf[2]);
-               ret = -EIO;
-               goto err;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (req->rlen)
-               memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
-
-exit:
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-/* write multiple registers */
-static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
-{
-       u8 wbuf[6 + len];
-       u8 mbox = (reg >> 16) & 0xff;
-       struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
-
-       wbuf[0] = len;
-       wbuf[1] = 2;
-       wbuf[2] = 0;
-       wbuf[3] = 0;
-       wbuf[4] = (reg >> 8) & 0xff;
-       wbuf[5] = (reg >> 0) & 0xff;
-       memcpy(&wbuf[6], val, len);
-
-       return af9035_ctrl_msg(d, &req);
-}
-
-/* read multiple registers */
-static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
-{
-       u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
-       u8 mbox = (reg >> 16) & 0xff;
-       struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
-
-       return af9035_ctrl_msg(d, &req);
-}
-
-/* write single register */
-static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
-{
-       return af9035_wr_regs(d, reg, &val, 1);
-}
-
-/* read single register */
-static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
-{
-       return af9035_rd_regs(d, reg, val, 1);
-}
-
-/* write single register with mask */
-static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
-               u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = af9035_rd_regs(d, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return af9035_wr_regs(d, reg, &val, 1);
-}
-
-static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct state *state = d_to_priv(d);
-       int ret;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       /*
-        * I2C sub header is 5 bytes long. Meaning of those bytes are:
-        * 0: data len
-        * 1: I2C addr << 1
-        * 2: reg addr len
-        *    byte 3 and 4 can be used as reg addr
-        * 3: reg addr MSB
-        *    used when reg addr len is set to 2
-        * 4: reg addr LSB
-        *    used when reg addr len is set to 1 or 2
-        *
-        * For the simplify we do not use register addr at all.
-        * NOTE: As a firmware knows tuner type there is very small possibility
-        * there could be some tuner I2C hacks done by firmware and this may
-        * lead problems if firmware expects those bytes are used.
-        */
-       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
-                       (msg[1].flags & I2C_M_RD)) {
-               if (msg[0].len > 40 || msg[1].len > 40) {
-                       /* TODO: correct limits > 40 */
-                       ret = -EOPNOTSUPP;
-               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
-                       /* integrated demod */
-                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-                                       msg[0].buf[2];
-                       ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
-                                       msg[1].len);
-               } else {
-                       /* I2C */
-                       u8 buf[5 + msg[0].len];
-                       struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
-                                       buf, msg[1].len, msg[1].buf };
-                       buf[0] = msg[1].len;
-                       buf[1] = msg[0].addr << 1;
-                       buf[2] = 0x00; /* reg addr len */
-                       buf[3] = 0x00; /* reg addr MSB */
-                       buf[4] = 0x00; /* reg addr LSB */
-                       memcpy(&buf[5], msg[0].buf, msg[0].len);
-                       ret = af9035_ctrl_msg(d, &req);
-               }
-       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
-               if (msg[0].len > 40) {
-                       /* TODO: correct limits > 40 */
-                       ret = -EOPNOTSUPP;
-               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
-                       /* integrated demod */
-                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-                                       msg[0].buf[2];
-                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
-                                       msg[0].len - 3);
-               } else {
-                       /* I2C */
-                       u8 buf[5 + msg[0].len];
-                       struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
-                                       0, NULL };
-                       buf[0] = msg[0].len;
-                       buf[1] = msg[0].addr << 1;
-                       buf[2] = 0x00; /* reg addr len */
-                       buf[3] = 0x00; /* reg addr MSB */
-                       buf[4] = 0x00; /* reg addr LSB */
-                       memcpy(&buf[5], msg[0].buf, msg[0].len);
-                       ret = af9035_ctrl_msg(d, &req);
-               }
-       } else {
-               /*
-                * We support only two kind of I2C transactions:
-                * 1) 1 x read + 1 x write
-                * 2) 1 x write
-                */
-               ret = -EOPNOTSUPP;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       if (ret < 0)
-               return ret;
-       else
-               return num;
-}
-
-static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9035_i2c_algo = {
-       .master_xfer = af9035_i2c_master_xfer,
-       .functionality = af9035_i2c_functionality,
-};
-
-static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 wbuf[1] = { 1 };
-       u8 rbuf[4];
-       struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
-                       sizeof(rbuf), rbuf };
-
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       pr_debug("%s: reply=%*ph\n", __func__, 4, rbuf);
-       if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_download_firmware(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, i, j, len;
-       u8 wbuf[1];
-       u8 rbuf[4];
-       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
-       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
-       u8 hdr_core;
-       u16 hdr_addr, hdr_data_len, hdr_checksum;
-       #define MAX_DATA 58
-       #define HDR_SIZE 7
-
-       /*
-        * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
-        *
-        * byte 0: MCS 51 core
-        *  There are two inside the AF9035 (1=Link and 2=OFDM) with separate
-        *  address spaces
-        * byte 1-2: Big endian destination address
-        * byte 3-4: Big endian number of data bytes following the header
-        * byte 5-6: Big endian header checksum, apparently ignored by the chip
-        *  Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
-        */
-
-       for (i = fw->size; i > HDR_SIZE;) {
-               hdr_core = fw->data[fw->size - i + 0];
-               hdr_addr = fw->data[fw->size - i + 1] << 8;
-               hdr_addr |= fw->data[fw->size - i + 2] << 0;
-               hdr_data_len = fw->data[fw->size - i + 3] << 8;
-               hdr_data_len |= fw->data[fw->size - i + 4] << 0;
-               hdr_checksum = fw->data[fw->size - i + 5] << 8;
-               hdr_checksum |= fw->data[fw->size - i + 6] << 0;
-
-               pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
-                               __func__, hdr_core, hdr_addr, hdr_data_len,
-                               hdr_checksum);
-
-               if (((hdr_core != 1) && (hdr_core != 2)) ||
-                               (hdr_data_len > i)) {
-                       pr_debug("%s: bad firmware\n", __func__);
-                       break;
-               }
-
-               /* download begin packet */
-               req.cmd = CMD_FW_DL_BEGIN;
-               ret = af9035_ctrl_msg(d, &req);
-               if (ret < 0)
-                       goto err;
-
-               /* download firmware packet(s) */
-               for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
-                       len = j;
-                       if (len > MAX_DATA)
-                               len = MAX_DATA;
-                       req_fw_dl.wlen = len;
-                       req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
-                                       HDR_SIZE + hdr_data_len - j];
-                       ret = af9035_ctrl_msg(d, &req_fw_dl);
-                       if (ret < 0)
-                               goto err;
-               }
-
-               /* download end packet */
-               req.cmd = CMD_FW_DL_END;
-               ret = af9035_ctrl_msg(d, &req);
-               if (ret < 0)
-                       goto err;
-
-               i -= hdr_data_len + HDR_SIZE;
-
-               pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = CMD_FW_BOOT;
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       /* ensure firmware starts */
-       wbuf[0] = 1;
-       ret = af9035_ctrl_msg(d, &req_fw_ver);
-       if (ret < 0)
-               goto err;
-
-       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
-               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
-                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, i, i_prev;
-       u8 wbuf[1];
-       u8 rbuf[4];
-       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
-       #define HDR_SIZE 7
-
-       /*
-        * There seems to be following firmware header. Meaning of bytes 0-3
-        * is unknown.
-        *
-        * 0: 3
-        * 1: 0, 1
-        * 2: 0
-        * 3: 1, 2, 3
-        * 4: addr MSB
-        * 5: addr LSB
-        * 6: count of data bytes ?
-        */
-
-       for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
-               if (i == fw->size ||
-                               (fw->data[i + 0] == 0x03 &&
-                               (fw->data[i + 1] == 0x00 ||
-                               fw->data[i + 1] == 0x01) &&
-                               fw->data[i + 2] == 0x00)) {
-                       req_fw_dl.wlen = i - i_prev;
-                       req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
-                       i_prev = i;
-                       ret = af9035_ctrl_msg(d, &req_fw_dl);
-                       if (ret < 0)
-                               goto err;
-
-                       pr_debug("%s: data uploaded=%d\n", __func__, i);
-               }
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = CMD_FW_BOOT;
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       /* ensure firmware starts */
-       wbuf[0] = 1;
-       ret = af9035_ctrl_msg(d, &req_fw_ver);
-       if (ret < 0)
-               goto err;
-
-       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
-               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
-                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_read_config(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i, eeprom_shift = 0;
-       u8 tmp;
-       u16 tmp16;
-
-       /* check if there is dual tuners */
-       ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
-       if (ret < 0)
-               goto err;
-
-       state->dual_mode = tmp;
-       pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
-
-       for (i = 0; i < state->dual_mode + 1; i++) {
-               /* tuner */
-               ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               state->af9033_config[i].tuner = tmp;
-               pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
-
-               switch (tmp) {
-               case AF9033_TUNER_TUA9001:
-               case AF9033_TUNER_FC0011:
-               case AF9033_TUNER_MXL5007T:
-               case AF9033_TUNER_TDA18218:
-                       state->af9033_config[i].spec_inv = 1;
-                       break;
-               default:
-                       pr_info("%s: tuner ID=%02x not supported, please " \
-                                       "report!", KBUILD_MODNAME, tmp);
-               };
-
-               /* tuner IF frequency */
-               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               tmp16 = tmp;
-
-               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               tmp16 |= tmp << 8;
-
-               pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
-
-               eeprom_shift = 0x10; /* shift for the 2nd tuner params */
-       }
-
-       /* get demod clock */
-       ret = af9035_rd_reg(d, 0x00d800, &tmp);
-       if (ret < 0)
-               goto err;
-
-       tmp = (tmp >> 0) & 0x0f;
-
-       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
-               state->af9033_config[i].clock = clock_lut[tmp];
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_read_config_it9135(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i;
-       u8 tmp;
-
-       state->dual_mode = false;
-
-       /* get demod clock */
-       ret = af9035_rd_reg(d, 0x00d800, &tmp);
-       if (ret < 0)
-               goto err;
-
-       tmp = (tmp >> 0) & 0x0f;
-
-       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
-               state->af9033_config[i].clock = clock_lut_it9135[tmp];
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
-               int cmd, int arg)
-{
-       int ret;
-
-       switch (cmd) {
-       case FC0011_FE_CALLBACK_POWER:
-               /* Tuner enable */
-               ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               /* LED */
-               ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 50000);
-               break;
-       case FC0011_FE_CALLBACK_RESET:
-               ret = af9035_wr_reg(d, 0xd8e9, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0xd8e8, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0xd8e7, 1);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 20000);
-
-               ret = af9035_wr_reg(d, 0xd8e7, 0);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 20000);
-               break;
-       default:
-               ret = -EINVAL;
-               goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
-{
-       struct state *state = d_to_priv(d);
-
-       switch (state->af9033_config[0].tuner) {
-       case AF9033_TUNER_FC0011:
-               return af9035_fc0011_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -ENODEV;
-}
-
-static int af9035_frontend_callback(void *adapter_priv, int component,
-                                   int cmd, int arg)
-{
-       struct i2c_adapter *adap = adapter_priv;
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
-       switch (component) {
-       case DVB_FRONTEND_COMPONENT_TUNER:
-               return af9035_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-
-       if (!state->af9033_config[adap->id].tuner) {
-               /* unsupported tuner */
-               ret = -ENODEV;
-               goto err;
-       }
-
-       if (adap->id == 0) {
-               state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
-               state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
-
-               ret = af9035_wr_reg(d, 0x00417f,
-                               state->af9033_config[1].i2c_addr);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0x00d81a,
-                               state->dual_mode);
-               if (ret < 0)
-                       goto err;
-       }
-
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(af9033_attach,
-                       &state->af9033_config[adap->id], &d->i2c_adap);
-       if (adap->fe[0] == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       /* disable I2C-gate */
-       adap->fe[0]->ops.i2c_gate_ctrl = NULL;
-       adap->fe[0]->callback = af9035_frontend_callback;
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static struct tua9001_config af9035_tua9001_config = {
-       .i2c_addr = 0x60,
-};
-
-static const struct fc0011_config af9035_fc0011_config = {
-       .i2c_address = 0x60,
-};
-
-static struct mxl5007t_config af9035_mxl5007t_config = {
-       .xtal_freq_hz = MxL_XTAL_24_MHZ,
-       .if_freq_hz = MxL_IF_4_57_MHZ,
-       .invert_if = 0,
-       .loop_thru_enable = 0,
-       .clk_out_enable = 0,
-       .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
-};
-
-static struct tda18218_config af9035_tda18218_config = {
-       .i2c_address = 0x60,
-       .i2c_wr_max = 21,
-};
-
-static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       struct dvb_frontend *fe;
-
-       switch (state->af9033_config[adap->id].tuner) {
-       case AF9033_TUNER_TUA9001:
-               /* AF9035 gpiot3 = TUA9001 RESETN
-                  AF9035 gpiot2 = TUA9001 RXEN */
-
-               /* configure gpiot2 and gpiot2 as output */
-               ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* reset tuner */
-               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(2000, 20000);
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* activate tuner RX */
-               /* TODO: use callback for TUA9001 RXEN */
-               ret = af9035_wr_reg_mask(d, 0x00d8eb, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* attach tuner */
-               fe = dvb_attach(tua9001_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_tua9001_config);
-               break;
-       case AF9033_TUNER_FC0011:
-               fe = dvb_attach(fc0011_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_fc0011_config);
-               break;
-       case AF9033_TUNER_MXL5007T:
-               ret = af9035_wr_reg(d, 0x00d8e0, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8e1, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8df, 0);
-               if (ret < 0)
-                       goto err;
-
-               msleep(30);
-
-               ret = af9035_wr_reg(d, 0x00d8df, 1);
-               if (ret < 0)
-                       goto err;
-
-               msleep(300);
-
-               ret = af9035_wr_reg(d, 0x00d8c0, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8c1, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8bf, 0);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b4, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b5, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b3, 1);
-               if (ret < 0)
-                       goto err;
-
-               /* attach tuner */
-               fe = dvb_attach(mxl5007t_attach, adap->fe[0],
-                               &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
-               break;
-       case AF9033_TUNER_TDA18218:
-               /* attach tuner */
-               fe = dvb_attach(tda18218_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_tda18218_config);
-               break;
-       default:
-               fe = NULL;
-       }
-
-       if (fe == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_init(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i;
-       u16 frame_size = 87 * 188 / 4;
-       u8  packet_size = 512 / 4;
-       struct reg_val_mask tab[] = {
-               { 0x80f99d, 0x01, 0x01 },
-               { 0x80f9a4, 0x01, 0x01 },
-               { 0x00dd11, 0x00, 0x20 },
-               { 0x00dd11, 0x00, 0x40 },
-               { 0x00dd13, 0x00, 0x20 },
-               { 0x00dd13, 0x00, 0x40 },
-               { 0x00dd11, 0x20, 0x20 },
-               { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
-               { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
-               { 0x00dd0c, packet_size, 0xff},
-               { 0x00dd11, state->dual_mode << 6, 0x40 },
-               { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
-               { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
-               { 0x00dd0d, packet_size, 0xff },
-               { 0x80f9a3, 0x00, 0x01 },
-               { 0x80f9cd, 0x00, 0x01 },
-               { 0x80f99d, 0x00, 0x01 },
-               { 0x80f9a4, 0x00, 0x01 },
-       };
-
-       pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
-               __func__, d->udev->speed, frame_size, packet_size);
-
-       /* init endpoints */
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
-                               tab[i].mask);
-               if (ret < 0)
-                       goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_rc_query(struct dvb_usb_device *d)
-{
-       unsigned int key;
-       unsigned char b[4];
-       int ret;
-       struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
-
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       if ((b[2] + b[3]) == 0xff) {
-               if ((b[0] + b[1]) == 0xff) {
-                       /* NEC */
-                       key = b[0] << 8 | b[2];
-               } else {
-                       /* ext. NEC */
-                       key = b[0] << 16 | b[1] << 8 | b[2];
-               }
-       } else {
-               key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
-       }
-
-       rc_keydown(d->rc_dev, key, 0);
-
-err:
-       /* ignore errors */
-       return 0;
-}
-
-static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       int ret;
-       u8 tmp;
-
-       ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
-       if (ret < 0)
-               goto err;
-
-       pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
-
-       /* don't activate rc if in HID mode or if not available */
-       if (tmp == 5) {
-               ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               pr_debug("%s: ir_type=%02x\n", __func__, tmp);
-
-               switch (tmp) {
-               case 0: /* NEC */
-               default:
-                       rc->allowed_protos = RC_TYPE_NEC;
-                       break;
-               case 1: /* RC6 */
-                       rc->allowed_protos = RC_TYPE_RC6;
-                       break;
-               }
-
-               rc->query = af9035_rc_query;
-               rc->interval = 500;
-
-               /* load empty to enable rc */
-               if (!rc->map_name)
-                       rc->map_name = RC_MAP_EMPTY;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-/* interface 0 is used by DVB-T receiver and
-   interface 1 is for remote controller (HID) */
-static const struct dvb_usb_device_properties af9035_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9035_identify_state,
-       .firmware = "dvb-usb-af9035-02.fw",
-       .download_firmware = af9035_download_firmware,
-
-       .i2c_algo = &af9035_i2c_algo,
-       .read_config = af9035_read_config,
-       .frontend_attach = af9035_frontend_attach,
-       .tuner_attach = af9035_tuner_attach,
-       .init = af9035_init,
-       .get_rc_config = af9035_get_rc_config,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
-               },
-       },
-};
-
-static const struct dvb_usb_device_properties it9135_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9035_identify_state,
-       .firmware = "dvb-usb-it9135-01.fw",
-       .download_firmware = af9035_download_firmware_it9135,
-
-       .i2c_algo = &af9035_i2c_algo,
-       .read_config = af9035_read_config_it9135,
-       .frontend_attach = af9035_frontend_attach,
-       .tuner_attach = af9035_tuner_attach,
-       .init = af9035_init,
-       .get_rc_config = af9035_get_rc_config,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
-               },
-       },
-};
-
-static const struct usb_device_id af9035_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
-               &af9035_props, "TerraTec Cinergy T Stick", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
-               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
-               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
-               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
-               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
-               &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, af9035_id_table);
-
-static struct usb_driver af9035_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = af9035_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(af9035_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9035 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/af9035.h b/drivers/media/dvb/dvb-usb-v2/af9035.h
deleted file mode 100644 (file)
index 59ff69e..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Afatech AF9035 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef AF9035_H
-#define AF9035_H
-
-#include "dvb_usb.h"
-#include "af9033.h"
-#include "tua9001.h"
-#include "fc0011.h"
-#include "mxl5007t.h"
-#include "tda18218.h"
-
-struct reg_val {
-       u32 reg;
-       u8  val;
-};
-
-struct reg_val_mask {
-       u32 reg;
-       u8  val;
-       u8  mask;
-};
-
-struct usb_req {
-       u8  cmd;
-       u8  mbox;
-       u8  wlen;
-       u8  *wbuf;
-       u8  rlen;
-       u8  *rbuf;
-};
-
-struct state {
-       u8 seq; /* packet sequence number */
-       bool dual_mode;
-
-       struct af9033_config af9033_config[2];
-};
-
-u32 clock_lut[] = {
-       20480000, /*      FPGA */
-       16384000, /* 16.38 MHz */
-       20480000, /* 20.48 MHz */
-       36000000, /* 36.00 MHz */
-       30000000, /* 30.00 MHz */
-       26000000, /* 26.00 MHz */
-       28000000, /* 28.00 MHz */
-       32000000, /* 32.00 MHz */
-       34000000, /* 34.00 MHz */
-       24000000, /* 24.00 MHz */
-       22000000, /* 22.00 MHz */
-       12000000, /* 12.00 MHz */
-};
-
-u32 clock_lut_it9135[] = {
-       12000000, /* 12.00 MHz */
-       20480000, /* 20.48 MHz */
-       36000000, /* 36.00 MHz */
-       30000000, /* 30.00 MHz */
-       26000000, /* 26.00 MHz */
-       28000000, /* 28.00 MHz */
-       32000000, /* 32.00 MHz */
-       34000000, /* 34.00 MHz */
-       24000000, /* 24.00 MHz */
-       22000000, /* 22.00 MHz */
-};
-
-/* EEPROM locations */
-#define EEPROM_IR_MODE            0x430d
-#define EEPROM_DUAL_MODE          0x4326
-#define EEPROM_IR_TYPE            0x4329
-#define EEPROM_1_IFFREQ_L         0x432d
-#define EEPROM_1_IFFREQ_H         0x432e
-#define EEPROM_1_TUNER_ID         0x4331
-#define EEPROM_2_IFFREQ_L         0x433d
-#define EEPROM_2_IFFREQ_H         0x433e
-#define EEPROM_2_TUNER_ID         0x4341
-
-/* USB commands */
-#define CMD_MEM_RD                  0x00
-#define CMD_MEM_WR                  0x01
-#define CMD_I2C_RD                  0x02
-#define CMD_I2C_WR                  0x03
-#define CMD_IR_GET                  0x18
-#define CMD_FW_DL                   0x21
-#define CMD_FW_QUERYINFO            0x22
-#define CMD_FW_BOOT                 0x23
-#define CMD_FW_DL_BEGIN             0x24
-#define CMD_FW_DL_END               0x25
-#define CMD_FW_SCATTER_WR           0x29
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/anysee.c b/drivers/media/dvb/dvb-usb-v2/anysee.c
deleted file mode 100644 (file)
index fb3829a..0000000
+++ /dev/null
@@ -1,1324 +0,0 @@
-/*
- * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- *    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.
- *
- * TODO:
- * - add smart card reader support for Conditional Access (CA)
- *
- * Card reader in Anysee is nothing more than ISO 7816 card reader.
- * There is no hardware CAM in any Anysee device sold.
- * In my understanding it should be implemented by making own module
- * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
- * module registers serial interface that can be used to communicate
- * with any ISO 7816 smart card.
- *
- * Any help according to implement serial smart card reader support
- * is highly welcome!
- */
-
-#include "anysee.h"
-#include "dvb-pll.h"
-#include "tda1002x.h"
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "zl10353.h"
-#include "tda18212.h"
-#include "cx24116.h"
-#include "stv0900.h"
-#include "stv6110.h"
-#include "isl6423.h"
-#include "cxd2820r.h"
-
-/* debug */
-static int dvb_usb_anysee_debug;
-module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static DEFINE_MUTEX(anysee_usb_mutex);
-
-static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
-       u8 *rbuf, u8 rlen)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int act_len, ret, i;
-       u8 buf[64];
-
-       memcpy(&buf[0], sbuf, slen);
-       buf[60] = state->seq++;
-
-       mutex_lock(&anysee_usb_mutex);
-
-       deb_xfer(">>> ");
-       debug_dump(buf, slen, deb_xfer);
-
-       /* We need receive one message more after dvb_usb_generic_rw due
-          to weird transaction flow, which is 1 x send + 2 x receive. */
-       ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
-       if (ret)
-               goto error_unlock;
-
-       /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
-        * (EPIPE, Broken pipe). Function supports currently msleep() as a
-        * parameter but I would not like to use it, since according to
-        * Documentation/timers/timers-howto.txt it should not be used such
-        * short, under < 20ms, sleeps. Repeating failed message would be
-        * better choice as not to add unwanted delays...
-        * Fixing that correctly is one of those or both;
-        * 1) use repeat if possible
-        * 2) add suitable delay
-        */
-
-       /* get answer, retry few times if error returned */
-       for (i = 0; i < 3; i++) {
-               /* receive 2nd answer */
-               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
-                       d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
-                       &act_len, 2000);
-
-               if (ret) {
-                       deb_info("%s: recv bulk message failed: %d",
-                                       __func__, ret);
-               } else {
-                       deb_xfer("<<< ");
-                       debug_dump(buf, rlen, deb_xfer);
-
-                       if (buf[63] != 0x4f)
-                               deb_info("%s: cmd failed\n", __func__);
-
-                       break;
-               }
-       }
-
-       if (ret) {
-               /* all retries failed, it is fatal */
-               err("%s: recv bulk message failed: %d", __func__, ret);
-               goto error_unlock;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (rbuf && rlen)
-               memcpy(rbuf, buf, rlen);
-
-error_unlock:
-       mutex_unlock(&anysee_usb_mutex);
-
-       return ret;
-}
-
-static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
-{
-       u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
-       int ret;
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
-       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
-       return ret;
-}
-
-static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
-{
-       u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
-       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-/* write single register with mask */
-static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
-       u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = anysee_read_reg(d, reg, &tmp);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return anysee_write_reg(d, reg, val);
-}
-
-/* read single register with mask */
-static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
-       u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = anysee_read_reg(d, reg, &tmp);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
-{
-       u8 buf[] = {CMD_GET_HW_INFO};
-       return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
-}
-
-static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
-       deb_info("%s: onoff:%02x\n", __func__, onoff);
-       return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
-}
-
-static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
-{
-       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
-       deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
-{
-       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
-       deb_info("%s: onoff:%02x\n", __func__, onoff);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-/* I2C */
-static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int ret = 0, inc, i = 0;
-       u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].len > 2 || msg[i+1].len > 60) {
-                               ret = -EOPNOTSUPP;
-                               break;
-                       }
-                       buf[0] = CMD_I2C_READ;
-                       buf[1] = (msg[i].addr << 1) | 0x01;
-                       buf[2] = msg[i].buf[0];
-                       buf[3] = msg[i].buf[1];
-                       buf[4] = msg[i].len-1;
-                       buf[5] = msg[i+1].len;
-                       ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
-                               msg[i+1].len);
-                       inc = 2;
-               } else {
-                       if (msg[i].len > 48) {
-                               ret = -EOPNOTSUPP;
-                               break;
-                       }
-                       buf[0] = CMD_I2C_WRITE;
-                       buf[1] = (msg[i].addr << 1);
-                       buf[2] = msg[i].len;
-                       buf[3] = 0x01;
-                       memcpy(&buf[4], msg[i].buf, msg[i].len);
-                       ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
-                       inc = 1;
-               }
-               if (ret)
-                       break;
-
-               i += inc;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret ? ret : i;
-}
-
-static u32 anysee_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm anysee_i2c_algo = {
-       .master_xfer   = anysee_master_xfer,
-       .functionality = anysee_i2c_func,
-};
-
-static int anysee_mt352_demod_init(struct dvb_frontend *fe)
-{
-       static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
-       static u8 reset[]          = { RESET,      0x80 };
-       static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
-       static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
-       static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
-       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
-       mt352_write(fe, clock_config,   sizeof(clock_config));
-       udelay(200);
-       mt352_write(fe, reset,          sizeof(reset));
-       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
-
-       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
-       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
-       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
-       return 0;
-}
-
-/* Callbacks for DVB USB */
-static struct tda10023_config anysee_tda10023_config = {
-       .demod_address = (0x1a >> 1),
-       .invert = 0,
-       .xtal   = 16000000,
-       .pll_m  = 11,
-       .pll_p  = 3,
-       .pll_n  = 1,
-       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
-       .deltaf = 0xfeeb,
-};
-
-static struct mt352_config anysee_mt352_config = {
-       .demod_address = (0x1e >> 1),
-       .demod_init    = anysee_mt352_demod_init,
-};
-
-static struct zl10353_config anysee_zl10353_config = {
-       .demod_address = (0x1e >> 1),
-       .parallel_ts = 1,
-};
-
-static struct zl10353_config anysee_zl10353_tda18212_config2 = {
-       .demod_address = (0x1e >> 1),
-       .parallel_ts = 1,
-       .disable_i2c_gate_ctrl = 1,
-       .no_tuner = 1,
-       .if2 = 41500,
-};
-
-static struct zl10353_config anysee_zl10353_tda18212_config = {
-       .demod_address = (0x18 >> 1),
-       .parallel_ts = 1,
-       .disable_i2c_gate_ctrl = 1,
-       .no_tuner = 1,
-       .if2 = 41500,
-};
-
-static struct tda10023_config anysee_tda10023_tda18212_config = {
-       .demod_address = (0x1a >> 1),
-       .xtal   = 16000000,
-       .pll_m  = 12,
-       .pll_p  = 3,
-       .pll_n  = 1,
-       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
-       .deltaf = 0xba02,
-};
-
-static struct tda18212_config anysee_tda18212_config = {
-       .i2c_address = (0xc0 >> 1),
-       .if_dvbt_6 = 4150,
-       .if_dvbt_7 = 4150,
-       .if_dvbt_8 = 4150,
-       .if_dvbc = 5000,
-};
-
-static struct tda18212_config anysee_tda18212_config2 = {
-       .i2c_address = 0x60 /* (0xc0 >> 1) */,
-       .if_dvbt_6 = 3550,
-       .if_dvbt_7 = 3700,
-       .if_dvbt_8 = 4150,
-       .if_dvbt2_6 = 3250,
-       .if_dvbt2_7 = 4000,
-       .if_dvbt2_8 = 4000,
-       .if_dvbc = 5000,
-};
-
-static struct cx24116_config anysee_cx24116_config = {
-       .demod_address = (0xaa >> 1),
-       .mpg_clk_pos_pol = 0x00,
-       .i2c_wr_max = 48,
-};
-
-static struct stv0900_config anysee_stv0900_config = {
-       .demod_address = (0xd0 >> 1),
-       .demod_mode = 0,
-       .xtal = 8000000,
-       .clkmode = 3,
-       .diseqc_mode = 2,
-       .tun1_maddress = 0,
-       .tun1_adc = 1, /* 1 Vpp */
-       .path1_mode = 3,
-};
-
-static struct stv6110_config anysee_stv6110_config = {
-       .i2c_address = (0xc0 >> 1),
-       .mclk = 16000000,
-       .clk_div = 1,
-};
-
-static struct isl6423_config anysee_isl6423_config = {
-       .current_max = SEC_CURRENT_800m,
-       .curlim  = SEC_CURRENT_LIM_OFF,
-       .mod_extern = 1,
-       .addr = (0x10 >> 1),
-};
-
-static struct cxd2820r_config anysee_cxd2820r_config = {
-       .i2c_address = 0x6d, /* (0xda >> 1) */
-       .ts_mode = 0x38,
-};
-
-/*
- * New USB device strings: Mfr=1, Product=2, SerialNumber=0
- * Manufacturer: AMT.CO.KR
- *
- * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
- * PCB: ?
- * parts: DNOS404ZH102A(MT352, DTT7579(?))
- *
- * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
- * PCB: PCB 507T (rev1.61)
- * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
- * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
- * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
- *
- * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
- * PCB: 507CD (rev1.1)
- * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
- * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
- * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
- * IOD[0] ZL10353 1=enabled
- * IOA[7] TS 0=enabled
- * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
- *
- * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
- * PCB: 507DC (rev0.2)
- * parts: TDA10023, DTOS403IH102B TM, CST56I01
- * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
- * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
- * IOD[0] TDA10023 1=enabled
- *
- * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
- * PCB: 507SI (rev2.1)
- * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
- * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
- * IOD[0] CX24116 1=enabled
- *
- * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
- * PCB: 507FA (rev0.4)
- * parts: TDA10023, DTOS403IH102B TM, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
- * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
- * IOD[5] TDA10023 1=enabled
- * IOE[0] tuner 1=enabled
- *
- * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
- * PCB: 507FA (rev1.1)
- * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
- * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
- * DVB-C:
- * IOD[5] TDA10023 1=enabled
- * IOE[0] tuner 1=enabled
- * DVB-T:
- * IOD[0] ZL10353 1=enabled
- * IOE[0] tuner 0=enabled
- * tuner is behind ZL10353 I2C-gate
- *
- * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
- * PCB: 508TC (rev0.6)
- * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[4] TDA18212 1=enabled
- * DVB-C:
- * IOD[6] ZL10353 0=disabled
- * IOD[5] TDA10023 1=enabled
- * IOE[0] IF 1=enabled
- * DVB-T:
- * IOD[5] TDA10023 0=disabled
- * IOD[6] ZL10353 1=enabled
- * IOE[0] IF 0=enabled
- *
- * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
- * PCB: 508S2 (rev0.7)
- * parts: DNBU10512IST(STV0903, STV6110), ISL6423
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] STV0903 1=enabled
- *
- * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
- * PCB: 508T2C (rev0.3)
- * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] CXD2820R 1=enabled
- *
- * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
- * PCB: 508PTC (rev0.5)
- * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[4] TDA18212 1=enabled
- * DVB-C:
- * IOD[6] ZL10353 0=disabled
- * IOD[5] TDA10023 1=enabled
- * IOE[0] IF 1=enabled
- * DVB-T:
- * IOD[5] TDA10023 0=disabled
- * IOD[6] ZL10353 1=enabled
- * IOE[0] IF 0=enabled
- *
- * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
- * PCB: 508PS2 (rev0.4)
- * parts: DNBU10512IST(STV0903, STV6110), ISL6423
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] STV0903 1=enabled
- */
-
-static int anysee_read_config(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-       u8 hw_info[3];
-
-       /*
-        * Check which hardware we have.
-        * We must do this call two times to get reliable values (hw/fw bug).
-        */
-       ret = anysee_get_hw_info(d, hw_info);
-       if (ret)
-               goto error;
-
-       ret = anysee_get_hw_info(d, hw_info);
-       if (ret)
-               goto error;
-
-       /* Meaning of these info bytes are guessed. */
-       info("firmware version:%d.%d hardware id:%d",
-               hw_info[1], hw_info[2], hw_info[0]);
-
-       state->hw = hw_info[0];
-error:
-       return ret;
-}
-
-/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
-static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       /* enable / disable tuner access on IOE[4] */
-       return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
-}
-
-static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct anysee_state *state = fe_to_priv(fe);
-       struct dvb_usb_device *d = fe_to_d(fe);
-       int ret;
-
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       /* no frontend sleep control */
-       if (onoff == 0)
-               return 0;
-
-       switch (state->hw) {
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               if (fe->id == 0)  {
-                       /* disable DVB-T demod on IOD[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C tuner on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               } else {
-                       /* disable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T demod on IOD[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T tuner on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               if (fe->id == 0)  {
-                       /* disable DVB-T demod on IOD[6] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable IF route on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               } else {
-                       /* disable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T demod on IOD[6] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
-                       if (ret)
-                               goto error;
-
-                       /* enable IF route on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               }
-
-               break;
-       default:
-               ret = 0;
-       }
-
-error:
-       return ret;
-}
-
-static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct anysee_state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       u8 tmp;
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = anysee_tda18212_config.i2c_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = "\x00",
-               }, {
-                       .addr = anysee_tda18212_config.i2c_address,
-                       .flags = I2C_M_RD,
-                       .len = 1,
-                       .buf = &tmp,
-               }
-       };
-
-       switch (state->hw) {
-       case ANYSEE_HW_507T: /* 2 */
-               /* E30 */
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
-                               &d->i2c_adap);
-               if (adap->fe[0])
-                       break;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507CD: /* 6 */
-               /* E30 Plus */
-
-               /* enable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* enable transport stream on IOA[7] */
-               ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507DC: /* 10 */
-               /* E30 C Plus */
-
-               /* enable DVB-C demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(tda10023_attach,
-                               &anysee_tda10023_config, &d->i2c_adap, 0x48);
-
-               break;
-       case ANYSEE_HW_507SI: /* 11 */
-               /* E30 S2 Plus */
-
-               /* enable DVB-S/S2 demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               /* enable tuner on IOE[4] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
-               if (ret)
-                       goto error;
-
-               /* probe TDA18212 */
-               tmp = 0;
-               ret = i2c_transfer(&d->i2c_adap, msg, 2);
-               if (ret == 2 && tmp == 0xc7)
-                       deb_info("%s: TDA18212 found\n", __func__);
-               else
-                       tmp = 0;
-
-               /* disable tuner on IOE[4] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
-               if (ret)
-                       goto error;
-
-               /* disable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               if (tmp == 0xc7) {
-                       /* TDA18212 config */
-                       adap->fe[0] = dvb_attach(tda10023_attach,
-                                       &anysee_tda10023_tda18212_config,
-                                       &d->i2c_adap, 0x48);
-
-                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-                       if (adap->fe[0])
-                               adap->fe[0]->ops.i2c_gate_ctrl =
-                                               anysee_i2c_gate_ctrl;
-               } else {
-                       /* PLL config */
-                       adap->fe[0] = dvb_attach(tda10023_attach,
-                                       &anysee_tda10023_config,
-                                       &d->i2c_adap, 0x48);
-               }
-
-               /* break out if first frontend attaching fails */
-               if (!adap->fe[0])
-                       break;
-
-               /* disable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               if (tmp == 0xc7) {
-                       /* TDA18212 config */
-                       adap->fe[1] = dvb_attach(zl10353_attach,
-                                       &anysee_zl10353_tda18212_config2,
-                                       &d->i2c_adap);
-
-                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-                       if (adap->fe[1])
-                               adap->fe[1]->ops.i2c_gate_ctrl =
-                                               anysee_i2c_gate_ctrl;
-               } else {
-                       /* PLL config */
-                       adap->fe[1] = dvb_attach(zl10353_attach,
-                                       &anysee_zl10353_config,
-                                       &d->i2c_adap);
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               /* disable DVB-T demod on IOD[6] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(tda10023_attach,
-                               &anysee_tda10023_tda18212_config,
-                               &d->i2c_adap, 0x48);
-
-               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-               if (adap->fe[0])
-                       adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
-
-               /* break out if first frontend attaching fails */
-               if (!adap->fe[0])
-                       break;
-
-               /* disable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-T demod on IOD[6] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[1] = dvb_attach(zl10353_attach,
-                               &anysee_zl10353_tda18212_config,
-                               &d->i2c_adap);
-
-               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-               if (adap->fe[1])
-                       adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
-
-               state->has_ci = true;
-
-               break;
-       case ANYSEE_HW_508S2: /* 19 */
-       case ANYSEE_HW_508PS2: /* 22 */
-               /* E7 S2 */
-               /* E7 PS2 */
-
-               /* enable DVB-S/S2 demod on IOE[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(stv0900_attach,
-                               &anysee_stv0900_config, &d->i2c_adap, 0);
-
-               state->has_ci = true;
-
-               break;
-       case ANYSEE_HW_508T2C: /* 20 */
-               /* E7 T2C */
-
-               /* enable DVB-T/T2/C demod on IOE[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(cxd2820r_attach,
-                               &anysee_cxd2820r_config, &d->i2c_adap);
-
-               state->has_ci = true;
-
-               break;
-       }
-
-       if (!adap->fe[0]) {
-               /* we have no frontend :-( */
-               ret = -ENODEV;
-               err("Unsupported Anysee version. " \
-                       "Please report the <linux-media@vger.kernel.org>.");
-       }
-error:
-       return ret;
-}
-
-static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct anysee_state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct dvb_frontend *fe;
-       int ret;
-       deb_info("%s: adap=%d\n", __func__, adap->id);
-
-       switch (state->hw) {
-       case ANYSEE_HW_507T: /* 2 */
-               /* E30 */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
-                               DVB_PLL_THOMSON_DTT7579);
-
-               break;
-       case ANYSEE_HW_507CD: /* 6 */
-               /* E30 Plus */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
-                               &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
-
-               break;
-       case ANYSEE_HW_507DC: /* 10 */
-               /* E30 C Plus */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
-                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
-
-               break;
-       case ANYSEE_HW_507SI: /* 11 */
-               /* E30 S2 Plus */
-
-               /* attach LNB controller */
-               fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_isl6423_config);
-
-               break;
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               /* Try first attach TDA18212 silicon tuner on IOE[4], if that
-                * fails attach old simple PLL. */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config);
-
-               if (fe && adap->fe[1]) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(tda18212_attach, adap->fe[1],
-                                       &d->i2c_adap, &anysee_tda18212_config);
-                       break;
-               } else if (fe) {
-                       break;
-               }
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
-                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
-
-               if (fe && adap->fe[1]) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(dvb_pll_attach, adap->fe[0],
-                                       (0xc0 >> 1), &d->i2c_adap,
-                                       DVB_PLL_SAMSUNG_DTOS403IH102A);
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config);
-
-               if (fe) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(tda18212_attach, adap->fe[1],
-                                       &d->i2c_adap, &anysee_tda18212_config);
-               }
-
-               break;
-       case ANYSEE_HW_508S2: /* 19 */
-       case ANYSEE_HW_508PS2: /* 22 */
-               /* E7 S2 */
-               /* E7 PS2 */
-
-               /* attach tuner */
-               fe = dvb_attach(stv6110_attach, adap->fe[0],
-                               &anysee_stv6110_config, &d->i2c_adap);
-
-               if (fe) {
-                       /* attach LNB controller */
-                       fe = dvb_attach(isl6423_attach, adap->fe[0],
-                                       &d->i2c_adap, &anysee_isl6423_config);
-               }
-
-               break;
-
-       case ANYSEE_HW_508T2C: /* 20 */
-               /* E7 T2C */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config2);
-
-               break;
-       default:
-               fe = NULL;
-       }
-
-       if (fe)
-               ret = 0;
-       else
-               ret = -ENODEV;
-
-       return ret;
-}
-
-static int anysee_rc_query(struct dvb_usb_device *d)
-{
-       u8 buf[] = {CMD_GET_IR_CODE};
-       u8 ircode[2];
-       int ret;
-
-       /* Remote controller is basic NEC using address byte 0x08.
-          Anysee device RC query returns only two bytes, status and code,
-          address byte is dropped. Also it does not return any value for
-          NEC RCs having address byte other than 0x08. Due to that, we
-          cannot use that device as standard NEC receiver.
-          It could be possible make hack which reads whole code directly
-          from device memory... */
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
-       if (ret)
-               return ret;
-
-       if (ircode[0]) {
-               deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
-               rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
-       }
-
-       return 0;
-}
-
-static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query          = anysee_rc_query;
-       rc->interval       = 250;  /* windows driver uses 500ms */
-
-       return 0;
-}
-
-static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
-       int addr)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
-       u8 val;
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
-       if (ret)
-               return ret;
-
-       return val;
-}
-
-static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
-       int addr, u8 val)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
-       u8 addr)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
-       u8 val;
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
-       if (ret)
-               return ret;
-
-       return val;
-}
-
-static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
-       u8 addr, u8 val)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       struct anysee_state *state = d_to_priv(d);
-
-       state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       msleep(300);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       msleep(30);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
-       int open)
-{
-       struct dvb_usb_device *d = ci->data;
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-       u8 tmp;
-
-       ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
-       if (ret)
-               return ret;
-
-       if (tmp == 0) {
-               ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
-               if (time_after(jiffies, state->ci_cam_ready))
-                       ret |= DVB_CA_EN50221_POLL_CAM_READY;
-       }
-
-       return ret;
-}
-
-static int anysee_ci_init(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-
-       state->ci.owner               = THIS_MODULE;
-       state->ci.read_attribute_mem  = anysee_ci_read_attribute_mem;
-       state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
-       state->ci.read_cam_control    = anysee_ci_read_cam_control;
-       state->ci.write_cam_control   = anysee_ci_write_cam_control;
-       state->ci.slot_reset          = anysee_ci_slot_reset;
-       state->ci.slot_shutdown       = anysee_ci_slot_shutdown;
-       state->ci.slot_ts_enable      = anysee_ci_slot_ts_enable;
-       state->ci.poll_slot_status    = anysee_ci_poll_slot_status;
-       state->ci.data                = d;
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
-       if (ret)
-               return ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
-       if (ret)
-               return ret;
-
-       ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static void anysee_ci_release(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-
-       /* detach CI */
-       if (state->has_ci)
-               dvb_ca_en50221_release(&state->ci);
-
-       return;
-}
-
-static int anysee_init(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-
-       /* There is one interface with two alternate settings.
-          Alternate setting 0 is for bulk transfer.
-          Alternate setting 1 is for isochronous transfer.
-          We use bulk transfer (alternate setting 0). */
-       ret = usb_set_interface(d->udev, 0, 0);
-       if (ret)
-               return ret;
-
-       /* LED light */
-       ret = anysee_led_ctrl(d, 0x01, 0x03);
-       if (ret)
-               return ret;
-
-       /* enable IR */
-       ret = anysee_ir_ctrl(d, 1);
-       if (ret)
-               return ret;
-
-       /* attach CI */
-       if (state->has_ci) {
-               ret = anysee_ci_init(d);
-               if (ret) {
-                       state->has_ci = false;
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static void anysee_exit(struct dvb_usb_device *d)
-{
-       return anysee_ci_release(d);
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties anysee_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct anysee_state),
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo         = &anysee_i2c_algo,
-       .read_config      = anysee_read_config,
-       .frontend_attach  = anysee_frontend_attach,
-       .tuner_attach     = anysee_tuner_attach,
-       .init             = anysee_init,
-       .get_rc_config    = anysee_get_rc_config,
-       .frontend_ctrl    = anysee_frontend_ctrl,
-       .streaming_ctrl   = anysee_streaming_ctrl,
-       .exit             = anysee_exit,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
-               }
-       }
-};
-
-static const struct usb_device_id anysee_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
-               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
-       { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
-               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, anysee_id_table);
-
-static struct usb_driver anysee_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = anysee_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(anysee_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/anysee.h b/drivers/media/dvb/dvb-usb-v2/anysee.h
deleted file mode 100644 (file)
index dc40dcf..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- *    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.
- *
- * TODO:
- * - add smart card reader support for Conditional Access (CA)
- *
- * Card reader in Anysee is nothing more than ISO 7816 card reader.
- * There is no hardware CAM in any Anysee device sold.
- * In my understanding it should be implemented by making own module
- * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
- * module registers serial interface that can be used to communicate
- * with any ISO 7816 smart card.
- *
- * Any help according to implement serial smart card reader support
- * is highly welcome!
- */
-
-#ifndef _DVB_USB_ANYSEE_H_
-#define _DVB_USB_ANYSEE_H_
-
-#define DVB_USB_LOG_PREFIX "anysee"
-#include "dvb_usb.h"
-#include "dvb_ca_en50221.h"
-
-#ifdef CONFIG_DVB_USB_DEBUG
-#define dprintk(var, level, args...) \
-       do { if ((var & level)) printk(args); } while (0)
-#define DVB_USB_DEBUG_STATUS
-#else
-#define dprintk(args...)
-#define debug_dump(b, l, func)
-#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
-#endif
-
-#define debug_dump(b, l, func) {\
-       int loop_; \
-       for (loop_ = 0; loop_ < l; loop_++) \
-               func("%02x ", b[loop_]); \
-       func("\n");\
-}
-
-#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
-#define deb_rc(args...)   dprintk(dvb_usb_anysee_debug, 0x04, args)
-#define deb_reg(args...)  dprintk(dvb_usb_anysee_debug, 0x08, args)
-#define deb_i2c(args...)  dprintk(dvb_usb_anysee_debug, 0x10, args)
-#define deb_fw(args...)   dprintk(dvb_usb_anysee_debug, 0x20, args)
-
-#undef err
-#define err(format, arg...)  printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) printk(KERN_INFO    DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-
-enum cmd {
-       CMD_I2C_READ            = 0x33,
-       CMD_I2C_WRITE           = 0x31,
-       CMD_REG_READ            = 0xb0,
-       CMD_REG_WRITE           = 0xb1,
-       CMD_STREAMING_CTRL      = 0x12,
-       CMD_LED_AND_IR_CTRL     = 0x16,
-       CMD_GET_IR_CODE         = 0x41,
-       CMD_GET_HW_INFO         = 0x19,
-       CMD_SMARTCARD           = 0x34,
-       CMD_CI                  = 0x37,
-};
-
-struct anysee_state {
-       u8 hw; /* PCB ID */
-       u8 seq;
-       u8 fe_id:1; /* frondend ID */
-       u8 has_ci:1;
-       struct dvb_ca_en50221 ci;
-       unsigned long ci_cam_ready; /* jiffies */
-};
-
-#define ANYSEE_HW_507T    2 /* E30 */
-#define ANYSEE_HW_507CD   6 /* E30 Plus */
-#define ANYSEE_HW_507DC  10 /* E30 C Plus */
-#define ANYSEE_HW_507SI  11 /* E30 S2 Plus */
-#define ANYSEE_HW_507FA  15 /* E30 Combo Plus / E30 C Plus */
-#define ANYSEE_HW_508TC  18 /* E7 TC */
-#define ANYSEE_HW_508S2  19 /* E7 S2 */
-#define ANYSEE_HW_508T2C 20 /* E7 T2C */
-#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
-#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
-
-#define REG_IOA       0x80 /* Port A (bit addressable) */
-#define REG_IOB       0x90 /* Port B (bit addressable) */
-#define REG_IOC       0xa0 /* Port C (bit addressable) */
-#define REG_IOD       0xb0 /* Port D (bit addressable) */
-#define REG_IOE       0xb1 /* Port E (NOT bit addressable) */
-#define REG_OEA       0xb2 /* Port A Output Enable */
-#define REG_OEB       0xb3 /* Port B Output Enable */
-#define REG_OEC       0xb4 /* Port C Output Enable */
-#define REG_OED       0xb5 /* Port D Output Enable */
-#define REG_OEE       0xb6 /* Port E Output Enable */
-
-#endif
-
-/***************************************************************************
- * USB API description (reverse engineered)
- ***************************************************************************
-
-Transaction flow:
-=================
-BULK[00001] >>> REQUEST PACKET 64 bytes
-BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
-BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
-
-General reply packet(s) are always used if not own reply defined.
-
-============================================================================
-| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
-============================================================================
-|    00 | reply data (if any) from previous transaction
-|       | Just same reply packet as returned during previous transaction.
-|       | Needed only if reply is missed in previous transaction.
-|       | Just skip normally.
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
-============================================================================
-|    00 | reply data (if any)
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | I2C WRITE REQUEST PACKET
-============================================================================
-|    00 | 0x31 I2C write command
-----------------------------------------------------------------------------
-|    01 | i2c address
-----------------------------------------------------------------------------
-|    02 | data length
-|       | 0x02 (for typical I2C reg / val pair)
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-| 04-   | data
-----------------------------------------------------------------------------
-|   -59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | I2C READ REQUEST PACKET
-============================================================================
-|    00 | 0x33 I2C read command
-----------------------------------------------------------------------------
-|    01 | i2c address + 1
-----------------------------------------------------------------------------
-|    02 | register
-----------------------------------------------------------------------------
-|    03 | 0x00
-----------------------------------------------------------------------------
-|    04 | 0x00
-----------------------------------------------------------------------------
-|    05 | data length
-----------------------------------------------------------------------------
-| 06-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
-============================================================================
-|    00 | 0xb1 register write command
-----------------------------------------------------------------------------
-| 01-02 | register
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-|    04 | value
-----------------------------------------------------------------------------
-| 05-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
-============================================================================
-|    00 | 0xb0 register read command
-----------------------------------------------------------------------------
-| 01-02 | register
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-| 04-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | LED CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x16 LED and IR control command
-----------------------------------------------------------------------------
-|    01 | 0x01 (LED)
-----------------------------------------------------------------------------
-|    03 | 0x00 blink
-|       | 0x01 lights continuously
-----------------------------------------------------------------------------
-|    04 | blink interval
-|       | 0x00 fastest (looks like LED lights continuously)
-|       | 0xff slowest
-----------------------------------------------------------------------------
-| 05-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | IR CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x16 LED and IR control command
-----------------------------------------------------------------------------
-|    01 | 0x02 (IR)
-----------------------------------------------------------------------------
-|    03 | 0x00 IR disabled
-|       | 0x01 IR enabled
-----------------------------------------------------------------------------
-| 04-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | STREAMING CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x12 streaming control command
-----------------------------------------------------------------------------
-|    01 | 0x00 streaming disabled
-|       | 0x01 streaming enabled
-----------------------------------------------------------------------------
-|    02 | 0x00
-----------------------------------------------------------------------------
-| 03-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | REMOTE CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x41 remote control command
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | REMOTE CONTROL REPLY PACKET
-============================================================================
-|    00 | 0x00 code not received
-|       | 0x01 code received
-----------------------------------------------------------------------------
-|    01 | remote control code
-----------------------------------------------------------------------------
-| 02-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GET HARDWARE INFO REQUEST PACKET
-============================================================================
-|    00 | 0x19 get hardware info command
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GET HARDWARE INFO REPLY PACKET
-============================================================================
-|    00 | hardware id
-----------------------------------------------------------------------------
-| 01-02 | firmware version
-----------------------------------------------------------------------------
-| 03-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | SMART CARD READER PACKET
-============================================================================
-|    00 | 0x34 smart card reader command
-----------------------------------------------------------------------------
-|    xx |
-----------------------------------------------------------------------------
-| xx-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-*/
diff --git a/drivers/media/dvb/dvb-usb-v2/au6610.c b/drivers/media/dvb/dvb-usb-v2/au6610.c
deleted file mode 100644 (file)
index 05f2a86..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *
- *    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 "au6610.h"
-#include "zl10353.h"
-#include "qt1010.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
-                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       int ret;
-       u16 index;
-       u8 *usb_buf;
-
-       /*
-        * allocate enough for all known requests,
-        * read returns 5 and write 6 bytes
-        */
-       usb_buf = kmalloc(6, GFP_KERNEL);
-       if (!usb_buf)
-               return -ENOMEM;
-
-       switch (wlen) {
-       case 1:
-               index = wbuf[0] << 8;
-               break;
-       case 2:
-               index = wbuf[0] << 8;
-               index += wbuf[1];
-               break;
-       default:
-               pr_err("%s: wlen = %d, aborting\n", KBUILD_MODNAME, wlen);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
-                             USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
-                             usb_buf, 6, AU6610_USB_TIMEOUT);
-       if (ret < 0)
-               goto error;
-
-       switch (operation) {
-       case AU6610_REQ_I2C_READ:
-       case AU6610_REQ_USB_READ:
-               /* requested value is always 5th byte in buffer */
-               rbuf[0] = usb_buf[4];
-       }
-error:
-       kfree(usb_buf);
-       return ret;
-}
-
-static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u8 request;
-       u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
-
-       if (wo) {
-               request = AU6610_REQ_I2C_WRITE;
-       } else { /* rw */
-               request = AU6610_REQ_I2C_READ;
-       }
-
-       return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
-}
-
-
-/* I2C */
-static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                          int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                          msg[i].len, msg[i+1].buf,
-                                          msg[i+1].len) < 0)
-                               break;
-                       i++;
-               } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                              msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-
-static u32 au6610_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm au6610_i2c_algo = {
-       .master_xfer   = au6610_i2c_xfer,
-       .functionality = au6610_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config au6610_zl10353_config = {
-       .demod_address = 0x0f,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct qt1010_config au6610_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(qt1010_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &au6610_qt1010_config) == NULL ? -ENODEV : 0;
-}
-
-static int au6610_init(struct dvb_usb_device *d)
-{
-       /* TODO: this functionality belongs likely to the streaming control */
-       /* bInterfaceNumber 0, bAlternateSetting 5 */
-       return usb_set_interface(d->udev, 0, 5);
-}
-
-static struct dvb_usb_device_properties au6610_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-
-       .i2c_algo = &au6610_i2c_algo,
-       .frontend_attach = au6610_zl10353_frontend_attach,
-       .tuner_attach = au6610_qt1010_tuner_attach,
-       .init = au6610_init,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
-               },
-       },
-};
-
-static const struct usb_device_id au6610_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
-               &au6610_props, "Sigmatek DVB-110", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, au6610_id_table);
-
-static struct usb_driver au6610_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = au6610_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(au6610_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/au6610.h b/drivers/media/dvb/dvb-usb-v2/au6610.h
deleted file mode 100644 (file)
index ea337bf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *
- *    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 AU6610_H
-#define AU6610_H
-#include "dvb_usb.h"
-
-#define AU6610_REQ_I2C_WRITE   0x14
-#define AU6610_REQ_I2C_READ    0x13
-#define AU6610_REQ_USB_WRITE   0x16
-#define AU6610_REQ_USB_READ    0x15
-
-#define AU6610_USB_TIMEOUT 1000
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/az6007.c b/drivers/media/dvb/dvb-usb-v2/az6007.c
deleted file mode 100644 (file)
index 54f1221..0000000
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
- *
- * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
- *
- * This driver was made publicly available by Terratec, at:
- *     http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
- * The original driver's license is GPL, as declared with MODULE_LICENSE()
- *
- * Copyright (c) 2010-2012 Mauro Carvalho Chehab <mchehab@redhat.com>
- *     Driver modified by in order to work with upstream drxk driver, and
- *     tons of bugs got fixed, and converted to use dvb-usb-v2.
- *
- * 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 under version 2 of the License.
- *
- * 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.
- */
-
-#include "drxk.h"
-#include "mt2063.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_usb.h"
-#include "cypress_firmware.h"
-
-#define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw"
-
-static int az6007_xfer_debug;
-module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
-MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
-
-#define FX2_OED                        0xb5
-#define AZ6007_READ_DATA       0xb7
-#define AZ6007_I2C_RD          0xb9
-#define AZ6007_POWER           0xbc
-#define AZ6007_I2C_WR          0xbd
-#define FX2_SCON1              0xc0
-#define AZ6007_TS_THROUGH      0xc7
-#define AZ6007_READ_IR         0xb4
-
-struct az6007_device_state {
-       struct mutex            mutex;
-       struct mutex            ca_mutex;
-       struct dvb_ca_en50221   ca;
-       unsigned                warm:1;
-       int                     (*gate_ctrl) (struct dvb_frontend *, int);
-       unsigned char           data[4096];
-};
-
-static struct drxk_config terratec_h7_drxk = {
-       .adr = 0x29,
-       .parallel_ts = true,
-       .dynamic_clk = true,
-       .single_master = true,
-       .enable_merr_cfg = true,
-       .no_i2c_bridge = false,
-       .chunk_size = 64,
-       .mpeg_out_clk_strength = 0x02,
-       .qam_demod_parameter_count = 2,
-       .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
-};
-
-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct az6007_device_state *st = fe_to_priv(fe);
-       struct dvb_usb_adapter *adap = fe->sec_priv;
-       int status = 0;
-
-       pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable");
-
-       if (!adap || !st)
-               return -EINVAL;
-
-       if (enable)
-               status = st->gate_ctrl(fe, 1);
-       else
-               status = st->gate_ctrl(fe, 0);
-
-       return status;
-}
-
-static struct mt2063_config az6007_mt2063_config = {
-       .tuner_address = 0x60,
-       .refclock = 36125000,
-};
-
-static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
-                           u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       ret = usb_control_msg(udev,
-                             usb_rcvctrlpipe(udev, 0),
-                             req,
-                             USB_TYPE_VENDOR | USB_DIR_IN,
-                             value, index, b, blen, 5000);
-       if (ret < 0) {
-               pr_warn("usb read operation failed. (%d)\n", ret);
-               return -EIO;
-       }
-
-       if (az6007_xfer_debug) {
-               printk(KERN_DEBUG "az6007: IN  req: %02x, value: %04x, index: %04x\n",
-                      req, value, index);
-               print_hex_dump_bytes("az6007: payload: ",
-                                    DUMP_PREFIX_NONE, b, blen);
-       }
-
-       return ret;
-}
-
-static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
-                           u16 index, u8 *b, int blen)
-{
-       struct az6007_device_state *st = d->priv;
-       int ret;
-
-       if (mutex_lock_interruptible(&st->mutex) < 0)
-               return -EAGAIN;
-
-       ret = __az6007_read(d->udev, req, value, index, b, blen);
-
-       mutex_unlock(&st->mutex);
-
-       return ret;
-}
-
-static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
-                            u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       if (az6007_xfer_debug) {
-               printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
-                      req, value, index);
-               print_hex_dump_bytes("az6007: payload: ",
-                                    DUMP_PREFIX_NONE, b, blen);
-       }
-
-       if (blen > 64) {
-               pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
-                      blen);
-               return -EOPNOTSUPP;
-       }
-
-       ret = usb_control_msg(udev,
-                             usb_sndctrlpipe(udev, 0),
-                             req,
-                             USB_TYPE_VENDOR | USB_DIR_OUT,
-                             value, index, b, blen, 5000);
-       if (ret != blen) {
-               pr_err("usb write operation failed. (%d)\n", ret);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
-                           u16 index, u8 *b, int blen)
-{
-       struct az6007_device_state *st = d->priv;
-       int ret;
-
-       if (mutex_lock_interruptible(&st->mutex) < 0)
-               return -EAGAIN;
-
-       ret = __az6007_write(d->udev, req, value, index, b, blen);
-
-       mutex_unlock(&st->mutex);
-
-       return ret;
-}
-
-static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_device *d = fe_to_d(fe);
-
-       pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable");
-
-       return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
-}
-
-/* remote control stuff (does not work with my box) */
-static int az6007_rc_query(struct dvb_usb_device *d)
-{
-       struct az6007_device_state *st = d_to_priv(d);
-       unsigned code = 0;
-
-       az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
-
-       if (st->data[1] == 0x44)
-               return 0;
-
-       if ((st->data[1] ^ st->data[2]) == 0xff)
-               code = st->data[1];
-       else
-               code = st->data[1] << 8 | st->data[2];
-
-       if ((st->data[3] ^ st->data[4]) == 0xff)
-               code = code << 8 | st->data[3];
-       else
-               code = code << 16 | st->data[3] << 8 | st->data[4];
-
-       rc_keydown(d->rc_dev, code, st->data[5]);
-
-       return 0;
-}
-
-static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
-                                       int slot,
-                                       int address)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC1;
-       value = address;
-       index = 0;
-       blen = 1;
-
-       ret = az6007_read(d, req, value, index, b, blen);
-       if (ret < 0) {
-               pr_warn("usb in operation failed. (%d)\n", ret);
-               ret = -EINVAL;
-       } else {
-               ret = b[0];
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
-                                        int slot,
-                                        int address,
-                                        u8 value)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret;
-       u8 req;
-       u16 value1;
-       u16 index;
-       int blen;
-
-       pr_debug("%s(), slot %d\n", __func__, slot);
-       if (slot != 0)
-               return -EINVAL;
-
-       mutex_lock(&state->ca_mutex);
-       req = 0xC2;
-       value1 = address;
-       index = value;
-       blen = 0;
-
-       ret = az6007_write(d, req, value1, index, NULL, blen);
-       if (ret != 0)
-               pr_warn("usb out operation failed. (%d)\n", ret);
-
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
-                                     int slot,
-                                     u8 address)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC3;
-       value = address;
-       index = 0;
-       blen = 2;
-
-       ret = az6007_read(d, req, value, index, b, blen);
-       if (ret < 0) {
-               pr_warn("usb in operation failed. (%d)\n", ret);
-               ret = -EINVAL;
-       } else {
-               if (b[0] == 0)
-                       pr_warn("Read CI IO error\n");
-
-               ret = b[1];
-               pr_debug("read cam data = %x from 0x%x\n", b[1], value);
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
-                                      int slot,
-                                      u8 address,
-                                      u8 value)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret;
-       u8 req;
-       u16 value1;
-       u16 index;
-       int blen;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       mutex_lock(&state->ca_mutex);
-       req = 0xC4;
-       value1 = address;
-       index = value;
-       blen = 0;
-
-       ret = az6007_write(d, req, value1, index, NULL, blen);
-       if (ret != 0) {
-               pr_warn("usb out operation failed. (%d)\n", ret);
-               goto failed;
-       }
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       req = 0xC8;
-       value = 0;
-       index = 0;
-       blen = 1;
-
-       ret = az6007_read(d, req, value, index, b, blen);
-       if (ret < 0) {
-               pr_warn("usb in operation failed. (%d)\n", ret);
-               ret = -EIO;
-       } else{
-               ret = b[0];
-       }
-       kfree(b);
-       return ret;
-}
-
-static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret, i;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC6;
-       value = 1;
-       index = 0;
-       blen = 0;
-
-       ret = az6007_write(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               pr_warn("usb out operation failed. (%d)\n", ret);
-               goto failed;
-       }
-
-       msleep(500);
-       req = 0xC6;
-       value = 0;
-       index = 0;
-       blen = 0;
-
-       ret = az6007_write(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               pr_warn("usb out operation failed. (%d)\n", ret);
-               goto failed;
-       }
-
-       for (i = 0; i < 15; i++) {
-               msleep(100);
-
-               if (CI_CamReady(ca, slot)) {
-                       pr_debug("CAM Ready\n");
-                       break;
-               }
-       }
-       msleep(5000);
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       return 0;
-}
-
-static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       pr_debug("%s()\n", __func__);
-       mutex_lock(&state->ca_mutex);
-       req = 0xC7;
-       value = 1;
-       index = 0;
-       blen = 0;
-
-       ret = az6007_write(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               pr_warn("usb out operation failed. (%d)\n", ret);
-               goto failed;
-       }
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6007_device_state *state = d_to_priv(d);
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC5;
-       value = 0;
-       index = 0;
-       blen = 1;
-
-       ret = az6007_read(d, req, value, index, b, blen);
-       if (ret < 0) {
-               pr_warn("usb in operation failed. (%d)\n", ret);
-               ret = -EIO;
-       } else
-               ret = 0;
-
-       if (!ret && b[0] == 1) {
-               ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
-                     DVB_CA_EN50221_POLL_CAM_READY;
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-
-static void az6007_ci_uninit(struct dvb_usb_device *d)
-{
-       struct az6007_device_state *state;
-
-       pr_debug("%s()\n", __func__);
-
-       if (NULL == d)
-               return;
-
-       state = d_to_priv(d);
-       if (NULL == state)
-               return;
-
-       if (NULL == state->ca.data)
-               return;
-
-       dvb_ca_en50221_release(&state->ca);
-
-       memset(&state->ca, 0, sizeof(state->ca));
-}
-
-
-static int az6007_ci_init(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct az6007_device_state *state = adap_to_priv(adap);
-       int ret;
-
-       pr_debug("%s()\n", __func__);
-
-       mutex_init(&state->ca_mutex);
-       state->ca.owner                 = THIS_MODULE;
-       state->ca.read_attribute_mem    = az6007_ci_read_attribute_mem;
-       state->ca.write_attribute_mem   = az6007_ci_write_attribute_mem;
-       state->ca.read_cam_control      = az6007_ci_read_cam_control;
-       state->ca.write_cam_control     = az6007_ci_write_cam_control;
-       state->ca.slot_reset            = az6007_ci_slot_reset;
-       state->ca.slot_shutdown         = az6007_ci_slot_shutdown;
-       state->ca.slot_ts_enable        = az6007_ci_slot_ts_enable;
-       state->ca.poll_slot_status      = az6007_ci_poll_slot_status;
-       state->ca.data                  = d;
-
-       ret = dvb_ca_en50221_init(&adap->dvb_adap,
-                                 &state->ca,
-                                 0, /* flags */
-                                 1);/* n_slots */
-       if (ret != 0) {
-               pr_err("Cannot initialize CI: Error %d.\n", ret);
-               memset(&state->ca, 0, sizeof(state->ca));
-               return ret;
-       }
-
-       pr_debug("CI initialized.\n");
-
-       return 0;
-}
-
-static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct az6007_device_state *st = adap_to_priv(adap);
-       int ret;
-
-       ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
-       memcpy(mac, st->data, 6);
-
-       if (ret > 0)
-               pr_debug("%s: mac is %pM\n", __func__, mac);
-
-       return ret;
-}
-
-static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct az6007_device_state *st = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-
-       pr_debug("attaching demod drxk\n");
-
-       adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk,
-                                &d->i2c_adap);
-       if (!adap->fe[0])
-               return -EINVAL;
-
-       adap->fe[0]->sec_priv = adap;
-       st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
-       adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
-
-       az6007_ci_init(adap);
-
-       return 0;
-}
-
-static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-
-       pr_debug("attaching tuner mt2063\n");
-
-       /* Attach mt2063 to DVB-C frontend */
-       if (adap->fe[0]->ops.i2c_gate_ctrl)
-               adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1);
-       if (!dvb_attach(mt2063_attach, adap->fe[0],
-                       &az6007_mt2063_config,
-                       &d->i2c_adap))
-               return -EINVAL;
-
-       if (adap->fe[0]->ops.i2c_gate_ctrl)
-               adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0);
-
-       return 0;
-}
-
-static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       struct az6007_device_state *state = d_to_priv(d);
-       int ret;
-
-       pr_debug("%s()\n", __func__);
-
-       if (!state->warm) {
-               mutex_init(&state->mutex);
-
-               ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
-               if (ret < 0)
-                       return ret;
-               msleep(60);
-               ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
-               if (ret < 0)
-                       return ret;
-               msleep(100);
-               ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
-               if (ret < 0)
-                       return ret;
-               msleep(20);
-               ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
-               if (ret < 0)
-                       return ret;
-
-               msleep(400);
-               ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
-               if (ret < 0)
-                       return ret;
-               msleep(150);
-               ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
-               if (ret < 0)
-                       return ret;
-               msleep(430);
-               ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
-               if (ret < 0)
-                       return ret;
-
-               state->warm = true;
-
-               return 0;
-       }
-
-       if (!onoff)
-               return 0;
-
-       az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
-       az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
-
-       return 0;
-}
-
-/* I2C */
-static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-                          int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct az6007_device_state *st = d_to_priv(d);
-       int i, j, len;
-       int ret = 0;
-       u16 index;
-       u16 value;
-       int length;
-       u8 req, addr;
-
-       if (mutex_lock_interruptible(&st->mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               addr = msgs[i].addr << 1;
-               if (((i + 1) < num)
-                   && (msgs[i].len == 1)
-                   && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD)
-                   && (msgs[i + 1].flags & I2C_M_RD)
-                   && (msgs[i].addr == msgs[i + 1].addr)) {
-                       /*
-                        * A write + read xfer for the same address, where
-                        * the first xfer has just 1 byte length.
-                        * Need to join both into one operation
-                        */
-                       if (az6007_xfer_debug)
-                               printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n",
-                                      addr, msgs[i].len, msgs[i + 1].len);
-                       req = AZ6007_I2C_RD;
-                       index = msgs[i].buf[0];
-                       value = addr | (1 << 8);
-                       length = 6 + msgs[i + 1].len;
-                       len = msgs[i + 1].len;
-                       ret = __az6007_read(d->udev, req, value, index,
-                                           st->data, length);
-                       if (ret >= len) {
-                               for (j = 0; j < len; j++)
-                                       msgs[i + 1].buf[j] = st->data[j + 5];
-                       } else
-                               ret = -EIO;
-                       i++;
-               } else if (!(msgs[i].flags & I2C_M_RD)) {
-                       /* write bytes */
-                       if (az6007_xfer_debug)
-                               printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
-                                      addr, msgs[i].len);
-                       req = AZ6007_I2C_WR;
-                       index = msgs[i].buf[0];
-                       value = addr | (1 << 8);
-                       length = msgs[i].len - 1;
-                       len = msgs[i].len - 1;
-                       for (j = 0; j < len; j++)
-                               st->data[j] = msgs[i].buf[j + 1];
-                       ret =  __az6007_write(d->udev, req, value, index,
-                                             st->data, length);
-               } else {
-                       /* read bytes */
-                       if (az6007_xfer_debug)
-                               printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
-                                      addr, msgs[i].len);
-                       req = AZ6007_I2C_RD;
-                       index = msgs[i].buf[0];
-                       value = addr;
-                       length = msgs[i].len + 6;
-                       len = msgs[i].len;
-                       ret = __az6007_read(d->udev, req, value, index,
-                                           st->data, length);
-                       for (j = 0; j < len; j++)
-                               msgs[i].buf[j] = st->data[j + 5];
-               }
-               if (ret < 0)
-                       goto err;
-       }
-err:
-       mutex_unlock(&st->mutex);
-
-       if (ret < 0) {
-               pr_info("%s ERROR: %i\n", __func__, ret);
-               return ret;
-       }
-       return num;
-}
-
-static u32 az6007_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm az6007_i2c_algo = {
-       .master_xfer = az6007_i2c_xfer,
-       .functionality = az6007_i2c_func,
-};
-
-static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 *mac;
-
-       pr_debug("Identifying az6007 state\n");
-
-       mac = kmalloc(6, GFP_ATOMIC);
-       if (!mac)
-               return -ENOMEM;
-
-       /* Try to read the mac address */
-       ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
-       if (ret == 6)
-               ret = WARM;
-       else
-               ret = COLD;
-
-       kfree(mac);
-
-       if (ret == COLD) {
-               __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
-               __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
-               __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
-       }
-
-       pr_debug("Device is on %s state\n",
-                ret == WARM ? "warm" : "cold");
-       return ret;
-}
-
-static void az6007_usb_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       az6007_ci_uninit(d);
-       dvb_usbv2_disconnect(intf);
-}
-
-static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       pr_debug("Getting az6007 Remote Control properties\n");
-
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query          = az6007_rc_query;
-       rc->interval       = 400;
-
-       return 0;
-}
-
-static int az6007_download_firmware(struct dvb_usb_device *d,
-       const struct firmware *fw)
-{
-       pr_debug("Loading az6007 firmware\n");
-
-       return usbv2_cypress_load_firmware(d->udev, fw, CYPRESS_FX2);
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties az6007_props = {
-       .driver_name         = KBUILD_MODNAME,
-       .owner               = THIS_MODULE,
-       .firmware            = AZ6007_FIRMWARE,
-
-       .adapter_nr          = adapter_nr,
-       .size_of_priv        = sizeof(struct az6007_device_state),
-       .i2c_algo            = &az6007_i2c_algo,
-       .tuner_attach        = az6007_tuner_attach,
-       .frontend_attach     = az6007_frontend_attach,
-       .streaming_ctrl      = az6007_streaming_ctrl,
-       .get_rc_config       = az6007_get_rc_config,
-       .read_mac_address    = az6007_read_mac_addr,
-       .download_firmware   = az6007_download_firmware,
-       .identify_state      = az6007_identify_state,
-       .power_ctrl          = az6007_power_ctrl,
-       .num_adapters        = 1,
-       .adapter             = {
-               { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
-       }
-};
-
-static struct usb_device_id az6007_usb_table[] = {
-       {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
-               &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
-       {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7,
-               &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
-       {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
-               &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
-       {0},
-};
-
-MODULE_DEVICE_TABLE(usb, az6007_usb_table);
-
-static int az6007_suspend(struct usb_interface *intf, pm_message_t msg)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-
-       az6007_ci_uninit(d);
-       return dvb_usbv2_suspend(intf, msg);
-}
-
-static int az6007_resume(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       struct dvb_usb_adapter *adap = &d->adapter[0];
-
-       az6007_ci_init(adap);
-       return dvb_usbv2_resume(intf);
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver az6007_usb_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = az6007_usb_table,
-       .probe          = dvb_usbv2_probe,
-       .disconnect     = az6007_usb_disconnect,
-       .no_dynamic_id  = 1,
-       .soft_unbind    = 1,
-       /*
-        * FIXME: need to implement reset_resume, likely with
-        * dvb-usb-v2 core support
-        */
-       .suspend        = az6007_suspend,
-       .resume         = az6007_resume,
-};
-
-module_usb_driver(az6007_usb_driver);
-
-MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
-MODULE_VERSION("2.0");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(AZ6007_FIRMWARE);
diff --git a/drivers/media/dvb/dvb-usb-v2/ce6230.c b/drivers/media/dvb/dvb-usb-v2/ce6230.c
deleted file mode 100644 (file)
index 84ff4a9..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Intel CE6230 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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 "ce6230.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
-{
-       int ret;
-       unsigned int pipe;
-       u8 request;
-       u8 requesttype;
-       u16 value;
-       u16 index;
-       u8 *buf;
-
-       request = req->cmd;
-       value = req->value;
-       index = req->index;
-
-       switch (req->cmd) {
-       case I2C_READ:
-       case DEMOD_READ:
-       case REG_READ:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               break;
-       case I2C_WRITE:
-       case DEMOD_WRITE:
-       case REG_WRITE:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               break;
-       default:
-               pr_debug("%s: unknown command=%02x\n", __func__, req->cmd);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       buf = kmalloc(req->data_len, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
-               /* write */
-               memcpy(buf, req->data, req->data_len);
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {
-               /* read */
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
-                       buf, req->data_len, CE6230_USB_TIMEOUT);
-
-       ce6230_debug_dump(request, requesttype, value, index, buf,
-                       req->data_len);
-
-       if (ret < 0)
-               pr_err("%s: usb_control_msg() failed=%d\n", KBUILD_MODNAME,
-                               ret);
-       else
-               ret = 0;
-
-       /* read request, copy returned data to return buf */
-       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
-               memcpy(req->data, buf, req->data_len);
-
-       kfree(buf);
-error:
-       return ret;
-}
-
-/* I2C */
-static struct zl10353_config ce6230_zl10353_config;
-
-static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int ret = 0, i = 0;
-       struct usb_req req;
-
-       if (num > 2)
-               return -EOPNOTSUPP;
-
-       memset(&req, 0, sizeof(req));
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].addr ==
-                               ce6230_zl10353_config.demod_address) {
-                               req.cmd = DEMOD_READ;
-                               req.value = msg[i].addr >> 1;
-                               req.index = msg[i].buf[0];
-                               req.data_len = msg[i+1].len;
-                               req.data = &msg[i+1].buf[0];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       } else {
-                               pr_err("%s: I2C read not implemented\n",
-                                               KBUILD_MODNAME);
-                               ret = -EOPNOTSUPP;
-                       }
-                       i += 2;
-               } else {
-                       if (msg[i].addr ==
-                               ce6230_zl10353_config.demod_address) {
-                               req.cmd = DEMOD_WRITE;
-                               req.value = msg[i].addr >> 1;
-                               req.index = msg[i].buf[0];
-                               req.data_len = msg[i].len-1;
-                               req.data = &msg[i].buf[1];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       } else {
-                               req.cmd = I2C_WRITE;
-                               req.value = 0x2000 + (msg[i].addr >> 1);
-                               req.index = 0x0000;
-                               req.data_len = msg[i].len;
-                               req.data = &msg[i].buf[0];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       }
-                       i += 1;
-               }
-               if (ret)
-                       break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret ? ret : i;
-}
-
-static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm ce6230_i2c_algorithm = {
-       .master_xfer   = ce6230_i2c_master_xfer,
-       .functionality = ce6230_i2c_functionality,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config ce6230_zl10353_config = {
-       .demod_address = 0x1e,
-       .adc_clock = 450000,
-       .if2 = 45700,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-       .clock_ctl_1 = 0x34,
-       .pll_0 = 0x0e,
-};
-
-static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-
-       adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct mxl5005s_config ce6230_mxl5003s_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_DEFAULT,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-
-       pr_debug("%s:\n", __func__);
-
-       ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
-       return ret;
-}
-
-static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-
-       pr_debug("%s: onoff=%d\n", __func__, onoff);
-
-       /* InterfaceNumber 1 / AlternateSetting 0     idle
-          InterfaceNumber 1 / AlternateSetting 1     streaming */
-       ret = usb_set_interface(d->udev, 1, onoff);
-       if (ret)
-               pr_err("%s: usb_set_interface() failed=%d\n", KBUILD_MODNAME,
-                               ret);
-
-       return ret;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties ce6230_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .bInterfaceNumber = 1,
-
-       .i2c_algo = &ce6230_i2c_algorithm,
-       .power_ctrl = ce6230_power_ctrl,
-       .frontend_attach = ce6230_zl10353_frontend_attach,
-       .tuner_attach = ce6230_mxl5003s_tuner_attach,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 6,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = (16 * 512),
-                                       }
-                               }
-                       },
-               }
-       },
-};
-
-static const struct usb_device_id ce6230_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
-               &ce6230_props, "Intel CE9500 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
-               &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, ce6230_id_table);
-
-static struct usb_driver ce6230_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = ce6230_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(ce6230_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Intel CE6230 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/ce6230.h b/drivers/media/dvb/dvb-usb-v2/ce6230.h
deleted file mode 100644 (file)
index 42d7544..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Intel CE6230 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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 CE6230_H
-#define CE6230_H
-
-#include "dvb_usb.h"
-#include "zl10353.h"
-#include "mxl5005s.h"
-
-#define ce6230_debug_dump(r, t, v, i, b, l) { \
-       char *direction; \
-       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
-               direction = ">>>"; \
-       else \
-               direction = "<<<"; \
-       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s [%d bytes]\n", \
-                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
-                       l & 0xff, l >> 8, direction, l); \
-}
-
-#define CE6230_USB_TIMEOUT 1000
-
-struct usb_req {
-       u8  cmd;       /* [1] */
-       u16 value;     /* [2|3] */
-       u16 index;     /* [4|5] */
-       u16 data_len;  /* [6|7] */
-       u8  *data;
-};
-
-enum ce6230_cmd {
-       CONFIG_READ          = 0xd0, /* rd 0 (unclear) */
-       UNKNOWN_WRITE        = 0xc7, /* wr 7 (unclear) */
-       I2C_READ             = 0xd9, /* rd 9 (unclear) */
-       I2C_WRITE            = 0xca, /* wr a */
-       DEMOD_READ           = 0xdb, /* rd b */
-       DEMOD_WRITE          = 0xcc, /* wr c */
-       REG_READ             = 0xde, /* rd e */
-       REG_WRITE            = 0xcf, /* wr f */
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/cypress_firmware.c b/drivers/media/dvb/dvb-usb-v2/cypress_firmware.c
deleted file mode 100644 (file)
index 9f7c970..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*  cypress_firmware.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for downloading the firmware to Cypress FX 1
- * and 2 based devices.
- *
- */
-
-#include "dvb_usb.h"
-#include "cypress_firmware.h"
-
-struct usb_cypress_controller {
-       u8 id;
-       const char *name;       /* name of the usb controller */
-       u16 cs_reg;             /* needs to be restarted,
-                                * when the firmware has been downloaded */
-};
-
-static const struct usb_cypress_controller cypress[] = {
-       { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
-       { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
-       { .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cs_reg = 0xe600 },
-};
-
-/*
- * load a firmware packet to the device
- */
-static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
-               u8 len)
-{
-       return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                       0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
-}
-
-int usbv2_cypress_load_firmware(struct usb_device *udev,
-               const struct firmware *fw, int type)
-{
-       struct hexline hx;
-       u8 reset;
-       int ret, pos = 0;
-
-       /* stop the CPU */
-       reset = 1;
-       ret = usb_cypress_writemem(udev, cypress[type].cs_reg, &reset, 1);
-       if (ret != 1)
-               pr_err("%s: could not stop the USB controller CPU",
-                               KBUILD_MODNAME);
-
-       while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) {
-               pr_debug("%s: writing to address %04x (buffer: %02x %02x)\n",
-                               __func__, hx.addr, hx.len, hx.chk);
-
-               ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len);
-               if (ret != hx.len) {
-                       pr_err("%s: error while transferring firmware " \
-                                       "(transferred size=%d, block size=%d)",
-                                       KBUILD_MODNAME, ret, hx.len);
-                       ret = -EINVAL;
-                       break;
-               }
-       }
-       if (ret < 0) {
-               pr_err("%s: firmware download failed at %d with %d",
-                               KBUILD_MODNAME, pos, ret);
-               return ret;
-       }
-
-       if (ret == 0) {
-               /* restart the CPU */
-               reset = 0;
-               if (ret || usb_cypress_writemem(
-                               udev, cypress[type].cs_reg, &reset, 1) != 1) {
-                       pr_err("%s: could not restart the USB controller CPU",
-                                       KBUILD_MODNAME);
-                       ret = -EINVAL;
-               }
-       } else
-               ret = -EIO;
-
-       return ret;
-}
-EXPORT_SYMBOL(usbv2_cypress_load_firmware);
-
-int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
-               int *pos)
-{
-       u8 *b = (u8 *) &fw->data[*pos];
-       int data_offs = 4;
-
-       if (*pos >= fw->size)
-               return 0;
-
-       memset(hx, 0, sizeof(struct hexline));
-
-       hx->len = b[0];
-
-       if ((*pos + hx->len + 4) >= fw->size)
-               return -EINVAL;
-
-       hx->addr = b[1] | (b[2] << 8);
-       hx->type = b[3];
-
-       if (hx->type == 0x04) {
-               /* b[4] and b[5] are the Extended linear address record data
-                * field */
-               hx->addr |= (b[4] << 24) | (b[5] << 16);
-               /*
-               hx->len -= 2;
-               data_offs += 2;
-               */
-       }
-       memcpy(hx->data, &b[data_offs], hx->len);
-       hx->chk = b[hx->len + data_offs];
-
-       *pos += hx->len + 5;
-
-       return *pos;
-}
-EXPORT_SYMBOL(dvb_usbv2_get_hexline);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Cypress firmware download");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/cypress_firmware.h b/drivers/media/dvb/dvb-usb-v2/cypress_firmware.h
deleted file mode 100644 (file)
index 80085fd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* cypress_firmware.h is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for downloading the firmware to Cypress FX 1
- * and 2 based devices.
- *
- */
-
-#ifndef CYPRESS_FIRMWARE_H
-#define CYPRESS_FIRMWARE_H
-
-#define CYPRESS_AN2135  0
-#define CYPRESS_AN2235  1
-#define CYPRESS_FX2     2
-
-/* commonly used firmware download types and function */
-struct hexline {
-       u8 len;
-       u32 addr;
-       u8 type;
-       u8 data[255];
-       u8 chk;
-};
-extern int usbv2_cypress_load_firmware(struct usb_device *,
-               const struct firmware *, int);
-extern int dvb_usbv2_get_hexline(const struct firmware *,
-               struct hexline *, int *);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb.h b/drivers/media/dvb/dvb-usb-v2/dvb_usb.h
deleted file mode 100644 (file)
index 79b3b8b..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DVB_USB_H
-#define DVB_USB_H
-
-#include <linux/usb/input.h>
-#include <linux/firmware.h>
-#include <media/rc-core.h>
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-#include "dvb-usb-ids.h"
-
-/*
- * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
- *
- * |-- device
- * |   |-- adapter0
- * |   |   |-- frontend0
- * |   |   |-- frontend1
- * |   |   `-- frontend2
- * |   `-- adapter1
- * |       |-- frontend0
- * |       |-- frontend1
- * |       `-- frontend2
- *
- *
- * Commonly used variable names:
- * d = pointer to device (struct dvb_usb_device *)
- * adap = pointer to adapter (struct dvb_usb_adapter *)
- * fe = pointer to frontend (struct dvb_frontend *)
- *
- * Use macros defined in that file to resolve needed pointers.
- */
-
-/* helper macros for every DVB USB driver use */
-#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
-               adapter[adap->id]))
-#define adap_to_priv(adap) (adap_to_d(adap)->priv)
-#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
-#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
-#define fe_to_priv(fe) (fe_to_d(fe)->priv)
-#define d_to_priv(d) (d->priv)
-
-#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
-       .type = USB_BULK, \
-       .count = count_, \
-       .endpoint = endpoint_, \
-       .u = { \
-               .bulk = { \
-                       .buffersize = size_, \
-               } \
-       } \
-}
-
-#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
-       .type = USB_ISOC, \
-       .count = count_, \
-       .endpoint = endpoint_, \
-       .u = { \
-               .isoc = { \
-                       .framesperurb = frames_, \
-                       .framesize = size_,\
-                       .interval = interval_, \
-               } \
-       } \
-}
-
-#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
-       .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
-       .idVendor = (vend), \
-       .idProduct = (prod), \
-       .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
-               .props = (props_), \
-               .name = (name_), \
-               .rc_map = (rc), \
-       })
-
-struct dvb_usb_device;
-struct dvb_usb_adapter;
-
-/**
- * structure for carrying all needed data from the device driver to the general
- * dvb usb routines
- * @name: device name
- * @rc_map: name of rc codes table
- * @props: structure containing all device properties
- */
-struct dvb_usb_driver_info {
-       const char *name;
-       const char *rc_map;
-       const struct dvb_usb_device_properties *props;
-};
-
-/**
- * structure for remote controller configuration
- * @map_name: name of rc codes table
- * @allowed_protos: protocol(s) supported by the driver
- * @change_protocol: callback to change protocol
- * @query: called to query an event from the device
- * @interval: time in ms between two queries
- * @driver_type: used to point if a device supports raw mode
- * @bulk_mode: device supports bulk mode for rc (disable polling mode)
- */
-struct dvb_usb_rc {
-       const char *map_name;
-       u64 allowed_protos;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
-       int (*query) (struct dvb_usb_device *d);
-       unsigned int interval;
-       const enum rc_driver_type driver_type;
-       bool bulk_mode;
-};
-
-/**
- * usb streaming configration for adapter
- * @type: urb type
- * @count: count of used urbs
- * @endpoint: stream usb endpoint number
- */
-struct usb_data_stream_properties {
-#define USB_BULK  1
-#define USB_ISOC  2
-       u8 type;
-       u8 count;
-       u8 endpoint;
-
-       union {
-               struct {
-                       unsigned int buffersize; /* per URB */
-               } bulk;
-               struct {
-                       int framesperurb;
-                       int framesize;
-                       int interval;
-               } isoc;
-       } u;
-};
-
-/**
- * properties of dvb usb device adapter
- * @caps: adapter capabilities
- * @pid_filter_count: pid count of adapter pid-filter
- * @pid_filter_ctrl: called to enable/disable pid-filter
- * @pid_filter: called to set/unset pid for filtering
- * @stream: adapter usb stream configuration
- */
-#define MAX_NO_OF_FE_PER_ADAP 3
-struct dvb_usb_adapter_properties {
-#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
-#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
-#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
-       u8 caps;
-
-       u8 pid_filter_count;
-       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
-       int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
-
-       struct usb_data_stream_properties stream;
-};
-
-/**
- * struct dvb_usb_device_properties - properties of a dvb-usb-device
- * @driver_name: name of the owning driver module
- * @owner: owner of the dvb_adapter
- * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
- * @bInterfaceNumber: usb interface number driver binds
- * @size_of_priv: bytes allocated for the driver private data
- * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
- * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
- *  receive
- * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
- * @identify_state: called to determine the firmware state (cold or warm) and
- *  return possible firmware file name to be loaded
- * @firmware: name of the firmware file to be loaded
- * @download_firmware: called to download the firmware
- * @i2c_algo: i2c_algorithm if the device has i2c-adapter
- * @num_adapters: dvb usb device adapter count
- * @get_adapter_count: called to resolve adapter count
- * @adapter: array of all adapter properties of device
- * @power_ctrl: called to enable/disable power of the device
- * @read_config: called to resolve device configuration
- * @read_mac_address: called to resolve adapter mac-address
- * @frontend_attach: called to attach the possible frontends
- * @tuner_attach: called to attach the possible tuners
- * @frontend_ctrl: called to power on/off active frontend
- * @streaming_ctrl: called to start/stop the usb streaming of adapter
- * @init: called after adapters are created in order to finalize device
- *  configuration
- * @exit: called when driver is unloaded
- * @get_rc_config: called to resolve used remote controller configuration
- * @get_stream_config: called to resolve input and output stream configuration
- *  of the adapter just before streaming is started. input stream is transport
- *  stream from the demodulator and output stream is usb stream to host.
- */
-#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
-struct dvb_usb_device_properties {
-       const char *driver_name;
-       struct module *owner;
-       short *adapter_nr;
-
-       u8 bInterfaceNumber;
-       unsigned int size_of_priv;
-       u8 generic_bulk_ctrl_endpoint;
-       u8 generic_bulk_ctrl_endpoint_response;
-       unsigned int generic_bulk_ctrl_delay;
-
-#define WARM                  0
-#define COLD                  1
-       int (*identify_state) (struct dvb_usb_device *, const char **);
-       const char *firmware;
-#define RECONNECTS_USB        1
-       int (*download_firmware) (struct dvb_usb_device *,
-                       const struct firmware *);
-
-       struct i2c_algorithm *i2c_algo;
-
-       unsigned int num_adapters;
-       int (*get_adapter_count) (struct dvb_usb_device *);
-       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-       int (*power_ctrl) (struct dvb_usb_device *, int);
-       int (*read_config) (struct dvb_usb_device *d);
-       int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
-       int (*frontend_attach) (struct dvb_usb_adapter *);
-       int (*tuner_attach) (struct dvb_usb_adapter *);
-       int (*frontend_ctrl) (struct dvb_frontend *, int);
-       int (*streaming_ctrl) (struct dvb_frontend *, int);
-       int (*init) (struct dvb_usb_device *);
-       void (*exit) (struct dvb_usb_device *);
-       int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
-#define DVB_USB_FE_TS_TYPE_188        0
-#define DVB_USB_FE_TS_TYPE_204        1
-#define DVB_USB_FE_TS_TYPE_RAW        2
-       int (*get_stream_config) (struct dvb_frontend *,  u8 *,
-                       struct usb_data_stream_properties *);
-};
-
-/**
- * generic object of an usb stream
- * @buf_num: number of buffer allocated
- * @buf_size: size of each buffer in buf_list
- * @buf_list: array containing all allocate buffers for streaming
- * @dma_addr: list of dma_addr_t for each buffer in buf_list
- *
- * @urbs_initialized: number of URBs initialized
- * @urbs_submitted: number of URBs submitted
- */
-#define MAX_NO_URBS_FOR_DATA_STREAM 10
-struct usb_data_stream {
-       struct usb_device *udev;
-       struct usb_data_stream_properties props;
-
-#define USB_STATE_INIT    0x00
-#define USB_STATE_URB_BUF 0x01
-       u8 state;
-
-       void (*complete) (struct usb_data_stream *, u8 *, size_t);
-
-       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       int            buf_num;
-       unsigned long  buf_size;
-       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
-
-       int urbs_initialized;
-       int urbs_submitted;
-
-       void *user_priv;
-};
-
-/**
- * dvb adapter object on dvb usb device
- * @props: pointer to adapter properties
- * @stream: adapter the usb data stream
- * @id: index of this adapter (starting with 0)
- * @ts_type: transport stream, input stream, type
- * @pid_filtering: is hardware pid_filtering used or not
- * @feed_count: current feed count
- * @max_feed_count: maimum feed count device can handle
- * @dvb_adap: adapter dvb_adapter
- * @dmxdev: adapter dmxdev
- * @demux: adapter software demuxer
- * @dvb_net: adapter dvb_net interfaces
- * @sync_mutex: mutex used to sync control and streaming of the adapter
- * @fe: adapter frontends
- * @fe_init: rerouted frontend-init function
- * @fe_sleep: rerouted frontend-sleep function
- */
-struct dvb_usb_adapter {
-       const struct dvb_usb_adapter_properties *props;
-       struct usb_data_stream stream;
-       u8 id;
-       u8 ts_type;
-       bool pid_filtering;
-       u8 feed_count;
-       u8 max_feed_count;
-       s8 active_fe;
-
-       /* dvb */
-       struct dvb_adapter   dvb_adap;
-       struct dmxdev        dmxdev;
-       struct dvb_demux     demux;
-       struct dvb_net       dvb_net;
-       struct mutex         sync_mutex;
-
-       struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
-       int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
-       int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
-};
-
-/**
- * dvb usb device object
- * @props: device properties
- * @name: device name
- * @rc_map: name of rc codes table
- * @udev: pointer to the device's struct usb_device
- * @intf: pointer to the device's usb interface
- * @rc: remote controller configuration
- * @probe_work: work to defer .probe()
- * @powered: indicated whether the device is power or not
- * @usb_mutex: mutex for usb control messages
- * @i2c_mutex: mutex for i2c-transfers
- * @i2c_adap: device's i2c-adapter
- * @rc_dev: rc device for the remote control
- * @rc_query_work: work for polling remote
- * @priv: private data of the actual driver (allocate by dvb usb, size defined
- *  in size_of_priv of dvb_usb_properties).
- */
-struct dvb_usb_device {
-       const struct dvb_usb_device_properties *props;
-       const char *name;
-       const char *rc_map;
-
-       struct usb_device *udev;
-       struct usb_interface *intf;
-       struct dvb_usb_rc rc;
-       struct work_struct probe_work;
-       pid_t work_pid;
-       int powered;
-
-       /* locking */
-       struct mutex usb_mutex;
-
-       /* i2c */
-       struct mutex i2c_mutex;
-       struct i2c_adapter i2c_adap;
-
-       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-
-       /* remote control */
-       struct rc_dev *rc_dev;
-       char rc_phys[64];
-       struct delayed_work rc_query_work;
-
-       void *priv;
-};
-
-extern int dvb_usbv2_probe(struct usb_interface *,
-               const struct usb_device_id *);
-extern void dvb_usbv2_disconnect(struct usb_interface *);
-extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
-extern int dvb_usbv2_resume(struct usb_interface *);
-
-/* the generic read/write method for device control */
-extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
-extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h b/drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h
deleted file mode 100644 (file)
index 45f0709..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DVB_USB_COMMON_H
-#define DVB_USB_COMMON_H
-
-#include "dvb_usb.h"
-
-/* commonly used  methods */
-extern int usb_urb_initv2(struct usb_data_stream *stream,
-               const struct usb_data_stream_properties *props);
-extern int usb_urb_exitv2(struct usb_data_stream *stream);
-extern int usb_urb_submitv2(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props);
-extern int usb_urb_killv2(struct usb_data_stream *stream);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c
deleted file mode 100644 (file)
index a72f9c7..0000000
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "dvb_usb_common.h"
-
-int dvb_usbv2_disable_rc_polling;
-module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
-MODULE_PARM_DESC(disable_rc_polling,
-               "disable remote control polling (default: 0)");
-static int dvb_usb_force_pid_filter_usage;
-module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
-               int, 0444);
-MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
-               "PID filter, if any (default: 0)");
-
-static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
-{
-       int ret;
-       const struct firmware *fw;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (!d->props->download_firmware) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       ret = request_firmware(&fw, name, &d->udev->dev);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
-                               "'%s'. Please see linux/Documentation/dvb/ " \
-                               "for more details on firmware-problems. " \
-                               "Status %d\n", KBUILD_MODNAME, name, ret);
-               goto err;
-       }
-
-       dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
-                       KBUILD_MODNAME, name);
-
-       ret = d->props->download_firmware(d, fw);
-       release_firmware(fw);
-       if (ret < 0)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
-{
-       int ret;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (!d->props->i2c_algo)
-               return 0;
-
-       strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
-       d->i2c_adap.algo = d->props->i2c_algo;
-       d->i2c_adap.dev.parent = &d->udev->dev;
-       i2c_set_adapdata(&d->i2c_adap, d);
-
-       ret = i2c_add_adapter(&d->i2c_adap);
-       if (ret < 0) {
-               d->i2c_adap.algo = NULL;
-               dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (d->i2c_adap.algo)
-               i2c_del_adapter(&d->i2c_adap);
-
-       return 0;
-}
-
-static void dvb_usb_read_remote_control(struct work_struct *work)
-{
-       struct dvb_usb_device *d = container_of(work,
-                       struct dvb_usb_device, rc_query_work.work);
-       int ret;
-
-       /*
-        * When the parameter has been set to 1 via sysfs while the
-        * driver was running, or when bulk mode is enabled after IR init.
-        */
-       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
-               return;
-
-       ret = d->rc.query(d);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               return; /* stop polling */
-       }
-
-       schedule_delayed_work(&d->rc_query_work,
-                       msecs_to_jiffies(d->rc.interval));
-}
-
-static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
-{
-       int ret;
-       struct rc_dev *dev;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
-               return 0;
-
-       d->rc.map_name = d->rc_map;
-       ret = d->props->get_rc_config(d, &d->rc);
-       if (ret < 0)
-               goto err;
-
-       /* disable rc when there is no keymap defined */
-       if (!d->rc.map_name)
-               return 0;
-
-       dev = rc_allocate_device();
-       if (!dev) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       dev->dev.parent = &d->udev->dev;
-       dev->input_name = d->name;
-       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-       dev->input_phys = d->rc_phys;
-       usb_to_input_id(d->udev, &dev->input_id);
-       /* TODO: likely RC-core should took const char * */
-       dev->driver_name = (char *) d->props->driver_name;
-       dev->map_name = d->rc.map_name;
-       dev->driver_type = d->rc.driver_type;
-       dev->allowed_protos = d->rc.allowed_protos;
-       dev->change_protocol = d->rc.change_protocol;
-       dev->priv = d;
-
-       ret = rc_register_device(dev);
-       if (ret < 0) {
-               rc_free_device(dev);
-               goto err;
-       }
-
-       d->rc_dev = dev;
-
-       /* start polling if needed */
-       if (d->rc.query && !d->rc.bulk_mode) {
-               /* initialize a work queue for handling polling */
-               INIT_DELAYED_WORK(&d->rc_query_work,
-                               dvb_usb_read_remote_control);
-               dev_info(&d->udev->dev, "%s: schedule remote query interval " \
-                               "to %d msecs\n", KBUILD_MODNAME,
-                               d->rc.interval);
-               schedule_delayed_work(&d->rc_query_work,
-                               msecs_to_jiffies(d->rc.interval));
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (d->rc_dev) {
-               cancel_delayed_work_sync(&d->rc_query_work);
-               rc_unregister_device(d->rc_dev);
-               d->rc_dev = NULL;
-       }
-
-       return 0;
-}
-
-static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_204(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
-}
-
-int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       adap->stream.udev = adap_to_d(adap)->udev;
-       adap->stream.user_priv = adap;
-       adap->stream.complete = dvb_usb_data_complete;
-
-       return usb_urb_initv2(&adap->stream, &adap->props->stream);
-}
-
-int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       return usb_urb_exitv2(&adap->stream);
-}
-
-static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
-               int count)
-{
-       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
-                       "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
-                       __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
-                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
-                       dvbdmxfeed->pid, dvbdmxfeed->index,
-                       (count == 1) ? "on" : "off");
-
-       if (adap->active_fe == -1)
-               return -EINVAL;
-
-       adap->feed_count += count;
-
-       /* stop feeding if it is last pid */
-       if (adap->feed_count == 0) {
-               dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
-               usb_urb_killv2(&adap->stream);
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(
-                                       adap->fe[adap->active_fe], 0);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-               mutex_unlock(&adap->sync_mutex);
-       }
-
-       /* activate the pid on the device pid filter */
-       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                       adap->pid_filtering &&
-                       adap->props->pid_filter)
-               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
-                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
-                       if (ret < 0)
-                               dev_err(&d->udev->dev, "%s: pid_filter() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-
-       /* start feeding if it is first pid */
-       if (adap->feed_count == 1 && count == 1) {
-               struct usb_data_stream_properties stream_props;
-               mutex_lock(&adap->sync_mutex);
-               dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
-
-               /* resolve input and output streaming paramters */
-               if (d->props->get_stream_config) {
-                       memcpy(&stream_props, &adap->props->stream,
-                               sizeof(struct usb_data_stream_properties));
-                       ret = d->props->get_stream_config(
-                                       adap->fe[adap->active_fe],
-                                       &adap->ts_type, &stream_props);
-                       if (ret < 0)
-                               goto err_mutex_unlock;
-               } else {
-                       stream_props = adap->props->stream;
-               }
-
-               switch (adap->ts_type) {
-               case DVB_USB_FE_TS_TYPE_204:
-                       adap->stream.complete = dvb_usb_data_complete_204;
-                       break;
-               case DVB_USB_FE_TS_TYPE_RAW:
-                       adap->stream.complete = dvb_usb_data_complete_raw;
-                       break;
-               case DVB_USB_FE_TS_TYPE_188:
-               default:
-                       adap->stream.complete = dvb_usb_data_complete;
-                       break;
-               }
-
-               usb_urb_submitv2(&adap->stream, &stream_props);
-
-               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                               adap->props->caps &
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
-                               adap->props->pid_filter_ctrl) {
-                       ret = adap->props->pid_filter_ctrl(adap,
-                                       adap->pid_filtering);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: " \
-                                               "pid_filter_ctrl() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(
-                                       adap->fe[adap->active_fe], 1);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-       }
-
-       return 0;
-err_mutex_unlock:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
-}
-
-static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
-}
-
-int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
-
-       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
-                       &d->udev->dev, d->props->adapter_nr);
-       if (ret < 0) {
-               dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
-                               __func__, ret);
-               goto err_dvb_register_adapter;
-       }
-
-       adap->dvb_adap.priv = adap;
-
-       if (d->props->read_mac_address) {
-               ret = d->props->read_mac_address(adap,
-                               adap->dvb_adap.proposed_mac);
-               if (ret < 0)
-                       goto err_dvb_dmx_init;
-
-               dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
-                               KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
-       }
-
-       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       adap->demux.priv             = adap;
-       adap->demux.filternum        = 0;
-       adap->demux.filternum        = adap->max_feed_count;
-       adap->demux.feednum          = adap->demux.filternum;
-       adap->demux.start_feed       = dvb_usb_start_feed;
-       adap->demux.stop_feed        = dvb_usb_stop_feed;
-       adap->demux.write_to_decoder = NULL;
-       ret = dvb_dmx_init(&adap->demux);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_dmx_init;
-       }
-
-       adap->dmxdev.filternum       = adap->demux.filternum;
-       adap->dmxdev.demux           = &adap->demux.dmx;
-       adap->dmxdev.capabilities    = 0;
-       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_dmxdev_init;
-       }
-
-       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_net_init;
-       }
-
-       mutex_init(&adap->sync_mutex);
-
-       return 0;
-err_dvb_net_init:
-       dvb_dmxdev_release(&adap->dmxdev);
-err_dvb_dmxdev_init:
-       dvb_dmx_release(&adap->demux);
-err_dvb_dmx_init:
-       dvb_unregister_adapter(&adap->dvb_adap);
-err_dvb_register_adapter:
-       adap->dvb_adap.priv = NULL;
-       return ret;
-}
-
-int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       if (adap->dvb_adap.priv) {
-               dvb_net_release(&adap->dvb_net);
-               adap->demux.dmx.close(&adap->demux.dmx);
-               dvb_dmxdev_release(&adap->dmxdev);
-               dvb_dmx_release(&adap->demux);
-               dvb_unregister_adapter(&adap->dvb_adap);
-       }
-
-       return 0;
-}
-
-int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-
-       if (onoff)
-               d->powered++;
-       else
-               d->powered--;
-
-       if (d->powered == 0 || (onoff && d->powered == 1)) {
-               /* when switching from 1 to 0 or from 0 to 1 */
-               dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
-               if (d->props->power_ctrl) {
-                       ret = d->props->power_ctrl(d, onoff);
-                       if (ret < 0)
-                               goto err;
-               }
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_fe_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
-                       fe->id);
-
-       ret = dvb_usbv2_device_power_ctrl(d, 1);
-       if (ret < 0)
-               goto err;
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 1);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (adap->fe_init[fe->id]) {
-               ret = adap->fe_init[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       adap->active_fe = fe->id;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
-                       fe->id);
-
-       if (adap->fe_sleep[fe->id]) {
-               ret = adap->fe_sleep[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 0);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_device_power_ctrl(d, 0);
-       if (ret < 0)
-               goto err;
-
-       adap->active_fe = -1;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
-{
-       int ret, i, count_registered = 0;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
-
-       memset(adap->fe, 0, sizeof(adap->fe));
-       adap->active_fe = -1;
-
-       if (d->props->frontend_attach) {
-               ret = d->props->frontend_attach(adap);
-               if (ret < 0) {
-                       dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
-                                       "failed=%d\n", __func__, ret);
-                       goto err_dvb_frontend_detach;
-               }
-       } else {
-               dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
-                               __func__);
-               ret = 0;
-               goto err;
-       }
-
-       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
-               adap->fe[i]->id = i;
-               /* re-assign sleep and wakeup functions */
-               adap->fe_init[i] = adap->fe[i]->ops.init;
-               adap->fe[i]->ops.init = dvb_usb_fe_init;
-               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
-               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
-
-               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
-               if (ret < 0) {
-                       dev_err(&d->udev->dev, "%s: frontend%d registration " \
-                                       "failed\n", KBUILD_MODNAME, i);
-                       goto err_dvb_unregister_frontend;
-               }
-
-               count_registered++;
-       }
-
-       if (d->props->tuner_attach) {
-               ret = d->props->tuner_attach(adap);
-               if (ret < 0) {
-                       dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
-                                       __func__, ret);
-                       goto err_dvb_unregister_frontend;
-               }
-       }
-
-       return 0;
-
-err_dvb_unregister_frontend:
-       for (i = count_registered - 1; i >= 0; i--)
-               dvb_unregister_frontend(adap->fe[i]);
-
-err_dvb_frontend_detach:
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i])
-                       dvb_frontend_detach(adap->fe[i]);
-       }
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
-{
-       int i;
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i]) {
-                       dvb_unregister_frontend(adap->fe[i]);
-                       dvb_frontend_detach(adap->fe[i]);
-               }
-       }
-
-       return 0;
-}
-
-static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
-{
-       struct dvb_usb_adapter *adap;
-       int ret, i, adapter_count;
-
-       /* resolve adapter count */
-       adapter_count = d->props->num_adapters;
-       if (d->props->get_adapter_count) {
-               ret = d->props->get_adapter_count(d);
-               if (ret < 0)
-                       goto err;
-
-               adapter_count = ret;
-       }
-
-       for (i = 0; i < adapter_count; i++) {
-               adap = &d->adapter[i];
-               adap->id = i;
-               adap->props = &d->props->adapter[i];
-
-               /* speed - when running at FULL speed we need a HW PID filter */
-               if (d->udev->speed == USB_SPEED_FULL &&
-                               !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
-                       dev_err(&d->udev->dev, "%s: this USB2.0 device " \
-                                       "cannot be run on a USB1.1 port (it " \
-                                       "lacks a hardware PID filter)\n",
-                                       KBUILD_MODNAME);
-                       ret = -ENODEV;
-                       goto err;
-               } else if ((d->udev->speed == USB_SPEED_FULL &&
-                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
-                               (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
-                       dev_info(&d->udev->dev, "%s: will use the device's " \
-                                       "hardware PID filter " \
-                                       "(table count: %d)\n", KBUILD_MODNAME,
-                                       adap->props->pid_filter_count);
-                       adap->pid_filtering  = 1;
-                       adap->max_feed_count = adap->props->pid_filter_count;
-               } else {
-                       dev_info(&d->udev->dev, "%s: will pass the complete " \
-                                       "MPEG2 transport stream to the " \
-                                       "software demuxer\n", KBUILD_MODNAME);
-                       adap->pid_filtering  = 0;
-                       adap->max_feed_count = 255;
-               }
-
-               if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
-                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
-                       dev_info(&d->udev->dev, "%s: PID filter enabled by " \
-                                       "module option\n", KBUILD_MODNAME);
-                       adap->pid_filtering  = 1;
-                       adap->max_feed_count = adap->props->pid_filter_count;
-               }
-
-               ret = dvb_usbv2_adapter_stream_init(adap);
-               if (ret)
-                       goto err;
-
-               ret = dvb_usbv2_adapter_dvb_init(adap);
-               if (ret)
-                       goto err;
-
-               ret = dvb_usbv2_adapter_frontend_init(adap);
-               if (ret)
-                       goto err;
-
-               /* use exclusive FE lock if there is multiple shared FEs */
-               if (adap->fe[1])
-                       adap->dvb_adap.mfe_shared = 1;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
-{
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
-               if (d->adapter[i].props) {
-                       dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
-                       dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
-                       dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
-               }
-       }
-
-       return 0;
-}
-
-/* general initialization functions */
-static int dvb_usbv2_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       dvb_usbv2_remote_exit(d);
-       dvb_usbv2_adapter_exit(d);
-       dvb_usbv2_i2c_exit(d);
-       kfree(d->priv);
-       kfree(d);
-
-       return 0;
-}
-
-static int dvb_usbv2_init(struct dvb_usb_device *d)
-{
-       int ret;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       dvb_usbv2_device_power_ctrl(d, 1);
-
-       if (d->props->read_config) {
-               ret = d->props->read_config(d);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_i2c_init(d);
-       if (ret < 0)
-               goto err;
-
-       ret = dvb_usbv2_adapter_init(d);
-       if (ret < 0)
-               goto err;
-
-       if (d->props->init) {
-               ret = d->props->init(d);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_remote_init(d);
-       if (ret < 0)
-               goto err;
-
-       dvb_usbv2_device_power_ctrl(d, 0);
-
-       return 0;
-err:
-       dvb_usbv2_device_power_ctrl(d, 0);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-/*
- * udev, which is used for the firmware downloading, requires we cannot
- * block during module_init(). module_init() calls USB probe() which
- * is this routine. Due to that we delay actual operation using workqueue
- * and return always success here.
- */
-static void dvb_usbv2_init_work(struct work_struct *work)
-{
-       int ret;
-       struct dvb_usb_device *d =
-                       container_of(work, struct dvb_usb_device, probe_work);
-
-       d->work_pid = current->pid;
-       dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
-
-       if (d->props->size_of_priv) {
-               d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
-               if (!d->priv) {
-                       dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
-                                       KBUILD_MODNAME);
-                       ret = -ENOMEM;
-                       goto err_usb_driver_release_interface;
-               }
-       }
-
-       if (d->props->identify_state) {
-               const char *name = NULL;
-               ret = d->props->identify_state(d, &name);
-               if (ret == 0) {
-                       ;
-               } else if (ret == COLD) {
-                       dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
-                                       "state\n", KBUILD_MODNAME, d->name);
-
-                       if (!name)
-                               name = d->props->firmware;
-
-                       ret = dvb_usbv2_download_firmware(d, name);
-                       if (ret == 0) {
-                               /* device is warm, continue initialization */
-                               ;
-                       } else if (ret == RECONNECTS_USB) {
-                               /*
-                                * USB core will call disconnect() and then
-                                * probe() as device reconnects itself from the
-                                * USB bus. disconnect() will release all driver
-                                * resources and probe() is called for 'new'
-                                * device. As 'new' device is warm we should
-                                * never go here again.
-                                */
-                               return;
-                       } else {
-                               /*
-                                * Unexpected error. We must unregister driver
-                                * manually from the device, because device is
-                                * already register by returning from probe()
-                                * with success. usb_driver_release_interface()
-                                * finally calls disconnect() in order to free
-                                * resources.
-                                */
-                               goto err_usb_driver_release_interface;
-                       }
-               } else {
-                       goto err_usb_driver_release_interface;
-               }
-       }
-
-       dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
-                       KBUILD_MODNAME, d->name);
-
-       ret = dvb_usbv2_init(d);
-       if (ret < 0)
-               goto err_usb_driver_release_interface;
-
-       dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
-                       "connected\n", KBUILD_MODNAME, d->name);
-
-       return;
-err_usb_driver_release_interface:
-       dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
-                       KBUILD_MODNAME, d->name, ret);
-       usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
-                       d->intf);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return;
-}
-
-int dvb_usbv2_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       int ret;
-       struct dvb_usb_device *d;
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct dvb_usb_driver_info *driver_info =
-                       (struct dvb_usb_driver_info *) id->driver_info;
-
-       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
-                       intf->cur_altsetting->desc.bInterfaceNumber);
-
-       if (!id->driver_info) {
-               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
-       if (!d) {
-               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       d->name = driver_info->name;
-       d->rc_map = driver_info->rc_map;
-       d->udev = udev;
-       d->intf = intf;
-       d->props = driver_info->props;
-
-       if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
-                       d->props->bInterfaceNumber) {
-               ret = -ENODEV;
-               goto err_kfree;
-       }
-
-       mutex_init(&d->usb_mutex);
-       mutex_init(&d->i2c_mutex);
-       INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
-       usb_set_intfdata(intf, d);
-       ret = schedule_work(&d->probe_work);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
-                               KBUILD_MODNAME);
-               goto err_kfree;
-       }
-
-       return 0;
-err_kfree:
-       kfree(d);
-err:
-       dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usbv2_probe);
-
-void dvb_usbv2_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       const char *name = d->name;
-       struct device dev = d->udev->dev;
-       dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
-                       current->pid, d->work_pid);
-
-       /* ensure initialization work is finished until release resources */
-       if (d->work_pid != current->pid)
-               cancel_work_sync(&d->probe_work);
-
-       if (d->props->exit)
-               d->props->exit(d);
-
-       dvb_usbv2_exit(d);
-
-       dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
-                       KBUILD_MODNAME, name);
-}
-EXPORT_SYMBOL(dvb_usbv2_disconnect);
-
-int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* stop remote controller poll */
-       if (d->rc.query && !d->rc.bulk_mode)
-               cancel_delayed_work_sync(&d->rc_query_work);
-
-       /* stop streaming */
-       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
-               if (d->adapter[i].dvb_adap.priv &&
-                               d->adapter[i].active_fe != -1)
-                       usb_urb_killv2(&d->adapter[i].stream);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(dvb_usbv2_suspend);
-
-int dvb_usbv2_resume(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* start streaming */
-       for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
-               if (d->adapter[i].dvb_adap.priv &&
-                               d->adapter[i].active_fe != -1)
-                       usb_urb_submitv2(&d->adapter[i].stream, NULL);
-       }
-
-       /* start remote controller poll */
-       if (d->rc.query && !d->rc.bulk_mode)
-               schedule_delayed_work(&d->rc_query_work,
-                               msecs_to_jiffies(d->rc.interval));
-
-       return 0;
-}
-EXPORT_SYMBOL(dvb_usbv2_resume);
-
-MODULE_VERSION("2.0");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("DVB USB common");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c
deleted file mode 100644 (file)
index 0431bee..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "dvb_usb_common.h"
-
-int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
-               u16 rlen)
-{
-       int ret, actual_length;
-
-       if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
-                       !d->props->generic_bulk_ctrl_endpoint_response) {
-               dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
-               return -EINVAL;
-       }
-
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-       if (ret < 0)
-               return ret;
-
-       dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
-
-       ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
-                       d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
-                       &actual_length, 2000);
-       if (ret < 0)
-               dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-       else
-               ret = actual_length != wlen ? -EIO : 0;
-
-       /* an answer is expected, and no error before */
-       if (!ret && rbuf && rlen) {
-               if (d->props->generic_bulk_ctrl_delay)
-                       usleep_range(d->props->generic_bulk_ctrl_delay,
-                                       d->props->generic_bulk_ctrl_delay
-                                       + 20000);
-
-               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
-                               d->props->generic_bulk_ctrl_endpoint_response),
-                               rbuf, rlen, &actual_length, 2000);
-               if (ret)
-                       dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
-                                       "failed=%d\n", KBUILD_MODNAME, ret);
-
-               dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
-                               actual_length, rbuf);
-       }
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usbv2_generic_rw);
-
-int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
-{
-       return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
-}
-EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/dvb/dvb-usb-v2/ec168.c b/drivers/media/dvb/dvb-usb-v2/ec168.c
deleted file mode 100644 (file)
index ab77622..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * E3C EC168 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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 "ec168.h"
-#include "ec100.h"
-#include "mxl5005s.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
-{
-       int ret;
-       unsigned int pipe;
-       u8 request, requesttype;
-       u8 *buf;
-
-       switch (req->cmd) {
-       case DOWNLOAD_FIRMWARE:
-       case GPIO:
-       case WRITE_I2C:
-       case STREAMING_CTRL:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = req->cmd;
-               break;
-       case READ_I2C:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = req->cmd;
-               break;
-       case GET_CONFIG:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = CONFIG;
-               break;
-       case SET_CONFIG:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = CONFIG;
-               break;
-       case WRITE_DEMOD:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = DEMOD_RW;
-               break;
-       case READ_DEMOD:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = DEMOD_RW;
-               break;
-       default:
-               pr_err("%s: unknown command=%02x\n", KBUILD_MODNAME, req->cmd);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       buf = kmalloc(req->size, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
-               /* write */
-               memcpy(buf, req->data, req->size);
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {
-               /* read */
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
-               req->index, buf, req->size, EC168_USB_TIMEOUT);
-
-       ec168_debug_dump(request, requesttype, req->value, req->index, buf,
-               req->size);
-
-       if (ret < 0)
-               goto err_dealloc;
-       else
-               ret = 0;
-
-       /* read request, copy returned data to return buf */
-       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
-               memcpy(req->data, buf, req->size);
-
-       kfree(buf);
-       return ret;
-
-err_dealloc:
-       kfree(buf);
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-/* I2C */
-static struct ec100_config ec168_ec100_config;
-
-static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct ec168_req req;
-       int i = 0;
-       int ret;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].addr == ec168_ec100_config.demod_address) {
-                               req.cmd = READ_DEMOD;
-                               req.value = 0;
-                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
-                               req.size = msg[i+1].len; /* bytes to read */
-                               req.data = &msg[i+1].buf[0];
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 2;
-                       } else {
-                               pr_err("%s: I2C read not implemented\n",
-                                               KBUILD_MODNAME);
-                               ret = -EOPNOTSUPP;
-                               i += 2;
-                       }
-               } else {
-                       if (msg[i].addr == ec168_ec100_config.demod_address) {
-                               req.cmd = WRITE_DEMOD;
-                               req.value = msg[i].buf[1]; /* val */
-                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
-                               req.size = 0;
-                               req.data = NULL;
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 1;
-                       } else {
-                               req.cmd = WRITE_I2C;
-                               req.value = msg[i].buf[0]; /* val */
-                               req.index = 0x0100 + msg[i].addr; /* I2C addr */
-                               req.size = msg[i].len-1;
-                               req.data = &msg[i].buf[1];
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 1;
-                       }
-               }
-               if (ret)
-                       goto error;
-
-       }
-       ret = i;
-
-error:
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 ec168_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm ec168_i2c_algo = {
-       .master_xfer   = ec168_i2c_xfer,
-       .functionality = ec168_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 reply;
-       struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
-       pr_debug("%s:\n", __func__);
-
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       pr_debug("%s: reply=%02x\n", __func__, reply);
-
-       if (reply == 0x01)
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec168_download_firmware(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, len, remaining;
-       struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
-       pr_debug("%s:\n", __func__);
-
-       #define LEN_MAX 2048 /* max packet size */
-       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-               len = remaining;
-               if (len > LEN_MAX)
-                       len = LEN_MAX;
-
-               req.size = len;
-               req.data = (u8 *) &fw->data[fw->size - remaining];
-               req.index = fw->size - remaining;
-
-               ret = ec168_ctrl_msg(d, &req);
-               if (ret) {
-                       pr_err("%s: firmware download failed=%d\n",
-                                       KBUILD_MODNAME, ret);
-                       goto error;
-               }
-       }
-
-       req.size = 0;
-
-       /* set "warm"? */
-       req.cmd = SET_CONFIG;
-       req.value = 0;
-       req.index = 0x0001;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       /* really needed - no idea what does */
-       req.cmd = GPIO;
-       req.value = 0;
-       req.index = 0x0206;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       /* activate tuner I2C? */
-       req.cmd = WRITE_I2C;
-       req.value = 0;
-       req.index = 0x00c6;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static struct ec100_config ec168_ec100_config = {
-       .demod_address = 0xff, /* not real address, demod is integrated */
-};
-
-static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-       adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct mxl5005s_config ec168_mxl5003s_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_OFF,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-       return dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
-}
-
-static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
-       pr_debug("%s: onoff=%d\n", __func__, onoff);
-       if (onoff)
-               req.index = 0x0102;
-       return ec168_ctrl_msg(fe_to_d(fe), &req);
-}
-
-/* DVB USB Driver stuff */
-/* bInterfaceNumber 0 is HID
- * bInterfaceNumber 1 is DVB-T */
-static struct dvb_usb_device_properties ec168_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .bInterfaceNumber = 1,
-
-       .identify_state = ec168_identify_state,
-       .firmware = "dvb-usb-ec168.fw",
-       .download_firmware = ec168_download_firmware,
-
-       .i2c_algo = &ec168_i2c_algo,
-       .frontend_attach = ec168_ec100_frontend_attach,
-       .tuner_attach = ec168_mxl5003s_tuner_attach,
-       .streaming_ctrl = ec168_streaming_ctrl,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
-               }
-       },
-};
-
-static const struct dvb_usb_driver_info ec168_driver_info = {
-       .name = "E3C EC168 reference design",
-       .props = &ec168_props,
-};
-
-static const struct usb_device_id ec168_id[] = {
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       {}
-};
-MODULE_DEVICE_TABLE(usb, ec168_id);
-
-static struct usb_driver ec168_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = ec168_id,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(ec168_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("E3C EC168 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/ec168.h b/drivers/media/dvb/dvb-usb-v2/ec168.h
deleted file mode 100644 (file)
index 9181236..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * E3C EC168 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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 EC168_H
-#define EC168_H
-
-#include "dvb_usb.h"
-
-#define ec168_debug_dump(r, t, v, i, b, l) { \
-       char *direction; \
-       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
-               direction = ">>>"; \
-       else \
-               direction = "<<<"; \
-       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s\n", \
-                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
-                       l & 0xff, l >> 8, direction); \
-}
-
-#define EC168_USB_TIMEOUT 1000
-
-struct ec168_req {
-       u8  cmd;       /* [1] */
-       u16 value;     /* [2|3] */
-       u16 index;     /* [4|5] */
-       u16 size;      /* [6|7] */
-       u8  *data;
-};
-
-enum ec168_cmd {
-       DOWNLOAD_FIRMWARE    = 0x00,
-       CONFIG               = 0x01,
-       DEMOD_RW             = 0x03,
-       GPIO                 = 0x04,
-       STREAMING_CTRL       = 0x10,
-       READ_I2C             = 0x20,
-       WRITE_I2C            = 0x21,
-       HID_DOWNLOAD         = 0x30,
-       GET_CONFIG,
-       SET_CONFIG,
-       READ_DEMOD,
-       WRITE_DEMOD,
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/gl861.c b/drivers/media/dvb/dvb-usb-v2/gl861.c
deleted file mode 100644 (file)
index cf29f43..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* DVB USB compliant linux driver for GL861 USB2.0 devices.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "gl861.h"
-
-#include "zl10353.h"
-#include "qt1010.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u16 index;
-       u16 value = addr << (8 + 1);
-       int wo = (rbuf == NULL || rlen == 0); /* write-only */
-       u8 req, type;
-
-       if (wo) {
-               req = GL861_REQ_I2C_WRITE;
-               type = GL861_WRITE;
-       } else { /* rw */
-               req = GL861_REQ_I2C_READ;
-               type = GL861_READ;
-       }
-
-       switch (wlen) {
-       case 1:
-               index = wbuf[0];
-               break;
-       case 2:
-               index = wbuf[0];
-               value = value + wbuf[1];
-               break;
-       default:
-               pr_err("%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen);
-               return -EINVAL;
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
-                              value, index, rbuf, rlen, 2000);
-}
-
-/* I2C */
-static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
-                               msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
-                               break;
-                       i++;
-               } else
-                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                         msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 gl861_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm gl861_i2c_algo = {
-       .master_xfer   = gl861_i2c_xfer,
-       .functionality = gl861_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config gl861_zl10353_config = {
-       .demod_address = 0x0f,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
-{
-
-       adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
-               &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static struct qt1010_config gl861_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(qt1010_attach,
-                         adap->fe[0], &adap_to_d(adap)->i2c_adap,
-                         &gl861_qt1010_config) == NULL ? -ENODEV : 0;
-}
-
-static int gl861_init(struct dvb_usb_device *d)
-{
-       /*
-        * There is 2 interfaces. Interface 0 is for TV and interface 1 is
-        * for HID remote controller. Interface 0 has 2 alternate settings.
-        * For some reason we need to set interface explicitly, defaulted
-        * as alternate setting 1?
-        */
-       return usb_set_interface(d->udev, 0, 0);
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties gl861_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-
-       .i2c_algo = &gl861_i2c_algo,
-       .frontend_attach = gl861_frontend_attach,
-       .tuner_attach = gl861_tuner_attach,
-       .init = gl861_init,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
-               }
-       }
-};
-
-static const struct usb_device_id gl861_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
-               &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
-       { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
-               &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, gl861_id_table);
-
-static struct usb_driver gl861_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = gl861_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(gl861_usb_driver);
-
-MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
-MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/gl861.h b/drivers/media/dvb/dvb-usb-v2/gl861.h
deleted file mode 100644 (file)
index b0b80d8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _DVB_USB_GL861_H_
-#define _DVB_USB_GL861_H_
-
-#include "dvb_usb.h"
-
-#define GL861_WRITE            0x40
-#define GL861_READ             0xc0
-
-#define GL861_REQ_I2C_WRITE    0x01
-#define GL861_REQ_I2C_READ     0x02
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/it913x.c b/drivers/media/dvb/dvb-usb-v2/it913x.c
deleted file mode 100644 (file)
index 695f910..0000000
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * DVB USB compliant linux driver for ITE IT9135 and IT9137
- *
- * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
- * IT9135 (C) ITE Tech Inc.
- * IT9137 (C) ITE Tech Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * see Documentation/dvb/README.dvb-usb for more information
- * see Documentation/dvb/it9137.txt for firmware information
- *
- */
-#define DVB_USB_LOG_PREFIX "it913x"
-
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <media/rc-core.h>
-
-#include "dvb_usb.h"
-#include "it913x-fe.h"
-
-/* debug */
-static int dvb_usb_it913x_debug;
-#define it_debug(var, level, args...) \
-       do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \
-} while (0)
-#define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args)
-#define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args)
-
-module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-static int dvb_usb_it913x_firmware;
-module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
-       "1=IT9137 2=IT9135 V1 3=IT9135 V2");
-#define FW_IT9137 "dvb-usb-it9137-01.fw"
-#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
-#define FW_IT9135_V2 "dvb-usb-it9135-02.fw"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct it913x_state {
-       struct ite_config it913x_config;
-       u8 pid_filter_onoff;
-       bool proprietary_ir;
-       int cmd_counter;
-};
-
-static u16 check_sum(u8 *p, u8 len)
-{
-       u16 sum = 0;
-       u8 i = 1;
-       while (i < len)
-               sum += (i++ & 1) ? (*p++) << 8 : *p++;
-       return ~sum;
-}
-
-static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro,
-                       u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
-{
-       struct it913x_state *st = d->priv;
-       int ret = 0, i, buf_size = 1;
-       u8 *buff;
-       u8 rlen;
-       u16 chk_sum;
-
-       buff = kzalloc(256, GFP_KERNEL);
-       if (!buff) {
-               info("USB Buffer Failed");
-               return -ENOMEM;
-       }
-
-       buff[buf_size++] = pro;
-       buff[buf_size++] = cmd;
-       buff[buf_size++] = st->cmd_counter;
-
-       switch (mode) {
-       case READ_LONG:
-       case WRITE_LONG:
-               buff[buf_size++] = len;
-               buff[buf_size++] = 2;
-               buff[buf_size++] = (reg >> 24);
-               buff[buf_size++] = (reg >> 16) & 0xff;
-               buff[buf_size++] = (reg >> 8) & 0xff;
-               buff[buf_size++] = reg & 0xff;
-       break;
-       case READ_SHORT:
-               buff[buf_size++] = addr;
-               break;
-       case WRITE_SHORT:
-               buff[buf_size++] = len;
-               buff[buf_size++] = addr;
-               buff[buf_size++] = (reg >> 8) & 0xff;
-               buff[buf_size++] = reg & 0xff;
-       break;
-       case READ_DATA:
-       case WRITE_DATA:
-               break;
-       case WRITE_CMD:
-               mode = 7;
-               break;
-       default:
-               kfree(buff);
-               return -EINVAL;
-       }
-
-       if (mode & 1) {
-               for (i = 0; i < len ; i++)
-                       buff[buf_size++] = data[i];
-       }
-       chk_sum = check_sum(&buff[1], buf_size);
-
-       buff[buf_size++] = chk_sum >> 8;
-       buff[0] = buf_size;
-       buff[buf_size++] = (chk_sum & 0xff);
-
-       ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ?
-                       5 : len + 5);
-       if (ret < 0)
-               goto error;
-
-       rlen = (mode & 0x1) ? 0x1 : len;
-
-       if (mode & 1)
-               ret = buff[2];
-       else
-               memcpy(data, &buff[3], rlen);
-
-       st->cmd_counter++;
-
-error: kfree(buff);
-
-       return ret;
-}
-
-static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data)
-{
-       int ret;
-       u8 b[1];
-       b[0] = data;
-       ret = it913x_io(d, WRITE_LONG, pro,
-                       CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
-
-       return ret;
-}
-
-static int it913x_read_reg(struct dvb_usb_device *d, u32 reg)
-{
-       int ret;
-       u8 data[1];
-
-       ret = it913x_io(d, READ_LONG, DEV_0,
-                       CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data));
-
-       return (ret < 0) ? ret : data[0];
-}
-
-static int it913x_query(struct dvb_usb_device *d, u8 pro)
-{
-       struct it913x_state *st = d->priv;
-       int ret, i;
-       u8 data[4];
-       u8 ver;
-
-       for (i = 0; i < 5; i++) {
-               ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ,
-                       0x1222, 0, &data[0], 3);
-               ver = data[0];
-               if (ver > 0 && ver < 3)
-                       break;
-               msleep(100);
-       }
-
-       if (ver < 1 || ver > 2) {
-               info("Failed to identify chip version applying 1");
-               st->it913x_config.chip_ver = 0x1;
-               st->it913x_config.chip_type = 0x9135;
-               return 0;
-       }
-
-       st->it913x_config.chip_ver = ver;
-       st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
-
-       info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver,
-               st->it913x_config.chip_type);
-
-       ret = it913x_io(d, READ_SHORT, pro,
-                       CMD_QUERYINFO, 0, 0x1, &data[0], 4);
-
-       st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) |
-                       (data[2] << 8) | data[3];
-
-       return ret;
-}
-
-static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = adap_to_priv(adap);
-       int ret;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(1, "PID_C  (%02x)", onoff);
-
-       ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff);
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret;
-}
-
-static int it913x_pid_filter(struct dvb_usb_adapter *adap,
-               int index, u16 pid, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = adap_to_priv(adap);
-       int ret;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(1, "PID_F  (%02x)", onoff);
-
-       ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff));
-
-       ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8));
-
-       ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff);
-
-       ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f));
-
-       if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
-                       ret |= it913x_wr_reg(d , pro, PID_EN, !onoff);
-                       st->pid_filter_onoff = !onoff;
-       } else
-               st->pid_filter_onoff =
-                       adap->pid_filtering;
-
-       mutex_unlock(&d->i2c_mutex);
-       return 0;
-}
-
-
-static int it913x_return_status(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       int ret = it913x_query(d, DEV_0);
-       if (st->it913x_config.firmware > 0)
-               info("Firmware Version %d", st->it913x_config.firmware);
-
-       return ret;
-}
-
-static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       static u8 data[256];
-       int ret;
-       u32 reg;
-       u8 pro;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
-
-       pro = (msg[0].addr & 0x2) ?  DEV_0_DMOD : 0x0;
-       pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
-       memcpy(data, msg[0].buf, msg[0].len);
-       reg = (data[0] << 24) + (data[1] << 16) +
-                       (data[2] << 8) + data[3];
-       if (num == 2) {
-               ret = it913x_io(d, READ_LONG, pro,
-                       CMD_DEMOD_READ, reg, 0, data, msg[1].len);
-               memcpy(msg[1].buf, data, msg[1].len);
-       } else
-               ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE,
-                       reg, 0, &data[4], msg[0].len - 4);
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 it913x_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm it913x_i2c_algo = {
-       .master_xfer   = it913x_i2c_xfer,
-       .functionality = it913x_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-#define IT913X_POLL 250
-static int it913x_rc_query(struct dvb_usb_device *d)
-{
-       u8 ibuf[4];
-       int ret;
-       u32 key;
-       /* Avoid conflict with frontends*/
-       mutex_lock(&d->i2c_mutex);
-
-       ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET,
-               0, 0, &ibuf[0], sizeof(ibuf));
-
-       if ((ibuf[2] + ibuf[3]) == 0xff) {
-               key = ibuf[2];
-               key += ibuf[0] << 16;
-               key += ibuf[1] << 8;
-               deb_info(1, "NEC Extended Key =%08x", key);
-               if (d->rc_dev != NULL)
-                       rc_keydown(d->rc_dev, key, 0);
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-/* Firmware sets raw */
-static const char fw_it9135_v1[] = FW_IT9135_V1;
-static const char fw_it9135_v2[] = FW_IT9135_V2;
-static const char fw_it9137[] = FW_IT9137;
-
-static void ite_get_firmware_name(struct dvb_usb_device *d,
-       const char **name)
-{
-       struct it913x_state *st = d->priv;
-       int sw;
-       /* auto switch */
-       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2)
-               sw = IT9137_FW;
-       else if (st->it913x_config.chip_ver == 1)
-               sw = IT9135_V1_FW;
-       else
-               sw = IT9135_V2_FW;
-
-       /* force switch */
-       if (dvb_usb_it913x_firmware != IT9135_AUTO)
-               sw = dvb_usb_it913x_firmware;
-
-       switch (sw) {
-       case IT9135_V1_FW:
-               st->it913x_config.firmware_ver = 1;
-               st->it913x_config.adc_x2 = 1;
-               st->it913x_config.read_slevel = false;
-               *name = fw_it9135_v1;
-               break;
-       case IT9135_V2_FW:
-               st->it913x_config.firmware_ver = 1;
-               st->it913x_config.adc_x2 = 1;
-               st->it913x_config.read_slevel = false;
-               *name = fw_it9135_v2;
-               switch (st->it913x_config.tuner_id_0) {
-               case IT9135_61:
-               case IT9135_62:
-                       break;
-               default:
-                       info("Unknown tuner ID applying default 0x60");
-               case IT9135_60:
-                       st->it913x_config.tuner_id_0 = IT9135_60;
-               }
-               break;
-       case IT9137_FW:
-       default:
-               st->it913x_config.firmware_ver = 0;
-               st->it913x_config.adc_x2 = 0;
-               st->it913x_config.read_slevel = true;
-               *name = fw_it9137;
-       }
-
-       return;
-}
-
-#define TS_MPEG_PKT_SIZE       188
-#define EP_LOW                 21
-#define TS_BUFFER_SIZE_PID     (EP_LOW*TS_MPEG_PKT_SIZE)
-#define EP_HIGH                        348
-#define TS_BUFFER_SIZE_MAX     (EP_HIGH*TS_MPEG_PKT_SIZE)
-
-static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       if (adap->pid_filtering)
-               stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID;
-       else
-               stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX;
-
-       return 0;
-}
-
-static int it913x_select_config(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       int ret, reg;
-
-       ret = it913x_return_status(d);
-       if (ret < 0)
-               return ret;
-
-       if (st->it913x_config.chip_ver == 0x02
-                       && st->it913x_config.chip_type == 0x9135)
-               reg = it913x_read_reg(d, 0x461d);
-       else
-               reg = it913x_read_reg(d, 0x461b);
-
-       if (reg < 0)
-               return reg;
-
-       if (reg == 0) {
-               st->it913x_config.dual_mode = 0;
-               st->it913x_config.tuner_id_0 = IT9135_38;
-               st->proprietary_ir = true;
-       } else {
-               /* TS mode */
-               reg =  it913x_read_reg(d, 0x49c5);
-               if (reg < 0)
-                       return reg;
-               st->it913x_config.dual_mode = reg;
-
-               /* IR mode type */
-               reg = it913x_read_reg(d, 0x49ac);
-               if (reg < 0)
-                       return reg;
-               if (reg == 5) {
-                       info("Remote propriety (raw) mode");
-                       st->proprietary_ir = true;
-               } else if (reg == 1) {
-                       info("Remote HID mode NOT SUPPORTED");
-                       st->proprietary_ir = false;
-               }
-
-               /* Tuner_id */
-               reg = it913x_read_reg(d, 0x49d0);
-               if (reg < 0)
-                       return reg;
-               st->it913x_config.tuner_id_0 = reg;
-       }
-
-       info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode,
-               st->it913x_config.tuner_id_0);
-
-       return ret;
-}
-
-static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = fe_to_priv(fe);
-       int ret = 0;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       deb_info(1, "STM  (%02x)", onoff);
-
-       if (!onoff) {
-               mutex_lock(&d->i2c_mutex);
-
-               ret = it913x_wr_reg(d, pro, PID_RST, 0x1);
-
-               mutex_unlock(&d->i2c_mutex);
-               st->pid_filter_onoff =
-                       adap->pid_filtering;
-
-       }
-
-       return ret;
-}
-
-static int it913x_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       struct it913x_state *st = d->priv;
-       int ret;
-       u8 reg;
-
-       /* Read and select config */
-       ret = it913x_select_config(d);
-       if (ret < 0)
-               return ret;
-
-       ite_get_firmware_name(d, name);
-
-       if (st->it913x_config.firmware > 0)
-               return WARM;
-
-       if (st->it913x_config.dual_mode) {
-               st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0);
-               ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
-               msleep(50);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0);
-               msleep(50);
-               reg = it913x_read_reg(d, GPIOH1_O);
-               if (reg == 0) {
-                       ret |= it913x_wr_reg(d, DEV_0,  GPIOH1_O, 0x1);
-                       ret |= it913x_return_status(d);
-                       if (ret != 0)
-                               ret = it913x_wr_reg(d, DEV_0,
-                                       GPIOH1_O, 0x0);
-               }
-       }
-
-       reg = it913x_read_reg(d, IO_MUX_POWER_CLK);
-
-       if (st->it913x_config.dual_mode) {
-               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
-               if (st->it913x_config.firmware_ver == 1)
-                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x1);
-               else
-                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x1);
-       } else {
-               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0);
-               if (st->it913x_config.firmware_ver == 1)
-                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x0);
-               else
-                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x0);
-       }
-
-       ret |= it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
-
-       return (ret < 0) ? ret : COLD;
-}
-
-static int it913x_download_firmware(struct dvb_usb_device *d,
-                                       const struct firmware *fw)
-{
-       struct it913x_state *st = d->priv;
-       int ret = 0, i = 0, pos = 0;
-       u8 packet_size, min_pkt;
-       u8 *fw_data;
-
-       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
-
-       info("FRM Starting Firmware Download");
-
-       /* Multi firmware loader */
-       /* This uses scatter write firmware headers */
-       /* The firmware must start with 03 XX 00 */
-       /* and be the extact firmware length */
-
-       if (st->it913x_config.chip_ver == 2)
-               min_pkt = 0x11;
-       else
-               min_pkt = 0x19;
-
-       while (i <= fw->size) {
-               if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
-                       || (i == fw->size)) {
-                       packet_size = i - pos;
-                       if ((packet_size > min_pkt) || (i == fw->size)) {
-                               fw_data = (u8 *)(fw->data + pos);
-                               pos += packet_size;
-                               if (packet_size > 0) {
-                                       ret = it913x_io(d, WRITE_DATA,
-                                               DEV_0, CMD_SCATTER_WRITE, 0,
-                                               0, fw_data, packet_size);
-                                       if (ret < 0)
-                                               break;
-                               }
-                               udelay(1000);
-                       }
-               }
-               i++;
-       }
-
-       if (ret < 0)
-               info("FRM Firmware Download Failed (%d)" , ret);
-       else
-               info("FRM Firmware Download Completed - Resetting Device");
-
-       msleep(30);
-
-       ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
-       if (ret < 0)
-               info("FRM Device not responding to reboot");
-
-       ret = it913x_return_status(d);
-       if (st->it913x_config.firmware == 0) {
-               info("FRM Failed to reboot device");
-               return -ENODEV;
-       }
-
-       msleep(30);
-
-       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_400);
-
-       msleep(30);
-
-       /* Tuner function */
-       if (st->it913x_config.dual_mode)
-               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0);
-       else
-               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68);
-
-       if ((st->it913x_config.chip_ver == 1) &&
-               (st->it913x_config.chip_type == 0x9135)) {
-               ret |= it913x_wr_reg(d, DEV_0,  PADODPU, 0x0);
-               ret |= it913x_wr_reg(d, DEV_0,  AGC_O_D, 0x0);
-               if (st->it913x_config.dual_mode) {
-                       ret |= it913x_wr_reg(d, DEV_1,  PADODPU, 0x0);
-                       ret |= it913x_wr_reg(d, DEV_1,  AGC_O_D, 0x0);
-               }
-       }
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_name(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       const char *desc = d->name;
-       char *fe_name[] = {"_1", "_2", "_3", "_4"};
-       char *name = adap->fe[0]->ops.info.name;
-
-       strlcpy(name, desc, 128);
-       strlcat(name, fe_name[adap->id], 128);
-
-       return 0;
-}
-
-static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = d->priv;
-       int ret = 0;
-       u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
-       u16 ep_size = adap->stream.buf_size / 4;
-       u8 pkt_size = 0x80;
-
-       if (d->udev->speed != USB_SPEED_HIGH)
-               pkt_size = 0x10;
-
-       st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK);
-
-       adap->fe[0] = dvb_attach(it913x_fe_attach,
-               &d->i2c_adap, adap_addr, &st->it913x_config);
-
-       if (adap->id == 0 && adap->fe[0]) {
-               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
-               it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
-               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
-                                       ep_size & 0xff);
-               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
-               ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
-       } else if (adap->id == 1 && adap->fe[0]) {
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
-               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
-                                       ep_size & 0xff);
-               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
-               it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1);
-               it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
-               it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
-               it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
-               ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
-       } else
-               return -ENODEV;
-
-       ret |= it913x_name(adap);
-
-       return ret;
-}
-
-/* DVB USB Driver */
-static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       struct it913x_state *st = d->priv;
-
-       if (st->proprietary_ir == false) {
-               rc->map_name = NULL;
-               return 0;
-       }
-
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query = it913x_rc_query;
-       rc->interval = 250;
-
-       return 0;
-}
-
-static int it913x_get_adapter_count(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       if (st->it913x_config.dual_mode)
-               return 2;
-       return 1;
-}
-
-static struct dvb_usb_device_properties it913x_properties = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .bInterfaceNumber = 0,
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct it913x_state),
-
-       .identify_state = it913x_identify_state,
-       .i2c_algo = &it913x_i2c_algo,
-
-       .download_firmware = it913x_download_firmware,
-
-       .frontend_attach  = it913x_frontend_attach,
-       .get_rc_config = it913x_get_rc_config,
-       .get_stream_config = it913x_get_stream_config,
-       .get_adapter_count = it913x_get_adapter_count,
-       .streaming_ctrl   = it913x_streaming_ctrl,
-
-
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = it913x_pid_filter,
-                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX),
-               },
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = it913x_pid_filter,
-                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX),
-               }
-       }
-};
-
-static const struct usb_device_id it913x_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
-               &it913x_properties, "Kworld UB499-2T T09(IT9137)",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
-               &it913x_properties, "ITE 9135 Generic",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
-               &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
-               &it913x_properties, "ITE 9135(9005) Generic",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
-               &it913x_properties, "ITE 9135(9006) Generic",
-                       RC_MAP_IT913X_V1) },
-       {}              /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, it913x_id_table);
-
-static struct usb_driver it913x_driver = {
-       .name           = KBUILD_MODNAME,
-       .probe          = dvb_usbv2_probe,
-       .disconnect     = dvb_usbv2_disconnect,
-       .suspend        = dvb_usbv2_suspend,
-       .resume         = dvb_usbv2_resume,
-       .id_table       = it913x_id_table,
-};
-
-module_usb_driver(it913x_driver);
-
-MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.32");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FW_IT9135_V1);
-MODULE_FIRMWARE(FW_IT9135_V2);
-MODULE_FIRMWARE(FW_IT9137);
-
diff --git a/drivers/media/dvb/dvb-usb-v2/lmedm04.c b/drivers/media/dvb/dvb-usb-v2/lmedm04.c
deleted file mode 100644 (file)
index c41d9d9..0000000
+++ /dev/null
@@ -1,1369 +0,0 @@
-/* DVB USB compliant linux driver for
- *
- * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
- *                             LME2510C + LG TDQY-P001F
- *                             LME2510C + BS2F7HZ0194
- *                             LME2510 + LG TDQY-P001F
- *                             LME2510 + BS2F7HZ0194
- *
- * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
- * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
- *
- * MV001F (LME2510+LGTDQY-P001F)
- * LG TDQY - P001F =(TDA8263 + TDA10086H)
- *
- * MVB0001F (LME2510C+LGTDQT-P001F)
- *
- * MV0194 (LME2510+SHARP:BS2F7HZ0194)
- * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
- *
- * MVB0194 (LME2510C+SHARP0194)
- *
- * LME2510C + M88RS2000
- *
- * For firmware see Documentation/dvb/lmedm04.txt
- *
- * I2C addresses:
- * 0xd0 - STV0288      - Demodulator
- * 0xc0 - Sharp IX2505V        - Tuner
- * --
- * 0x1c - TDA10086   - Demodulator
- * 0xc0 - TDA8263    - Tuner
- * --
- * 0xd0 - STV0299      - Demodulator
- * 0xc0 - IX2410       - Tuner
- *
- *
- * VID = 3344  PID LME2510=1122 LME2510C=1120
- *
- * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
- * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- * Known Issues :
- *     LME2510: Non Intel USB chipsets fail to maintain High Speed on
- * Boot or Hot Plug.
- *
- * QQbox suffers from noise on LNB voltage.
- *
- *     LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
- * with other tuners. After a cold reset streaming will not start.
- *
- * M88RS2000 suffers from loss of lock.
- */
-#define DVB_USB_LOG_PREFIX "LME2510(C)"
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <media/rc-core.h>
-
-#include "dvb_usb.h"
-#include "lmedm04.h"
-#include "tda826x.h"
-#include "tda10086.h"
-#include "stv0288.h"
-#include "ix2505v.h"
-#include "stv0299.h"
-#include "dvb-pll.h"
-#include "z0194a.h"
-#include "m88rs2000.h"
-
-
-#define LME2510_C_S7395        "dvb-usb-lme2510c-s7395.fw";
-#define LME2510_C_LG   "dvb-usb-lme2510c-lg.fw";
-#define LME2510_C_S0194        "dvb-usb-lme2510c-s0194.fw";
-#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
-#define LME2510_LG     "dvb-usb-lme2510-lg.fw";
-#define LME2510_S0194  "dvb-usb-lme2510-s0194.fw";
-
-/* debug */
-static int dvb_usb_lme2510_debug;
-#define lme_debug(var, level, args...) do { \
-       if ((var >= level)) \
-               pr_debug(DVB_USB_LOG_PREFIX": " args); \
-} while (0)
-#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
-#define debug_data_snipet(level, name, p) \
-        deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
-               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
-                       *(p+5), *(p+6), *(p+7));
-#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
-
-module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-static int dvb_usb_lme2510_firmware;
-module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
-
-static int pid_filter;
-module_param_named(pid, pid_filter, int, 0644);
-MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
-
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define TUNER_DEFAULT  0x0
-#define TUNER_LG       0x1
-#define TUNER_S7395    0x2
-#define TUNER_S0194    0x3
-#define TUNER_RS2000   0x4
-
-struct lme2510_state {
-       u8 id;
-       u8 tuner_config;
-       u8 signal_lock;
-       u8 signal_level;
-       u8 signal_sn;
-       u8 time_key;
-       u8 last_key;
-       u8 key_timeout;
-       u8 i2c_talk_onoff;
-       u8 i2c_gate;
-       u8 i2c_tuner_gate_w;
-       u8 i2c_tuner_gate_r;
-       u8 i2c_tuner_addr;
-       u8 stream_on;
-       u8 pid_size;
-       u8 pid_off;
-       void *buffer;
-       struct urb *lme_urb;
-       void *usb_buffer;
-       int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
-       u8 dvb_usb_lme2510_firmware;
-};
-
-static int lme2510_bulk_write(struct usb_device *dev,
-                               u8 *snd, int len, u8 pipe)
-{
-       int ret, actual_l;
-
-       ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
-                               snd, len , &actual_l, 100);
-       return ret;
-}
-
-static int lme2510_bulk_read(struct usb_device *dev,
-                               u8 *rev, int len, u8 pipe)
-{
-       int ret, actual_l;
-
-       ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
-                                rev, len , &actual_l, 200);
-       return ret;
-}
-
-static int lme2510_usb_talk(struct dvb_usb_device *d,
-               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       struct lme2510_state *st = d->priv;
-       u8 *buff;
-       int ret = 0;
-
-       if (st->usb_buffer == NULL) {
-               st->usb_buffer = kmalloc(64, GFP_KERNEL);
-               if (st->usb_buffer == NULL) {
-                       info("MEM Error no memory");
-                       return -ENOMEM;
-               }
-       }
-       buff = st->usb_buffer;
-
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-
-       if (ret < 0)
-               return -EAGAIN;
-
-       /* the read/write capped at 64 */
-       memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
-
-       ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
-
-       ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
-                       rlen : 64 , 0x01);
-
-       if (rlen > 0)
-               memcpy(rbuf, buff, rlen);
-
-       mutex_unlock(&d->usb_mutex);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int lme2510_stream_restart(struct dvb_usb_device *d)
-{
-       struct lme2510_state *st = d->priv;
-       u8 all_pids[] = LME_ALL_PIDS;
-       u8 stream_on[] = LME_ST_ON_W;
-       int ret;
-       u8 rbuff[1];
-       if (st->pid_off)
-               ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
-                       rbuff, sizeof(rbuff));
-       /*Restart Stream Command*/
-       ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
-                       rbuff, sizeof(rbuff));
-       return ret;
-}
-
-static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
-{
-       struct lme2510_state *st = d->priv;
-       static u8 pid_buff[] = LME_ZERO_PID;
-       static u8 rbuf[1];
-       u8 pid_no = index * 2;
-       u8 pid_len = pid_no + 2;
-       int ret = 0;
-       deb_info(1, "PID Setting Pid %04x", pid_out);
-
-       if (st->pid_size == 0)
-               ret |= lme2510_stream_restart(d);
-
-       pid_buff[2] = pid_no;
-       pid_buff[3] = (u8)pid_out & 0xff;
-       pid_buff[4] = pid_no + 1;
-       pid_buff[5] = (u8)(pid_out >> 8);
-
-       if (pid_len > st->pid_size)
-               st->pid_size = pid_len;
-       pid_buff[7] = 0x80 + st->pid_size;
-
-       ret |= lme2510_usb_talk(d, pid_buff ,
-               sizeof(pid_buff) , rbuf, sizeof(rbuf));
-
-       if (st->stream_on)
-               ret |= lme2510_stream_restart(d);
-
-       return ret;
-}
-
-static void lme2510_int_response(struct urb *lme_urb)
-{
-       struct dvb_usb_adapter *adap = lme_urb->context;
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 *ibuf, *rbuf;
-       int i = 0, offset;
-       u32 key;
-
-       switch (lme_urb->status) {
-       case 0:
-       case -ETIMEDOUT:
-               break;
-       case -ECONNRESET:
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       default:
-               info("Error %x", lme_urb->status);
-               break;
-       }
-
-       rbuf = (u8 *) lme_urb->transfer_buffer;
-
-       offset = ((lme_urb->actual_length/8) > 4)
-                       ? 4 : (lme_urb->actual_length/8) ;
-
-       for (i = 0; i < offset; ++i) {
-               ibuf = (u8 *)&rbuf[i*8];
-               deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
-               offset, i, ibuf[0], ibuf[1]);
-
-               switch (ibuf[0]) {
-               case 0xaa:
-                       debug_data_snipet(1, "INT Remote data snipet", ibuf);
-                       if ((ibuf[4] + ibuf[5]) == 0xff) {
-                               key = ibuf[5];
-                               key += (ibuf[3] > 0)
-                                       ? (ibuf[3] ^ 0xff) << 8 : 0;
-                               key += (ibuf[2] ^ 0xff) << 16;
-                               deb_info(1, "INT Key =%08x", key);
-                               if (adap_to_d(adap)->rc_dev != NULL)
-                                       rc_keydown(adap_to_d(adap)->rc_dev,
-                                               key, 0);
-                       }
-                       break;
-               case 0xbb:
-                       switch (st->tuner_config) {
-                       case TUNER_LG:
-                               if (ibuf[2] > 0)
-                                       st->signal_lock = ibuf[2];
-                               st->signal_level = ibuf[4];
-                               st->signal_sn = ibuf[3];
-                               st->time_key = ibuf[7];
-                               break;
-                       case TUNER_S7395:
-                       case TUNER_S0194:
-                               /* Tweak for earlier firmware*/
-                               if (ibuf[1] == 0x03) {
-                                       if (ibuf[2] > 1)
-                                               st->signal_lock = ibuf[2];
-                                       st->signal_level = ibuf[3];
-                                       st->signal_sn = ibuf[4];
-                               } else {
-                                       st->signal_level = ibuf[4];
-                                       st->signal_sn = ibuf[5];
-                                       st->signal_lock =
-                                               (st->signal_lock & 0xf7) +
-                                               ((ibuf[2] & 0x01) << 0x03);
-                               }
-                               break;
-                       case TUNER_RS2000:
-                               if (ibuf[1] == 0x3 &&  ibuf[6] == 0xff)
-                                       st->signal_lock = 0xff;
-                               else
-                                       st->signal_lock = 0x00;
-                               st->signal_level = ibuf[5];
-                               st->signal_sn = ibuf[4];
-                               st->time_key = ibuf[7];
-                       default:
-                               break;
-                       }
-                       debug_data_snipet(5, "INT Remote data snipet in", ibuf);
-               break;
-               case 0xcc:
-                       debug_data_snipet(1, "INT Control data snipet", ibuf);
-                       break;
-               default:
-                       debug_data_snipet(1, "INT Unknown data snipet", ibuf);
-               break;
-               }
-       }
-       usb_submit_urb(lme_urb, GFP_ATOMIC);
-}
-
-static int lme2510_int_read(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *lme_int = adap_to_priv(adap);
-
-       lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
-
-       if (lme_int->lme_urb == NULL)
-                       return -ENOMEM;
-
-       lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
-                                       &lme_int->lme_urb->transfer_dma);
-
-       if (lme_int->buffer == NULL)
-                       return -ENOMEM;
-
-       usb_fill_int_urb(lme_int->lme_urb,
-                               d->udev,
-                               usb_rcvintpipe(d->udev, 0xa),
-                               lme_int->buffer,
-                               128,
-                               lme2510_int_response,
-                               adap,
-                               8);
-
-       lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
-       info("INT Interrupt Service Started");
-
-       return 0;
-}
-
-static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 clear_pid_reg[] = LME_ALL_PIDS;
-       static u8 rbuf[1];
-       int ret = 0;
-
-       deb_info(1, "PID Clearing Filter");
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (!onoff) {
-               ret |= lme2510_usb_talk(d, clear_pid_reg,
-                       sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
-               st->pid_off = true;
-       } else
-               st->pid_off = false;
-
-       st->pid_size = 0;
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return 0;
-}
-
-static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-       int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret = 0;
-
-       deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
-               pid, index, onoff);
-
-       if (onoff) {
-               mutex_lock(&d->i2c_mutex);
-               ret |= lme2510_enable_pid(d, index, pid);
-               mutex_unlock(&d->i2c_mutex);
-       }
-
-
-       return ret;
-}
-
-
-static int lme2510_return_status(struct dvb_usb_device *d)
-{
-       int ret = 0;
-       u8 *data;
-
-       data = kzalloc(10, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-                       0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
-       info("Firmware Status: %x (%x)", ret , data[2]);
-
-       ret = (ret < 0) ? -ENODEV : data[2];
-       kfree(data);
-       return ret;
-}
-
-static int lme2510_msg(struct dvb_usb_device *d,
-               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       int ret = 0;
-       struct lme2510_state *st = d->priv;
-
-       if (st->i2c_talk_onoff == 1) {
-
-               ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-
-               switch (st->tuner_config) {
-               case TUNER_LG:
-                       if (wbuf[2] == 0x1c) {
-                               if (wbuf[3] == 0x0e) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x10)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                                       msleep(80);
-                               }
-                       }
-                       break;
-               case TUNER_S7395:
-                       if (wbuf[2] == 0xd0) {
-                               if (wbuf[3] == 0x24) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x8)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                               }
-                       }
-                       break;
-               case TUNER_S0194:
-                       if (wbuf[2] == 0xd0) {
-                               if (wbuf[3] == 0x1b) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x8)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                               }
-                       }
-                       break;
-               case TUNER_RS2000:
-               default:
-                       break;
-               }
-       } else {
-               /* TODO rewrite this section */
-               switch (st->tuner_config) {
-               case TUNER_LG:
-                       switch (wbuf[3]) {
-                       case 0x0e:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x43:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_level;
-                               break;
-                       case 0x1c:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x15:
-                       case 0x16:
-                       case 0x17:
-                       case 0x18:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_S7395:
-                       switch (wbuf[3]) {
-                       case 0x10:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = (st->signal_level & 0x80)
-                                               ? 0 : (st->signal_level * 2);
-                               break;
-                       case 0x2d:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x24:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x2e:
-                       case 0x26:
-                       case 0x27:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_S0194:
-                       switch (wbuf[3]) {
-                       case 0x18:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = (st->signal_level & 0x80)
-                                               ? 0 : (st->signal_level * 2);
-                               break;
-                       case 0x24:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x1b:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x19:
-                       case 0x25:
-                       case 0x1e:
-                       case 0x1d:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_RS2000:
-                       switch (wbuf[3]) {
-                       case 0x8c:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0xff;
-                               if (st->last_key == st->time_key) {
-                                       st->key_timeout++;
-                                       if (st->key_timeout > 5)
-                                               rbuf[1] = 0;
-                               } else
-                                       st->key_timeout = 0;
-                               st->last_key = st->time_key;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-               default:
-                       break;
-               }
-
-               deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
-                               wbuf[3], rbuf[1]);
-
-       }
-
-       return ret;
-}
-
-
-static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct lme2510_state *st = d->priv;
-       static u8 obuf[64], ibuf[64];
-       int i, read, read_o;
-       u16 len;
-       u8 gate = st->i2c_gate;
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (gate == 0)
-               gate = 5;
-
-       for (i = 0; i < num; i++) {
-               read_o = 1 & (msg[i].flags & I2C_M_RD);
-               read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
-               read |= read_o;
-               gate = (msg[i].addr == st->i2c_tuner_addr)
-                       ? (read)        ? st->i2c_tuner_gate_r
-                                       : st->i2c_tuner_gate_w
-                       : st->i2c_gate;
-               obuf[0] = gate | (read << 7);
-
-               if (gate == 5)
-                       obuf[1] = (read) ? 2 : msg[i].len + 1;
-               else
-                       obuf[1] = msg[i].len + read + 1;
-
-               obuf[2] = msg[i].addr;
-               if (read) {
-                       if (read_o)
-                               len = 3;
-                       else {
-                               memcpy(&obuf[3], msg[i].buf, msg[i].len);
-                               obuf[msg[i].len+3] = msg[i+1].len;
-                               len = msg[i].len+4;
-                       }
-               } else {
-                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
-                       len = msg[i].len+3;
-               }
-
-               if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
-                       deb_info(1, "i2c transfer failed.");
-                       mutex_unlock(&d->i2c_mutex);
-                       return -EAGAIN;
-               }
-
-               if (read) {
-                       if (read_o)
-                               memcpy(msg[i].buf, &ibuf[1], msg[i].len);
-                       else {
-                               memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
-                               i++;
-                       }
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm lme2510_i2c_algo = {
-       .master_xfer   = lme2510_i2c_xfer,
-       .functionality = lme2510_i2c_func,
-};
-
-static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 clear_reg_3[] = LME_ALL_PIDS;
-       static u8 rbuf[1];
-       int ret = 0, rlen = sizeof(rbuf);
-
-       deb_info(1, "STM  (%02x)", onoff);
-
-       /* Streaming is started by FE_HAS_LOCK */
-       if (onoff == 1)
-               st->stream_on = 1;
-       else {
-               deb_info(1, "STM Steam Off");
-               /* mutex is here only to avoid collision with I2C */
-               mutex_lock(&d->i2c_mutex);
-
-               ret = lme2510_usb_talk(d, clear_reg_3,
-                               sizeof(clear_reg_3), rbuf, rlen);
-               st->stream_on = 0;
-               st->i2c_talk_onoff = 1;
-
-               mutex_unlock(&d->i2c_mutex);
-       }
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static u8 check_sum(u8 *p, u8 len)
-{
-       u8 sum = 0;
-       while (len--)
-               sum += *p++;
-       return sum;
-}
-
-static int lme2510_download_firmware(struct dvb_usb_device *d,
-                                       const struct firmware *fw)
-{
-       int ret = 0;
-       u8 *data;
-       u16 j, wlen, len_in, start, end;
-       u8 packet_size, dlen, i;
-       u8 *fw_data;
-
-       packet_size = 0x31;
-       len_in = 1;
-
-       data = kzalloc(128, GFP_KERNEL);
-       if (!data) {
-               info("FRM Could not start Firmware Download"\
-                       "(Buffer allocation failed)");
-               return -ENOMEM;
-       }
-
-       info("FRM Starting Firmware Download");
-
-       for (i = 1; i < 3; i++) {
-               start = (i == 1) ? 0 : 512;
-               end = (i == 1) ? 512 : fw->size;
-               for (j = start; j < end; j += (packet_size+1)) {
-                       fw_data = (u8 *)(fw->data + j);
-                       if ((end - j) > packet_size) {
-                               data[0] = i;
-                               dlen = packet_size;
-                       } else {
-                               data[0] = i | 0x80;
-                               dlen = (u8)(end - j)-1;
-                       }
-                       data[1] = dlen;
-                       memcpy(&data[2], fw_data, dlen+1);
-                       wlen = (u8) dlen + 4;
-                       data[wlen-1] = check_sum(fw_data, dlen+1);
-                       deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
-                               data[dlen+2], data[dlen+3]);
-                       lme2510_usb_talk(d, data, wlen, data, len_in);
-                       ret |= (data[0] == 0x88) ? 0 : -1;
-               }
-       }
-
-       data[0] = 0x8a;
-       len_in = 1;
-       msleep(2000);
-       lme2510_usb_talk(d, data, len_in, data, len_in);
-       msleep(400);
-
-       if (ret < 0)
-               info("FRM Firmware Download Failed (%04x)" , ret);
-       else
-               info("FRM Firmware Download Completed - Resetting Device");
-
-       kfree(data);
-       return RECONNECTS_USB;
-}
-
-static void lme_coldreset(struct dvb_usb_device *d)
-{
-       u8 data[1] = {0};
-       data[0] = 0x0a;
-       info("FRM Firmware Cold Reset");
-
-       lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
-
-       return;
-}
-
-static const char fw_c_s7395[] = LME2510_C_S7395;
-static const char fw_c_lg[] = LME2510_C_LG;
-static const char fw_c_s0194[] = LME2510_C_S0194;
-static const char fw_c_rs2000[] = LME2510_C_RS2000;
-static const char fw_lg[] = LME2510_LG;
-static const char fw_s0194[] = LME2510_S0194;
-
-const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
-{
-       struct lme2510_state *st = d->priv;
-       struct usb_device *udev = d->udev;
-       const struct firmware *fw = NULL;
-       const char *fw_lme;
-       int ret = 0;
-
-       cold = (cold > 0) ? (cold & 1) : 0;
-
-       switch (le16_to_cpu(udev->descriptor.idProduct)) {
-       case 0x1122:
-               switch (st->dvb_usb_lme2510_firmware) {
-               default:
-                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
-               case TUNER_S0194:
-                       fw_lme = fw_s0194;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0) {
-                               cold = 0;
-                               break;
-                       }
-                       st->dvb_usb_lme2510_firmware = TUNER_LG;
-               case TUNER_LG:
-                       fw_lme = fw_lg;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
-                       break;
-               }
-               break;
-       case 0x1120:
-               switch (st->dvb_usb_lme2510_firmware) {
-               default:
-                       st->dvb_usb_lme2510_firmware = TUNER_S7395;
-               case TUNER_S7395:
-                       fw_lme = fw_c_s7395;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0) {
-                               cold = 0;
-                               break;
-                       }
-                       st->dvb_usb_lme2510_firmware = TUNER_LG;
-               case TUNER_LG:
-                       fw_lme = fw_c_lg;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
-               case TUNER_S0194:
-                       fw_lme = fw_c_s0194;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
-                       cold = 0;
-                       break;
-               }
-               break;
-       case 0x22f0:
-               fw_lme = fw_c_rs2000;
-               st->dvb_usb_lme2510_firmware = TUNER_RS2000;
-               break;
-       default:
-               fw_lme = fw_c_s7395;
-       }
-
-       release_firmware(fw);
-
-       if (cold) {
-               dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
-               info("FRM Changing to %s firmware", fw_lme);
-               lme_coldreset(d);
-               return NULL;
-       }
-
-       return fw_lme;
-}
-
-static int lme2510_kill_urb(struct usb_data_stream *stream)
-{
-       int i;
-
-       for (i = 0; i < stream->urbs_submitted; i++) {
-               deb_info(3, "killing URB no. %d.", i);
-               /* stop the URB */
-               usb_kill_urb(stream->urb_list[i]);
-       }
-       stream->urbs_submitted = 0;
-
-       return 0;
-}
-
-static struct tda10086_config tda10086_config = {
-       .demod_address = 0x1c,
-       .invert = 0,
-       .diseqc_tone = 1,
-       .xtal_freq = TDA10086_XTAL_16M,
-};
-
-static struct stv0288_config lme_config = {
-       .demod_address = 0xd0,
-       .min_delay_ms = 15,
-       .inittab = s7395_inittab,
-};
-
-static struct ix2505v_config lme_tuner = {
-       .tuner_address = 0xc0,
-       .min_delay_ms = 100,
-       .tuner_gain = 0x0,
-       .tuner_chargepump = 0x3,
-};
-
-static struct stv0299_config sharp_z0194_config = {
-       .demod_address = 0xd0,
-       .inittab = sharp_z0194a_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .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 int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
-       int caller)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = d->priv;
-
-       mutex_lock(&d->i2c_mutex);
-       if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
-               st->i2c_talk_onoff = 0;
-               lme2510_stream_restart(d);
-       }
-       mutex_unlock(&d->i2c_mutex);
-
-       return 0;
-}
-
-static struct m88rs2000_config m88rs2000_config = {
-       .demod_addr = 0xd0,
-       .tuner_addr = 0xc0,
-       .set_ts_params = dm04_rs2000_set_ts_param,
-};
-
-static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
-                                       fe_sec_voltage_t voltage)
-{
-       struct dvb_usb_device *d = fe_to_d(fe);
-       struct lme2510_state *st = fe_to_priv(fe);
-       static u8 voltage_low[] = LME_VOLTAGE_L;
-       static u8 voltage_high[] = LME_VOLTAGE_H;
-       static u8 rbuf[1];
-       int ret = 0, len = 3, rlen = 1;
-
-       mutex_lock(&d->i2c_mutex);
-
-       switch (voltage) {
-       case SEC_VOLTAGE_18:
-               ret |= lme2510_usb_talk(d,
-                       voltage_high, len, rbuf, rlen);
-               break;
-
-       case SEC_VOLTAGE_OFF:
-       case SEC_VOLTAGE_13:
-       default:
-               ret |= lme2510_usb_talk(d,
-                               voltage_low, len, rbuf, rlen);
-               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       if (st->tuner_config == TUNER_RS2000)
-               if (st->fe_set_voltage)
-                       st->fe_set_voltage(fe, voltage);
-
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       struct lme2510_state *st = fe_to_priv(fe);
-
-       *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
-
-       return 0;
-}
-
-static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lme2510_state *st = fe_to_priv(fe);
-
-       *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
-
-       return 0;
-}
-
-static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       *ber = 0;
-
-       return 0;
-}
-
-static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-
-       return 0;
-}
-
-static int lme_name(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       const char *desc = d->name;
-       char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
-                               " SHARP:BS2F7HZ0194", " RS2000"};
-       char *name = adap->fe[0]->ops.info.name;
-
-       strlcpy(name, desc, 128);
-       strlcat(name, fe_name[st->tuner_config], 128);
-
-       return 0;
-}
-
-static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = d->priv;
-       int ret = 0;
-
-       st->i2c_talk_onoff = 1;
-       switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
-       case 0x1122:
-       case 0x1120:
-               st->i2c_gate = 4;
-               adap->fe[0] = dvb_attach(tda10086_attach,
-                       &tda10086_config, &d->i2c_adap);
-               if (adap->fe[0]) {
-                       info("TUN Found Frontend TDA10086");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 4;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_LG;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
-                               st->dvb_usb_lme2510_firmware = TUNER_LG;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-
-               st->i2c_gate = 4;
-               adap->fe[0] = dvb_attach(stv0299_attach,
-                               &sharp_z0194_config, &d->i2c_adap);
-               if (adap->fe[0]) {
-                       info("FE Found Stv0299");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_S0194;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
-                               st->dvb_usb_lme2510_firmware = TUNER_S0194;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-
-               st->i2c_gate = 5;
-               adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
-                       &d->i2c_adap);
-
-               if (adap->fe[0]) {
-                       info("FE Found Stv0288");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_S7395;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
-                               st->dvb_usb_lme2510_firmware = TUNER_S7395;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-       case 0x22f0:
-               st->i2c_gate = 5;
-               adap->fe[0] = dvb_attach(m88rs2000_attach,
-                       &m88rs2000_config, &d->i2c_adap);
-
-               if (adap->fe[0]) {
-                       info("FE Found M88RS2000");
-                       st->i2c_tuner_gate_w = 5;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_RS2000;
-                       st->fe_set_voltage =
-                               adap->fe[0]->ops.set_voltage;
-
-                       adap->fe[0]->ops.read_signal_strength =
-                               dm04_rs2000_read_signal_strength;
-                       adap->fe[0]->ops.read_snr =
-                               dm04_rs2000_read_snr;
-                       adap->fe[0]->ops.read_ber =
-                               dm04_read_ber;
-                       adap->fe[0]->ops.read_ucblocks =
-                               dm04_read_ucblocks;
-               }
-               break;
-       }
-
-       if (adap->fe[0] == NULL) {
-               info("DM04/QQBOX Not Powered up or not Supported");
-               return -ENODEV;
-       }
-
-       if (ret) {
-               if (adap->fe[0]) {
-                       dvb_frontend_detach(adap->fe[0]);
-                       adap->fe[0] = NULL;
-               }
-               d->rc_map = NULL;
-               return -ENODEV;
-       }
-
-       adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
-       ret = lme_name(adap);
-       return ret;
-}
-
-static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
-       int ret = 0;
-
-       switch (st->tuner_config) {
-       case TUNER_LG:
-               if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
-                       &d->i2c_adap, 1))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_S7395:
-               if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
-                       &d->i2c_adap))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_S0194:
-               if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
-                       &d->i2c_adap, DVB_PLL_OPERA1))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_RS2000:
-               ret = st->tuner_config;
-               break;
-       default:
-               break;
-       }
-
-       if (ret)
-               info("TUN Found %s tuner", tun_msg[ret]);
-       else {
-               info("TUN No tuner found --- resetting device");
-               lme_coldreset(d);
-               return -ENODEV;
-       }
-
-       /* Start the Interrupt*/
-       ret = lme2510_int_read(adap);
-       if (ret < 0) {
-               info("INT Unable to start Interrupt Service");
-               return -ENODEV;
-       }
-
-       return ret;
-}
-
-static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
-{
-       struct lme2510_state *st = d->priv;
-       static u8 lnb_on[] = LNB_ON;
-       static u8 lnb_off[] = LNB_OFF;
-       static u8 rbuf[1];
-       int ret = 0, len = 3, rlen = 1;
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (onoff)
-               ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
-       else
-               ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
-
-       st->i2c_talk_onoff = 1;
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static int lme2510_get_adapter_count(struct dvb_usb_device *d)
-{
-       return 1;
-}
-
-static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       struct lme2510_state *st = d->priv;
-
-       usb_reset_configuration(d->udev);
-
-       usb_set_interface(d->udev,
-               d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
-
-       st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
-
-       if (lme2510_return_status(d) == 0x44) {
-               *name = lme_firmware_switch(d, 0);
-               return COLD;
-       }
-
-       return 0;
-}
-
-static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-
-       if (adap == NULL)
-               return 0;
-       /* Turn PID filter on the fly by module option */
-       if (pid_filter == 2) {
-               adap->pid_filtering  = 1;
-               adap->max_feed_count = 15;
-       }
-
-       if (!(le16_to_cpu(d->udev->descriptor.idProduct)
-               == 0x1122))
-               stream->endpoint = 0x8;
-
-       return 0;
-}
-
-static int lme2510_get_rc_config(struct dvb_usb_device *d,
-       struct dvb_usb_rc *rc)
-{
-       rc->allowed_protos = RC_TYPE_NEC;
-       return 0;
-}
-
-static void *lme2510_exit_int(struct dvb_usb_device *d)
-{
-       struct lme2510_state *st = d->priv;
-       struct dvb_usb_adapter *adap = &d->adapter[0];
-       void *buffer = NULL;
-
-       if (adap != NULL) {
-               lme2510_kill_urb(&adap->stream);
-       }
-
-       if (st->usb_buffer != NULL) {
-               st->i2c_talk_onoff = 1;
-               st->signal_lock = 0;
-               st->signal_level = 0;
-               st->signal_sn = 0;
-               buffer = st->usb_buffer;
-       }
-
-       if (st->lme_urb != NULL) {
-               usb_kill_urb(st->lme_urb);
-               usb_free_coherent(d->udev, 128, st->buffer,
-                                 st->lme_urb->transfer_dma);
-               info("Interrupt Service Stopped");
-       }
-
-       return buffer;
-}
-
-static void lme2510_exit(struct dvb_usb_device *d)
-{
-       void *usb_buffer;
-
-       if (d != NULL) {
-               usb_buffer = lme2510_exit_int(d);
-               if (usb_buffer != NULL)
-                       kfree(usb_buffer);
-       }
-}
-
-static struct dvb_usb_device_properties lme2510_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .bInterfaceNumber = 0,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct lme2510_state),
-
-       .download_firmware = lme2510_download_firmware,
-
-       .power_ctrl       = lme2510_powerup,
-       .identify_state   = lme2510_identify_state,
-       .i2c_algo         = &lme2510_i2c_algo,
-
-       .frontend_attach  = dm04_lme2510_frontend_attach,
-       .tuner_attach = dm04_lme2510_tuner,
-       .get_stream_config = lme2510_get_stream_config,
-       .get_adapter_count = lme2510_get_adapter_count,
-       .streaming_ctrl   = lme2510_streaming_ctrl,
-
-       .get_rc_config = lme2510_get_rc_config,
-
-       .exit = lme2510_exit,
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 15,
-                       .pid_filter = lme2510_pid_filter,
-                       .pid_filter_ctrl  = lme2510_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x86, 10, 4096),
-               },
-               {
-               }
-       },
-};
-
-static const struct usb_device_id lme2510_id_table[] = {
-       {       DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
-               "DM04_LME2510_DVB-S", RC_MAP_LME2510)   },
-       {       DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
-               "DM04_LME2510C_DVB-S", RC_MAP_LME2510)  },
-       {       DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
-               "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510)   },
-       {}              /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, lme2510_id_table);
-
-static struct usb_driver lme2510_driver = {
-       .name           = KBUILD_MODNAME,
-       .probe          = dvb_usbv2_probe,
-       .disconnect     = dvb_usbv2_disconnect,
-       .id_table       = lme2510_id_table,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(lme2510_driver);
-
-MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("2.06");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(LME2510_C_S7395);
-MODULE_FIRMWARE(LME2510_C_LG);
-MODULE_FIRMWARE(LME2510_C_S0194);
-MODULE_FIRMWARE(LME2510_C_RS2000);
-MODULE_FIRMWARE(LME2510_LG);
-MODULE_FIRMWARE(LME2510_S0194);
-
diff --git a/drivers/media/dvb/dvb-usb-v2/lmedm04.h b/drivers/media/dvb/dvb-usb-v2/lmedm04.h
deleted file mode 100644 (file)
index e9c2072..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* DVB USB compliant linux driver for
- *
- * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
- *                             LME2510C + LG TDQY-P001F
- *                             LME2510 + LG TDQY-P001F
- *
- * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
- * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
- *
- * MVB001F (LME2510+LGTDQT-P001F)
- * LG TDQY - P001F =(TDA8263 + TDA10086H)
- *
- * MVB0001F (LME2510C+LGTDQT-P001F)
- *
- * 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,  version 2.
- * *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_LME2510_H_
-#define _DVB_USB_LME2510_H_
-
-/* Streamer &  PID
- *
- * Note:       These commands do not actually stop the streaming
- *             but form some kind of packet filtering/stream count
- *             or tuning related functions.
- *  06 XX
- *  offset 1 = 00 Enable Streaming
- *
- *
- *  PID
- *  03 XX XX  ----> reg number ---> setting....20 XX
- *  offset 1 = length
- *  offset 2 = start of data
- *  end byte -1 = 20
- *  end byte = clear pid always a0, other wise 9c, 9a ??
- *
-*/
-#define LME_ST_ON_W    {0x06, 0x00}
-#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
-#define LME_ZERO_PID   {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
-#define LME_ALL_PIDS   {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
-
-/*  LNB Voltage
- *  07 XX XX
- *  offset 1 = 01
- *  offset 2 = 00=Voltage low 01=Voltage high
- *
- *  LNB Power
- *  03 01 XX
- *  offset 2 = 00=ON 01=OFF
- */
-
-#define LME_VOLTAGE_L  {0x07, 0x01, 0x00}
-#define LME_VOLTAGE_H  {0x07, 0x01, 0x01}
-#define LNB_ON         {0x3a, 0x01, 0x00}
-#define LNB_OFF                {0x3a, 0x01, 0x01}
-
-/* Initial stv0288 settings for 7395 Frontend */
-static u8 s7395_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x20,
-       0x03, 0xa0,
-       0x04, 0xa0,
-       0x05, 0x12,
-       0x06, 0x00,
-       0x09, 0x00,
-       0x0a, 0x04,
-       0x0b, 0x00,
-       0x0c, 0x00,
-       0x0d, 0x00,
-       0x0e, 0xc1,
-       0x0f, 0x54,
-       0x11, 0x7a,
-       0x12, 0x03,
-       0x13, 0x48,
-       0x14, 0x84,
-       0x15, 0xc5,
-       0x16, 0xb8,
-       0x17, 0x9c,
-       0x18, 0x00,
-       0x19, 0xa6,
-       0x1a, 0x88,
-       0x1b, 0x8f,
-       0x1c, 0xf0,
-       0x20, 0x0b,
-       0x21, 0x54,
-       0x22, 0xff,
-       0x23, 0x01,
-       0x28, 0x46,
-       0x29, 0x66,
-       0x2a, 0x90,
-       0x2b, 0xfa,
-       0x2c, 0xd9,
-       0x30, 0x0,
-       0x31, 0x1e,
-       0x32, 0x14,
-       0x33, 0x0f,
-       0x34, 0x09,
-       0x35, 0x0c,
-       0x36, 0x05,
-       0x37, 0x2f,
-       0x38, 0x16,
-       0x39, 0xbd,
-       0x3a, 0x0,
-       0x3b, 0x13,
-       0x3c, 0x11,
-       0x3d, 0x30,
-       0x40, 0x63,
-       0x41, 0x04,
-       0x42, 0x20,
-       0x43, 0x00,
-       0x44, 0x00,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x47, 0x00,
-       0x4a, 0x00,
-       0x50, 0x10,
-       0x51, 0x36,
-       0x52, 0x21,
-       0x53, 0x94,
-       0x54, 0xb2,
-       0x55, 0x29,
-       0x56, 0x64,
-       0x57, 0x2b,
-       0x58, 0x54,
-       0x59, 0x86,
-       0x5a, 0x00,
-       0x5b, 0x9b,
-       0x5c, 0x08,
-       0x5d, 0x7f,
-       0x5e, 0xff,
-       0x5f, 0x8d,
-       0x70, 0x0,
-       0x71, 0x0,
-       0x72, 0x0,
-       0x74, 0x0,
-       0x75, 0x0,
-       0x76, 0x0,
-       0x81, 0x0,
-       0x82, 0x3f,
-       0x83, 0x3f,
-       0x84, 0x0,
-       0x85, 0x0,
-       0x88, 0x0,
-       0x89, 0x0,
-       0x8a, 0x0,
-       0x8b, 0x0,
-       0x8c, 0x0,
-       0x90, 0x0,
-       0x91, 0x0,
-       0x92, 0x0,
-       0x93, 0x0,
-       0x94, 0x1c,
-       0x97, 0x0,
-       0xa0, 0x48,
-       0xa1, 0x0,
-       0xb0, 0xb8,
-       0xb1, 0x3a,
-       0xb2, 0x10,
-       0xb3, 0x82,
-       0xb4, 0x80,
-       0xb5, 0x82,
-       0xb6, 0x82,
-       0xb7, 0x82,
-       0xb8, 0x20,
-       0xb9, 0x0,
-       0xf0, 0x0,
-       0xf1, 0x0,
-       0xf2, 0xc0,
-       0xff, 0xff,
-};
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c
deleted file mode 100644 (file)
index d83df4b..0000000
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- *  mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-demod.h"
-#include "mxl111sf-reg.h"
-
-/* debug */
-static int mxl111sf_demod_debug;
-module_param_named(debug, mxl111sf_demod_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define mxl_dbg(fmt, arg...) \
-       if (mxl111sf_demod_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-/* ------------------------------------------------------------------------ */
-
-struct mxl111sf_demod_state {
-       struct mxl111sf_state *mxl_state;
-
-       struct mxl111sf_demod_config *cfg;
-
-       struct dvb_frontend fe;
-};
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
-                                  u8 addr, u8 *data)
-{
-       return (state->cfg->read_reg) ?
-               state->cfg->read_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
-                                   u8 addr, u8 data)
-{
-       return (state->cfg->write_reg) ?
-               state->cfg->write_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static
-int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
-                               struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       return (state->cfg->program_regs) ?
-               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
-               -EINVAL;
-}
-
-/* ------------------------------------------------------------------------ */
-/* TPS */
-
-static
-int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
-                                    fe_code_rate_t *code_rate)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
-       /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch (val & V6_CODE_RATE_TPS_MASK) {
-       case 0:
-               *code_rate = FEC_1_2;
-               break;
-       case 1:
-               *code_rate = FEC_2_3;
-               break;
-       case 2:
-               *code_rate = FEC_3_4;
-               break;
-       case 3:
-               *code_rate = FEC_5_6;
-               break;
-       case 4:
-               *code_rate = FEC_7_8;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state,
-                                        fe_modulation_t *modulation)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
-       /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
-       case 0:
-               *modulation = QPSK;
-               break;
-       case 1:
-               *modulation = QAM_16;
-               break;
-       case 2:
-               *modulation = QAM_64;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
-                                         fe_transmit_mode_t *fft_mode)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
-       /* FFT Mode, 00:2K, 01:8K, 10:4K */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
-       case 0:
-               *fft_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               *fft_mode = TRANSMISSION_MODE_8K;
-               break;
-       case 2:
-               *fft_mode = TRANSMISSION_MODE_4K;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
-                                         fe_guard_interval_t *guard)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
-       /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_GI_MASK) >> 4) {
-       case 0:
-               *guard = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               *guard = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               *guard = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               *guard = GUARD_INTERVAL_1_4;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
-                                    fe_hierarchy_t *hierarchy)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
-       /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
-       case 0:
-               *hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               *hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               *hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               *hierarchy = HIERARCHY_4;
-               break;
-       }
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-/* LOCKS */
-
-static
-int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
-                                       int *sync_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
-                                     int *rs_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
-                                      int *tps_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
-                                      int *fec_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
-fail:
-       return ret;
-}
-
-#if 0
-static
-int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
-                                     int *cp_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
-fail:
-       return ret;
-}
-#endif
-
-static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
-{
-       return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       int ret = 0;
-
-       struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
-               {0x00, 0xff, 0x01}, /* change page to 1 */
-               {0x40, 0xff, 0x05},
-               {0x40, 0xff, 0x01},
-               {0x41, 0xff, 0xca},
-               {0x41, 0xff, 0xc0},
-               {0x00, 0xff, 0x00}, /* change page to 0 */
-               {0,    0,    0}
-       };
-
-       mxl_dbg("()");
-
-       if (fe->ops.tuner_ops.set_params) {
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (mxl_fail(ret))
-                       goto fail;
-               msleep(50);
-       }
-       ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
-       mxl_fail(ret);
-       msleep(50);
-       ret = mxl1x1sf_demod_reset_irq_status(state);
-       mxl_fail(ret);
-       msleep(100);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#if 0
-/* resets TS Packet error count */
-/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
-static
-int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
-{
-       struct mxl111sf_reg_ctrl_info reset_per_count[] = {
-               {0x20, 0x01, 0x01},
-               {0x20, 0x01, 0x00},
-               {0,    0,    0}
-       };
-       return mxl111sf_demod_program_regs(state, reset_per_count);
-}
-#endif
-
-/* returns TS Packet error count */
-/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
-static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       u32 fec_per_count, fec_per_scale;
-       u8 val;
-       int ret;
-
-       *ucblocks = 0;
-
-       /* FEC_PER_COUNT Register */
-       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       fec_per_count = val;
-
-       /* FEC_PER_SCALE Register */
-       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       val &= V6_FEC_PER_SCALE_MASK;
-       val *= 4;
-
-       fec_per_scale = 1 << val;
-
-       fec_per_count *= fec_per_scale;
-
-       *ucblocks = fec_per_count;
-fail:
-       return ret;
-}
-
-#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
-/* FIXME: leaving this enabled breaks the build on some architectures,
- * and we shouldn't have any floating point math in the kernel, anyway.
- *
- * These macros need to be re-written, but it's harmless to simply
- * return zero for now. */
-#define CALCULATE_BER(avg_errors, count) \
-       ((u32)(avg_errors * 4)/(count*64*188*8))
-#define CALCULATE_SNR(data) \
-       ((u32)((10 * (u32)data / 64) - 2.5))
-#else
-#define CALCULATE_BER(avg_errors, count) 0
-#define CALCULATE_SNR(data) 0
-#endif
-
-static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       u8 val1, val2, val3;
-       int ret;
-
-       *ber = 0;
-
-       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
-                                  u16 *snr)
-{
-       u8 val1, val2;
-       int ret;
-
-       *snr = 0;
-
-       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-
-       int ret = mxl111sf_demod_calc_snr(state, snr);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *snr /= 10; /* 0.1 dB */
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
-                                     fe_status_t *status)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       int ret, locked, cr_lock, sync_lock, fec_lock;
-
-       *status = 0;
-
-       ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (locked)
-               *status |= FE_HAS_SIGNAL;
-       if (cr_lock)
-               *status |= FE_HAS_CARRIER;
-       if (sync_lock)
-               *status |= FE_HAS_SYNC;
-       if (fec_lock) /* false positives? */
-               *status |= FE_HAS_VITERBI;
-
-       if ((locked) && (cr_lock) && (sync_lock))
-               *status |= FE_HAS_LOCK;
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
-                                              u16 *signal_strength)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       fe_modulation_t modulation;
-       u16 snr;
-
-       mxl111sf_demod_calc_snr(state, &snr);
-       mxl1x1sf_demod_get_tps_modulation(state, &modulation);
-
-       switch (modulation) {
-       case QPSK:
-               *signal_strength = (snr >= 1300) ?
-                       min(65535, snr * 44) : snr * 38;
-               break;
-       case QAM_16:
-               *signal_strength = (snr >= 1500) ?
-                       min(65535, snr * 38) : snr * 33;
-               break;
-       case QAM_64:
-               *signal_strength = (snr >= 2000) ?
-                       min(65535, snr * 29) : snr * 25;
-               break;
-       default:
-               *signal_strength = 0;
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-
-       mxl_dbg("()");
-#if 0
-       p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
-#endif
-       if (fe->ops.tuner_ops.get_bandwidth)
-               fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz);
-       if (fe->ops.tuner_ops.get_frequency)
-               fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
-       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP);
-       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP);
-       mxl1x1sf_demod_get_tps_modulation(state, &p->modulation);
-       mxl1x1sf_demod_get_tps_guard_fft_mode(state,
-                                             &p->transmission_mode);
-       mxl1x1sf_demod_get_tps_guard_interval(state,
-                                             &p->guard_interval);
-       mxl1x1sf_demod_get_tps_hierarchy(state,
-                                        &p->hierarchy);
-
-       return 0;
-}
-
-static
-int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void mxl111sf_demod_release(struct dvb_frontend *fe)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       mxl_dbg("()");
-       kfree(state);
-       fe->demodulator_priv = NULL;
-}
-
-static struct dvb_frontend_ops mxl111sf_demod_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name               = "MaxLinear MxL111SF DVB-T demodulator",
-               .frequency_min      = 177000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
-       },
-       .release              = mxl111sf_demod_release,
-#if 0
-       .init                 = mxl111sf_init,
-       .i2c_gate_ctrl        = mxl111sf_i2c_gate_ctrl,
-#endif
-       .set_frontend         = mxl111sf_demod_set_frontend,
-       .get_frontend         = mxl111sf_demod_get_frontend,
-       .get_tune_settings    = mxl111sf_demod_get_tune_settings,
-       .read_status          = mxl111sf_demod_read_status,
-       .read_signal_strength = mxl111sf_demod_read_signal_strength,
-       .read_ber             = mxl111sf_demod_read_ber,
-       .read_snr             = mxl111sf_demod_read_snr,
-       .read_ucblocks        = mxl111sf_demod_read_ucblocks,
-};
-
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg)
-{
-       struct mxl111sf_demod_state *state = NULL;
-
-       mxl_dbg("()");
-
-       state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->mxl_state = mxl_state;
-       state->cfg = cfg;
-
-       memcpy(&state->fe.ops, &mxl111sf_demod_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       state->fe.demodulator_priv = state;
-       return &state->fe;
-}
-EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
-
-MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h
deleted file mode 100644 (file)
index 432706a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 __MXL111SF_DEMOD_H__
-#define __MXL111SF_DEMOD_H__
-
-#include "dvb_frontend.h"
-#include "mxl111sf.h"
-
-struct mxl111sf_demod_config {
-       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
-       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
-       int (*program_regs)(struct mxl111sf_state *state,
-                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-};
-
-#if defined(CONFIG_DVB_USB_MXL111SF) || \
-       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
-extern
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg);
-#else
-static inline
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_USB_MXL111SF */
-
-#endif /* __MXL111SF_DEMOD_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c
deleted file mode 100644 (file)
index e4121cb..0000000
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-gpio.h"
-#include "mxl111sf-i2c.h"
-#include "mxl111sf.h"
-
-/* ------------------------------------------------------------------------- */
-
-#define MXL_GPIO_MUX_REG_0 0x84
-#define MXL_GPIO_MUX_REG_1 0x89
-#define MXL_GPIO_MUX_REG_2 0x82
-
-#define MXL_GPIO_DIR_INPUT  0
-#define MXL_GPIO_DIR_OUTPUT 1
-
-
-static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug_adv("(%d, %d)", pin, val);
-
-       if ((pin > 0) && (pin < 8)) {
-               ret = mxl111sf_read_reg(state, 0x19, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (pin - 1));
-               tmp |= (val << (pin - 1));
-               ret = mxl111sf_write_reg(state, 0x19, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-       } else if (pin <= 10) {
-               if (pin == 0)
-                       pin += 7;
-               ret = mxl111sf_read_reg(state, 0x30, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (pin - 3));
-               tmp |= (val << (pin - 3));
-               ret = mxl111sf_write_reg(state, 0x30, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-       } else
-               ret = -EINVAL;
-fail:
-       return ret;
-}
-
-static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug("(0x%02x)", pin);
-
-       *val = 0;
-
-       switch (pin) {
-       case 0:
-       case 1:
-       case 2:
-       case 3:
-               ret = mxl111sf_read_reg(state, 0x23, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> (pin + 4)) & 0x01;
-               break;
-       case 4:
-       case 5:
-       case 6:
-       case 7:
-               ret = mxl111sf_read_reg(state, 0x2f, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> pin) & 0x01;
-               break;
-       case 8:
-       case 9:
-       case 10:
-               ret = mxl111sf_read_reg(state, 0x22, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> (pin - 3)) & 0x01;
-               break;
-       default:
-               return -EINVAL; /* invalid pin */
-       }
-fail:
-       return ret;
-}
-
-struct mxl_gpio_cfg {
-       u8 pin;
-       u8 dir;
-       u8 val;
-};
-
-static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
-                                    struct mxl_gpio_cfg *gpio_cfg)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
-
-       switch (gpio_cfg->pin) {
-       case 0:
-       case 1:
-       case 2:
-       case 3:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (gpio_cfg->pin + 4));
-               tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       case 4:
-       case 5:
-       case 6:
-       case 7:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << gpio_cfg->pin);
-               tmp |= (gpio_cfg->dir << gpio_cfg->pin);
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       case 8:
-       case 9:
-       case 10:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (gpio_cfg->pin - 3));
-               tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       default:
-               return -EINVAL; /* invalid pin */
-       }
-
-       ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
-               mxl111sf_set_gpo_state(state,
-                                      gpio_cfg->pin, gpio_cfg->val) :
-               mxl111sf_get_gpi_state(state,
-                                      gpio_cfg->pin, &gpio_cfg->val);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
-                                  int gpio, int direction, int val)
-{
-       struct mxl_gpio_cfg gpio_config = {
-               .pin = gpio,
-               .dir = direction,
-               .val = val,
-       };
-
-       mxl_debug("(%d, %d, %d)", gpio, direction, val);
-
-       return mxl111sf_config_gpio_pins(state, &gpio_config);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
-#define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
-#define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
-#define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
-#define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
-#define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
-#define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
-#define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
-#define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
-#define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
-#define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
-#define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
-#define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
-#define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
-#define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
-#define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
-#define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
-#define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
-#define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
-
-int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
-                                 enum mxl111sf_mux_config pin_mux_config)
-{
-       u8 r12, r15, r17, r18, r3D, r82, r84, r89;
-       int ret;
-
-       mxl_debug("(%d)", pin_mux_config);
-
-       ret = mxl111sf_read_reg(state, 0x17, &r17);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x18, &r18);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x12, &r12);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x15, &r15);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x82, &r82);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x84, &r84);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x89, &r89);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x3D, &r3D);
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch (pin_mux_config) {
-       case PIN_MUX_TS_OUT_PARALLEL:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 1 */
-               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 1 */
-               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 1 */
-               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0xF */
-               r84 |= 0xF0;
-               /* mdat_en_ctrl[7:4] = 0xF */
-               r89 |= 0xF0;
-               break;
-       case PIN_MUX_TS_OUT_SERIAL:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 1 */
-               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 1 */
-               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0xF */
-               r84 |= 0xF0;
-               /* mdat_en_ctrl[7:4] = 0xF */
-               r89 |= 0xF0;
-               break;
-       case PIN_MUX_GPIO_MODE:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SERIAL_IN_MODE_0:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SERIAL_IN_MODE_1:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 1 */
-               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SPI_IN_MODE_1:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 1 */
-               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 1 */
-               r3D |= PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SPI_IN_MODE_0:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 1 */
-               r3D |= PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_PARALLEL_IN:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 1 */
-               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_BT656_I2S_MODE:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 1 */
-               r12 |= PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_DEFAULT:
-       default:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       }
-
-       ret = mxl111sf_write_reg(state, 0x17, r17);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x18, r18);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x12, r12);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x15, r15);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x82, r82);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x84, r84);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x89, r89);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x3D, r3D);
-       if (mxl_fail(ret))
-               goto fail;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
-}
-
-static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
-{
-       u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
-       int i, ret;
-
-       mxl_debug("()");
-
-       for (i = 3; i < 8; i++) {
-               ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
-               if (mxl_fail(ret))
-                       break;
-       }
-
-       return ret;
-}
-
-#define PCA9534_I2C_ADDR (0x40 >> 1)
-static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       u8 w[2] = { 1, 0 };
-       u8 r = 0;
-       struct i2c_msg msg[] = {
-               { .addr = PCA9534_I2C_ADDR,
-                 .flags = 0, .buf = w, .len = 1 },
-               { .addr = PCA9534_I2C_ADDR,
-                 .flags = I2C_M_RD, .buf = &r, .len = 1 },
-       };
-
-       mxl_debug("(%d, %d)", gpio, val);
-
-       /* read current GPIO levels from flip-flop */
-       i2c_transfer(&state->d->i2c_adap, msg, 2);
-
-       /* prepare write buffer with current GPIO levels */
-       msg[0].len = 2;
-#if 0
-       w[0] = 1;
-#endif
-       w[1] = r;
-
-       /* clear the desired GPIO */
-       w[1] &= ~(1 << gpio);
-
-       /* set the desired GPIO value */
-       w[1] |= ((val ? 1 : 0) << gpio);
-
-       /* write new GPIO levels to flip-flop */
-       i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
-
-       return 0;
-}
-
-static int pca9534_init_port_expander(struct mxl111sf_state *state)
-{
-       u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
-
-       struct i2c_msg msg = {
-               .addr = PCA9534_I2C_ADDR,
-               .flags = 0, .buf = w, .len = 2
-       };
-
-       mxl_debug("()");
-
-       i2c_transfer(&state->d->i2c_adap, &msg, 1);
-
-       /* configure all pins as outputs */
-       w[0] = 3;
-       w[1] = 0;
-
-       i2c_transfer(&state->d->i2c_adap, &msg, 1);
-
-       return 0;
-}
-
-int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       mxl_debug("(%d, %d)", gpio, val);
-
-       switch (state->gpio_port_expander) {
-       default:
-               mxl_printk(KERN_ERR,
-                          "gpio_port_expander undefined, assuming PCA9534");
-               /* fall-thru */
-       case mxl111sf_PCA9534:
-               return pca9534_set_gpio(state, gpio, val);
-       case mxl111sf_gpio_hw:
-               return mxl111sf_hw_set_gpio(state, gpio, val);
-       }
-}
-
-static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 w = 1;
-       u8 r = 0;
-       struct i2c_msg msg[] = {
-               { .flags = 0,        .buf = &w, .len = 1 },
-               { .flags = I2C_M_RD, .buf = &r, .len = 1 },
-       };
-
-       mxl_debug("()");
-
-       msg[0].addr = 0x70 >> 1;
-       msg[1].addr = 0x70 >> 1;
-
-       /* read current GPIO levels from flip-flop */
-       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
-       if (ret == 2) {
-               state->port_expander_addr = msg[0].addr;
-               state->gpio_port_expander = mxl111sf_PCA9534;
-               mxl_debug("found port expander at 0x%02x",
-                         state->port_expander_addr);
-               return 0;
-       }
-
-       msg[0].addr = 0x40 >> 1;
-       msg[1].addr = 0x40 >> 1;
-
-       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
-       if (ret == 2) {
-               state->port_expander_addr = msg[0].addr;
-               state->gpio_port_expander = mxl111sf_PCA9534;
-               mxl_debug("found port expander at 0x%02x",
-                         state->port_expander_addr);
-               return 0;
-       }
-       state->port_expander_addr = 0xff;
-       state->gpio_port_expander = mxl111sf_gpio_hw;
-       mxl_debug("using hardware gpio");
-       return 0;
-}
-
-int mxl111sf_init_port_expander(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       if (0x00 == state->port_expander_addr)
-               mxl111sf_probe_port_expander(state);
-
-       switch (state->gpio_port_expander) {
-       default:
-               mxl_printk(KERN_ERR,
-                          "gpio_port_expander undefined, assuming PCA9534");
-               /* fall-thru */
-       case mxl111sf_PCA9534:
-               return pca9534_init_port_expander(state);
-       case mxl111sf_gpio_hw:
-               return mxl111sf_hw_gpio_initialize(state);
-       }
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
-{
-/*     GPO:
- *     3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
- *     4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
- *     5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
- *     6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
- *     7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
- */
-       mxl_debug("(%d)", mode);
-
-       switch (mode) {
-       case MXL111SF_GPIO_MOD_MH:
-               mxl111sf_set_gpio(state, 4, 0);
-               mxl111sf_set_gpio(state, 5, 0);
-               msleep(50);
-               mxl111sf_set_gpio(state, 7, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 6, 1);
-               msleep(50);
-
-               mxl111sf_set_gpio(state, 3, 0);
-               break;
-       case MXL111SF_GPIO_MOD_ATSC:
-               mxl111sf_set_gpio(state, 6, 0);
-               mxl111sf_set_gpio(state, 7, 0);
-               msleep(50);
-               mxl111sf_set_gpio(state, 5, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 4, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 3, 1);
-               break;
-       default: /* DVBT / STANDBY */
-               mxl111sf_init_port_expander(state);
-               break;
-       }
-       return 0;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h
deleted file mode 100644 (file)
index 0220f54..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  mxl111sf-gpio.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_GPIO_H_
-#define _DVB_USB_MXL111SF_GPIO_H_
-
-#include "mxl111sf.h"
-
-int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val);
-int mxl111sf_init_port_expander(struct mxl111sf_state *state);
-
-#define MXL111SF_GPIO_MOD_DVBT 0
-#define MXL111SF_GPIO_MOD_MH   1
-#define MXL111SF_GPIO_MOD_ATSC 2
-int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode);
-
-enum mxl111sf_mux_config {
-       PIN_MUX_DEFAULT = 0,
-       PIN_MUX_TS_OUT_PARALLEL,
-       PIN_MUX_TS_OUT_SERIAL,
-       PIN_MUX_GPIO_MODE,
-       PIN_MUX_TS_SERIAL_IN_MODE_0,
-       PIN_MUX_TS_SERIAL_IN_MODE_1,
-       PIN_MUX_TS_SPI_IN_MODE_0,
-       PIN_MUX_TS_SPI_IN_MODE_1,
-       PIN_MUX_TS_PARALLEL_IN,
-       PIN_MUX_BT656_I2S_MODE,
-};
-
-int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
-                                 enum mxl111sf_mux_config pin_mux_config);
-
-#endif /* _DVB_USB_MXL111SF_GPIO_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c
deleted file mode 100644 (file)
index 3443455..0000000
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- *  mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-i2c.h"
-#include "mxl111sf.h"
-
-/* SW-I2C ----------------------------------------------------------------- */
-
-#define SW_I2C_ADDR            0x1a
-#define SW_I2C_EN              0x02
-#define SW_SCL_OUT             0x04
-#define SW_SDA_OUT             0x08
-#define SW_SDA_IN              0x04
-
-#define SW_I2C_BUSY_ADDR       0x2f
-#define SW_I2C_BUSY            0x02
-
-static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
-                                        u8 byte)
-{
-       int i, ret;
-       u8 data = 0;
-
-       mxl_i2c("(0x%02x)", byte);
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       for (i = 0; i < 8; i++) {
-
-               data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data | SW_SCL_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-
-       /* last bit was 0 so we need to release SDA */
-       if (!(byte & 1)) {
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-
-       /* CLK high for ACK readback */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* drop the CLK after getting ACK, SDA will go high right away */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (data & SW_SDA_IN)
-               ret = -EIO;
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
-                                        u8 *pbyte)
-{
-       int i, ret;
-       u8 byte = 0;
-       u8 data = 0;
-
-       mxl_i2c("()");
-
-       *pbyte = 0;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       for (i = 0; i < 8; i++) {
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN |
-                                        SW_SCL_OUT | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               if (data & SW_SDA_IN)
-                       byte |= (0x80 >> i);
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-       *pbyte = byte;
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_start(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN); /* start */
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN); /* stop */
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_SCL_OUT | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 b = 0;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* pull SDA low */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       /* SDA high to signal last byte read from slave */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
-                                   struct i2c_msg *msg)
-{
-       int i, ret;
-
-       mxl_i2c("()");
-
-       if (msg->flags & I2C_M_RD) {
-
-               ret = mxl111sf_i2c_start(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                   (msg->addr << 1) | 0x01);
-               if (mxl_fail(ret)) {
-                       mxl111sf_i2c_stop(state);
-                       goto fail;
-               }
-
-               for (i = 0; i < msg->len; i++) {
-                       ret = mxl111sf_i2c_bitbang_recvbyte(state,
-                                                           &msg->buf[i]);
-                       if (mxl_fail(ret)) {
-                               mxl111sf_i2c_stop(state);
-                               goto fail;
-                       }
-
-                       if (i < msg->len - 1)
-                               mxl111sf_i2c_ack(state);
-               }
-
-               mxl111sf_i2c_nack(state);
-
-               ret = mxl111sf_i2c_stop(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-       } else {
-
-               ret = mxl111sf_i2c_start(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                   (msg->addr << 1) & 0xfe);
-               if (mxl_fail(ret)) {
-                       mxl111sf_i2c_stop(state);
-                       goto fail;
-               }
-
-               for (i = 0; i < msg->len; i++) {
-                       ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                           msg->buf[i]);
-                       if (mxl_fail(ret)) {
-                               mxl111sf_i2c_stop(state);
-                               goto fail;
-                       }
-               }
-
-               /* FIXME: we only want to do this on the last transaction */
-               mxl111sf_i2c_stop(state);
-       }
-fail:
-       return ret;
-}
-
-/* HW-I2C ----------------------------------------------------------------- */
-
-#define USB_WRITE_I2C_CMD     0x99
-#define USB_READ_I2C_CMD      0xdd
-#define USB_END_I2C_CMD       0xfe
-
-#define USB_WRITE_I2C_CMD_LEN   26
-#define USB_READ_I2C_CMD_LEN    24
-
-#define I2C_MUX_REG           0x30
-#define I2C_CONTROL_REG       0x00
-#define I2C_SLAVE_ADDR_REG    0x08
-#define I2C_DATA_REG          0x0c
-#define I2C_INT_STATUS_REG    0x10
-
-static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
-                                 u8 index, u8 *wdata)
-{
-       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
-                                   &wdata[1], 25, NULL, 0);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
-                                u8 index, u8 *wdata, u8 *rdata)
-{
-       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
-                                   &wdata[1], 25, rdata, 24);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
-{
-       u8 status = 0;
-       u8 buf[26];
-
-       mxl_i2c_adv("()");
-
-       buf[0] = USB_READ_I2C_CMD;
-       buf[1] = 0x00;
-
-       buf[2] = I2C_INT_STATUS_REG;
-       buf[3] = 0x00;
-       buf[4] = 0x00;
-
-       buf[5] = USB_END_I2C_CMD;
-
-       mxl111sf_i2c_get_data(state, 0, buf, buf);
-
-       if (buf[1] & 0x04)
-               status = 1;
-
-       return status;
-}
-
-static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
-{
-       u8 status = 0;
-       u8 buf[26];
-
-       mxl_i2c("()");
-
-       buf[0] = USB_READ_I2C_CMD;
-       buf[1] = 0x00;
-
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x00;
-       buf[4] = 0x00;
-
-       buf[5] = I2C_INT_STATUS_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-       buf[8] = USB_END_I2C_CMD;
-
-       mxl111sf_i2c_get_data(state, 0, buf, buf);
-
-       if (0x08 == (buf[1] & 0x08))
-               status = 1;
-
-       if ((buf[5] & 0x02) == 0x02)
-               mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
-
-       return status;
-}
-
-static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
-                                 u8 count, u8 *rbuf)
-{
-       u8 i2c_w_data[26];
-       u8 i2c_r_data[24];
-       u8 i = 0;
-       u8 fifo_status = 0;
-       int status = 0;
-
-       mxl_i2c("read %d bytes", count);
-
-       while ((fifo_status == 0) && (i++ < 5))
-               fifo_status = mxl111sf_i2c_check_fifo(state);
-
-       i2c_w_data[0] = 0xDD;
-       i2c_w_data[1] = 0x00;
-
-       for (i = 2; i < 26; i++)
-               i2c_w_data[i] = 0xFE;
-
-       for (i = 0; i < count; i++) {
-               i2c_w_data[2+(i*3)] = 0x0C;
-               i2c_w_data[3+(i*3)] = 0x00;
-               i2c_w_data[4+(i*3)] = 0x00;
-       }
-
-       mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
-
-       /* Check for I2C NACK status */
-       if (mxl111sf_i2c_check_status(state) == 1) {
-               mxl_i2c("error!");
-       } else {
-               for (i = 0; i < count; i++) {
-                       rbuf[i] = i2c_r_data[(i*3)+1];
-                       mxl_i2c("%02x\t %02x",
-                               i2c_r_data[(i*3)+1],
-                               i2c_r_data[(i*3)+2]);
-               }
-
-               status = 1;
-       }
-
-       return status;
-}
-
-#define HWI2C400 1
-static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
-                                   struct i2c_msg *msg)
-{
-       int i, k, ret = 0;
-       u16 index = 0;
-       u8 buf[26];
-       u8 i2c_r_data[24];
-       u16 block_len;
-       u16 left_over_len;
-       u8 rd_status[8];
-       u8 ret_status;
-       u8 readbuff[26];
-
-       mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
-               msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
-               (!(msg->flags & I2C_M_RD)) ? msg->len : 0);
-
-       for (index = 0; index < 26; index++)
-               buf[index] = USB_END_I2C_CMD;
-
-       /* command to indicate data payload is destined for I2C interface */
-       buf[0] = USB_WRITE_I2C_CMD;
-       buf[1] = 0x00;
-
-       /* enable I2C interface */
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x80;
-       buf[4] = 0x00;
-
-       /* enable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x81;
-       buf[7] = 0x00;
-
-       /* set Timeout register on I2C interface */
-       buf[8] = 0x14;
-       buf[9] = 0xff;
-       buf[10] = 0x00;
-#if 0
-       /* enable Interrupts on I2C interface */
-       buf[8] = 0x24;
-       buf[9] = 0xF7;
-       buf[10] = 0x00;
-#endif
-       buf[11] = 0x24;
-       buf[12] = 0xF7;
-       buf[13] = 0x00;
-
-       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* write data on I2C bus */
-       if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
-               mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
-
-               /* control register on I2C interface to initialize I2C bus */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x5E;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               /* I2C Slave device Address */
-               buf[5] = I2C_SLAVE_ADDR_REG;
-               buf[6] = (msg->addr);
-               buf[7] = 0x00;
-               buf[8] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* check for slave device status */
-               if (mxl111sf_i2c_check_status(state) == 1) {
-                       mxl_i2c("NACK writing slave address %02x",
-                               msg->addr);
-                       /* if NACK, stop I2C bus and exit */
-                       buf[2] = I2C_CONTROL_REG;
-                       buf[3] = 0x4E;
-                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                       ret = -EIO;
-                       goto exit;
-               }
-
-               /* I2C interface can do I2C operations in block of 8 bytes of
-                  I2C data. calculation to figure out number of blocks of i2c
-                  data required to program */
-               block_len = (msg->len / 8);
-               left_over_len = (msg->len % 8);
-               index = 0;
-
-               mxl_i2c("block_len %d, left_over_len %d",
-                       block_len, left_over_len);
-
-               for (index = 0; index < block_len; index++) {
-                       for (i = 0; i < 8; i++) {
-                               /* write data on I2C interface */
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = msg->buf[(index*8)+i];
-                               buf[4+(i*3)] = 0x00;
-                       }
-
-                       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK writing slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0x4E;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-               }
-
-               if (left_over_len) {
-                       for (k = 0; k < 26; k++)
-                               buf[k] = USB_END_I2C_CMD;
-
-                       buf[0] = 0x99;
-                       buf[1] = 0x00;
-
-                       for (i = 0; i < left_over_len; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = msg->buf[(index*8)+i];
-                               mxl_i2c("index = %d %d data %d",
-                                       index, i, msg->buf[(index*8)+i]);
-                               buf[4+(i*3)] = 0x00;
-                       }
-                       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK writing slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0x4E;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-               }
-
-               /* issue I2C STOP after write */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x4E;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-       }
-
-       /* read data from I2C bus */
-       if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
-               mxl_i2c("read buf len %d", msg->len);
-
-               /* command to indicate data payload is
-                  destined for I2C interface */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0xDF;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               /* I2C xfer length */
-               buf[5] = 0x14;
-               buf[6] = (msg->len & 0xFF);
-               buf[7] = 0;
-
-               /* I2C slave device Address */
-               buf[8] = I2C_SLAVE_ADDR_REG;
-               buf[9] = msg->addr;
-               buf[10] = 0x00;
-               buf[11] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* check for I2C NACK status */
-               if (mxl111sf_i2c_check_status(state) == 1) {
-                       mxl_i2c("NACK reading slave address %02x",
-                               msg->addr);
-
-                       /* if NACK, stop I2C bus and exit */
-                       buf[2] = I2C_CONTROL_REG;
-                       buf[3] = 0xC7;
-                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                       ret = -EIO;
-                       goto exit;
-               }
-
-               /* I2C interface can do I2C operations in block of 8 bytes of
-                  I2C data. calculation to figure out number of blocks of
-                  i2c data required to program */
-               block_len = ((msg->len) / 8);
-               left_over_len = ((msg->len) % 8);
-               index = 0;
-
-               mxl_i2c("block_len %d, left_over_len %d",
-                       block_len, left_over_len);
-
-               /* command to read data from I2C interface */
-               buf[0] = USB_READ_I2C_CMD;
-               buf[1] = 0x00;
-
-               for (index = 0; index < block_len; index++) {
-                       /* setup I2C read request packet on I2C interface */
-                       for (i = 0; i < 8; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = 0x00;
-                               buf[4+(i*3)] = 0x00;
-                       }
-
-                       ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK reading slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0xC7;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-                       /* copy data from i2c data payload to read buffer */
-                       for (i = 0; i < 8; i++) {
-                               rd_status[i] = i2c_r_data[(i*3)+2];
-
-                               if (rd_status[i] == 0x04) {
-                                       if (i < 7) {
-                                               mxl_i2c("i2c fifo empty!"
-                                                       " @ %d", i);
-                                               msg->buf[(index*8)+i] =
-                                                       i2c_r_data[(i*3)+1];
-                                               /* read again */
-                                               ret_status =
-                                                       mxl111sf_i2c_readagain(
-                                                               state, 8-(i+1),
-                                                               readbuff);
-                                               if (ret_status == 1) {
-                                                       for (k = 0;
-                                                            k < 8-(i+1);
-                                                            k++) {
-
-                                       msg->buf[(index*8)+(k+i+1)] =
-                                               readbuff[k];
-                                       mxl_i2c("read data: %02x\t %02x",
-                                               msg->buf[(index*8)+(k+i)],
-                                               (index*8)+(k+i));
-                                       mxl_i2c("read data: %02x\t %02x",
-                                               msg->buf[(index*8)+(k+i+1)],
-                                               readbuff[k]);
-
-                                                       }
-                                                       goto stop_copy;
-                                               } else {
-                                                       mxl_i2c("readagain "
-                                                               "ERROR!");
-                                               }
-                                       } else {
-                                               msg->buf[(index*8)+i] =
-                                                       i2c_r_data[(i*3)+1];
-                                       }
-                               } else {
-                                       msg->buf[(index*8)+i] =
-                                               i2c_r_data[(i*3)+1];
-                               }
-                       }
-stop_copy:
-                       ;
-
-               }
-
-               if (left_over_len) {
-                       for (k = 0; k < 26; k++)
-                               buf[k] = USB_END_I2C_CMD;
-
-                       buf[0] = 0xDD;
-                       buf[1] = 0x00;
-
-                       for (i = 0; i < left_over_len; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = 0x00;
-                               buf[4+(i*3)] = 0x00;
-                       }
-                       ret = mxl111sf_i2c_get_data(state, 0, buf,
-                                                   i2c_r_data);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK reading slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0xC7;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-                       for (i = 0; i < left_over_len; i++) {
-                               msg->buf[(block_len*8)+i] =
-                                       i2c_r_data[(i*3)+1];
-                               mxl_i2c("read data: %02x\t %02x",
-                                       i2c_r_data[(i*3)+1],
-                                       i2c_r_data[(i*3)+2]);
-                       }
-               }
-
-               /* indicate I2C interface to issue NACK
-                  after next I2C read op */
-               buf[0] = USB_WRITE_I2C_CMD;
-               buf[1] = 0x00;
-
-               /* control register */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x17;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               buf[5] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* control register */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0xC7;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-       }
-exit:
-       /* STOP and disable I2C MUX */
-       buf[0] = USB_WRITE_I2C_CMD;
-       buf[1] = 0x00;
-
-       /* de-initilize I2C BUS */
-       buf[5] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* Control Register */
-       buf[2] = I2C_CONTROL_REG;
-       buf[3] = 0xDF;
-       buf[4] = 0x03;
-
-       /* disable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-
-       /* de-initilize I2C BUS */
-       buf[8] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* disable I2C interface */
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x81;
-       buf[4] = 0x00;
-
-       /* disable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-
-       /* disable I2C interface */
-       buf[8] = I2C_MUX_REG;
-       buf[9] = 0x00;
-       buf[10] = 0x00;
-
-       buf[11] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
-                     struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct mxl111sf_state *state = d->priv;
-       int hwi2c = (state->chip_rev > MXL111SF_V6);
-       int i, ret;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               ret = (hwi2c) ?
-                       mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
-                       mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
-               if (mxl_fail(ret)) {
-                       mxl_debug_adv("failed with error %d on i2c "
-                                     "transaction %d of %d, %sing %d bytes "
-                                     "to/from 0x%02x", ret, i+1, num,
-                                     (msg[i].flags & I2C_M_RD) ?
-                                     "read" : "writ",
-                                     msg[i].len, msg[i].addr);
-
-                       break;
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return i == num ? num : -EREMOTEIO;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h
deleted file mode 100644 (file)
index a57a45f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  mxl111sf-i2c.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_I2C_H_
-#define _DVB_USB_MXL111SF_I2C_H_
-
-#include <linux/i2c.h>
-
-int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
-                     struct i2c_msg msg[], int num);
-
-#endif /* _DVB_USB_MXL111SF_I2C_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c
deleted file mode 100644 (file)
index b741b3a..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *  mxl111sf-phy.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-phy.h"
-#include "mxl111sf-reg.h"
-
-int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
-{
-       struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
-               {0x07, 0xff, 0x0c},
-               {0x58, 0xff, 0x9d},
-               {0x09, 0xff, 0x00},
-               {0x06, 0xff, 0x06},
-               {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
-               {0x8d, 0x01, 0x01}, /* NEGATE_Q */
-               {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
-               {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
-               {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
-               {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
-               {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
-               {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
-               {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
-               {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
-               {0x00, 0xff, 0x01}, /* Change to page 1 */
-               {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
-               {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
-               {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
-               {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
-               {0x00, 0xff, 0x00}, /* Change to page 0 */
-               {0,    0,    0}
-       };
-
-       mxl_debug("()");
-
-       return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
-}
-
-int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
-{
-       int ret;
-       mxl_debug("()");
-
-       ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
-{
-       int ret;
-
-       mxl_debug("(%s)", MXL_SOC_MODE == mode ?
-               "MXL_SOC_MODE" : "MXL_TUNER_MODE");
-
-       /* set device mode */
-       ret = mxl111sf_write_reg(state, 0x03,
-                                MXL_SOC_MODE == mode ? 0x01 : 0x00);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg_mask(state,
-                                     0x7d, 0x40, MXL_SOC_MODE == mode ?
-                                     0x00 : /* enable impulse noise filter,
-                                               INF_BYP = 0 */
-                                     0x40); /* disable impulse noise filter,
-                                               INF_BYP = 1 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->device_mode = mode;
-fail:
-       return ret;
-}
-
-/* power up tuner */
-int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
-{
-       mxl_debug("(%d)", onoff);
-
-       return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
-}
-
-int mxl111sf_disable_656_port(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
-}
-
-int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
-}
-
-/* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
-int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
-                           unsigned int parallel_serial,
-                           unsigned int msb_lsb_1st,
-                           unsigned int clock_phase,
-                           unsigned int mpeg_valid_pol,
-                           unsigned int mpeg_sync_pol)
-{
-       int ret;
-       u8 mode, tmp;
-
-       mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
-                 clock_phase, mpeg_valid_pol, mpeg_sync_pol);
-
-       /* Enable PIN MUX */
-       ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
-       mxl_fail(ret);
-
-       /* Configure MPEG Clock phase */
-       mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
-
-       if (clock_phase == TSIF_NORMAL)
-               mode &= ~V6_INVERTED_CLK_PHASE;
-       else
-               mode |= V6_INVERTED_CLK_PHASE;
-
-       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
-       mxl_fail(ret);
-
-       /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
-        * Get current configuration */
-       ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
-       mxl_fail(ret);
-
-       /* Data Input mode */
-       if (parallel_serial == TSIF_INPUT_PARALLEL) {
-               /* Disable serial mode */
-               mode &= ~V6_MPEG_IN_DATA_SERIAL;
-
-               /* Enable Parallel mode */
-               mode |= V6_MPEG_IN_DATA_PARALLEL;
-       } else {
-               /* Disable Parallel mode */
-               mode &= ~V6_MPEG_IN_DATA_PARALLEL;
-
-               /* Enable Serial Mode */
-               mode |= V6_MPEG_IN_DATA_SERIAL;
-
-               /* If serial interface is chosen, configure
-                  MSB or LSB order in transmission */
-               ret = mxl111sf_read_reg(state,
-                                       V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
-                                       &tmp);
-               mxl_fail(ret);
-
-               if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
-                       tmp |= V6_MPEG_SER_MSB_FIRST;
-               else
-                       tmp &= ~V6_MPEG_SER_MSB_FIRST;
-
-               ret = mxl111sf_write_reg(state,
-                                        V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
-                                        tmp);
-               mxl_fail(ret);
-       }
-
-       /* MPEG Sync polarity */
-       if (mpeg_sync_pol == TSIF_NORMAL)
-               mode &= ~V6_INVERTED_MPEG_SYNC;
-       else
-               mode |= V6_INVERTED_MPEG_SYNC;
-
-       /* MPEG Valid polarity */
-       if (mpeg_valid_pol == 0)
-               mode &= ~V6_INVERTED_MPEG_VALID;
-       else
-               mode |= V6_INVERTED_MPEG_VALID;
-
-       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
-{
-       static struct mxl111sf_reg_ctrl_info init_i2s[] = {
-               {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
-               {0x15, 0x60, 0x60}, /* Enable I2S */
-               {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
-                                      Inverted 656 Clock, I2S_SOFT_RESET,
-                                      0 : Normal operation, 1 : Reset State */
-#if 0
-               {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
-#endif
-               {0x00, 0xff, 0x02}, /* Change to Control Page */
-               {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
-               {0x00, 0xff, 0x00},
-               {0,    0,    0}
-       };
-       int ret;
-
-       mxl_debug("(0x%02x)", sample_size);
-
-       ret = mxl111sf_ctrl_program_regs(state, init_i2s);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
-{
-       static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
-               {0x15, 0x40, 0x00},
-               {0,    0,    0}
-       };
-
-       mxl_debug("()");
-
-       return mxl111sf_ctrl_program_regs(state, disable_i2s);
-}
-
-int mxl111sf_config_i2s(struct mxl111sf_state *state,
-                       u8 msb_start_pos, u8 data_width)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
-
-       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       tmp &= 0xe0;
-       tmp |= msb_start_pos;
-       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       tmp &= 0xe0;
-       tmp |= data_width;
-       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
-{
-       u8 val;
-       int ret;
-
-       mxl_debug("(%d)", onoff);
-
-       ret = mxl111sf_write_reg(state, 0x00, 0x02);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (onoff)
-               val |= 0x04;
-       else
-               val &= ~0x04;
-
-       ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, 0x00, 0x00);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_idac_config(struct mxl111sf_state *state,
-                        u8 control_mode, u8 current_setting,
-                        u8 current_value, u8 hysteresis_value)
-{
-       int ret;
-       u8 val;
-       /* current value will be set for both automatic & manual IDAC control */
-       val = current_value;
-
-       if (control_mode == IDAC_MANUAL_CONTROL) {
-               /* enable manual control of IDAC */
-               val |= IDAC_MANUAL_CONTROL_BIT_MASK;
-
-               if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
-                       /* enable current sinking in manual mode */
-                       val |= IDAC_CURRENT_SINKING_BIT_MASK;
-               else
-                       /* disable current sinking in manual mode */
-                       val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
-       } else {
-               /* disable manual control of IDAC */
-               val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
-
-               /* set hysteresis value  reg: 0x0B<5:0> */
-               ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
-                                        (hysteresis_value & 0x3F));
-               mxl_fail(ret);
-       }
-
-       ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h
deleted file mode 100644 (file)
index f075607..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  mxl111sf-phy.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_PHY_H_
-#define _DVB_USB_MXL111SF_PHY_H_
-
-#include "mxl111sf.h"
-
-int mxl1x1sf_soft_reset(struct mxl111sf_state *state);
-int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode);
-int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff);
-int mxl111sf_disable_656_port(struct mxl111sf_state *state);
-int mxl111sf_init_tuner_demod(struct mxl111sf_state *state);
-int mxl111sf_enable_usb_output(struct mxl111sf_state *state);
-int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
-                           unsigned int parallel_serial,
-                           unsigned int msb_lsb_1st,
-                           unsigned int clock_phase,
-                           unsigned int mpeg_valid_pol,
-                           unsigned int mpeg_sync_pol);
-int mxl111sf_config_i2s(struct mxl111sf_state *state,
-                       u8 msb_start_pos, u8 data_width);
-int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size);
-int mxl111sf_disable_i2s_port(struct mxl111sf_state *state);
-int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff);
-int mxl111sf_idac_config(struct mxl111sf_state *state,
-                        u8 control_mode, u8 current_setting,
-                        u8 current_value, u8 hysteresis_value);
-
-#endif /* _DVB_USB_MXL111SF_PHY_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h
deleted file mode 100644 (file)
index 17831b0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  mxl111sf-reg.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_REG_H_
-#define _DVB_USB_MXL111SF_REG_H_
-
-#define CHIP_ID_REG                  0xFC
-#define TOP_CHIP_REV_ID_REG          0xFA
-
-#define V6_SNR_RB_LSB_REG            0x27
-#define V6_SNR_RB_MSB_REG            0x28
-
-#define V6_N_ACCUMULATE_REG          0x11
-#define V6_RS_AVG_ERRORS_LSB_REG     0x2C
-#define V6_RS_AVG_ERRORS_MSB_REG     0x2D
-
-#define V6_IRQ_STATUS_REG            0x24
-#define  IRQ_MASK_FEC_LOCK       0x10
-
-#define V6_SYNC_LOCK_REG             0x28
-#define SYNC_LOCK_MASK           0x10
-
-#define V6_RS_LOCK_DET_REG           0x28
-#define  RS_LOCK_DET_MASK        0x08
-
-#define V6_INITACQ_NODETECT_REG    0x20
-#define V6_FORCE_NFFT_CPSIZE_REG   0x20
-
-#define V6_CODE_RATE_TPS_REG       0x29
-#define V6_CODE_RATE_TPS_MASK      0x07
-
-
-#define V6_CP_LOCK_DET_REG        0x28
-#define V6_CP_LOCK_DET_MASK       0x04
-
-#define V6_TPS_HIERACHY_REG        0x29
-#define V6_TPS_HIERARCHY_INFO_MASK  0x40
-
-#define V6_MODORDER_TPS_REG        0x2A
-#define V6_PARAM_CONSTELLATION_MASK   0x30
-
-#define V6_MODE_TPS_REG            0x2A
-#define V6_PARAM_FFT_MODE_MASK        0x0C
-
-
-#define V6_CP_TPS_REG             0x29
-#define V6_PARAM_GI_MASK              0x30
-
-#define V6_TPS_LOCK_REG           0x2A
-#define V6_PARAM_TPS_LOCK_MASK        0x40
-
-#define V6_FEC_PER_COUNT_REG      0x2E
-#define V6_FEC_PER_SCALE_REG      0x2B
-#define V6_FEC_PER_SCALE_MASK        0x03
-#define V6_FEC_PER_CLR_REG        0x20
-#define V6_FEC_PER_CLR_MASK          0x01
-
-#define V6_PIN_MUX_MODE_REG       0x1B
-#define V6_ENABLE_PIN_MUX            0x1E
-
-#define V6_I2S_NUM_SAMPLES_REG    0x16
-
-#define V6_MPEG_IN_CLK_INV_REG    0x17
-#define V6_MPEG_IN_CTRL_REG       0x18
-
-#define V6_INVERTED_CLK_PHASE       0x20
-#define V6_MPEG_IN_DATA_PARALLEL    0x01
-#define V6_MPEG_IN_DATA_SERIAL      0x02
-
-#define V6_INVERTED_MPEG_SYNC       0x04
-#define V6_INVERTED_MPEG_VALID      0x08
-
-#define TSIF_INPUT_PARALLEL         0
-#define TSIF_INPUT_SERIAL           1
-#define TSIF_NORMAL                 0
-
-#define V6_MPEG_INOUT_BIT_ORDER_CTRL_REG  0x19
-#define V6_MPEG_SER_MSB_FIRST                0x80
-#define MPEG_SER_MSB_FIRST_ENABLED        0x01
-
-#define V6_656_I2S_BUFF_STATUS_REG   0x2F
-#define V6_656_OVERFLOW_MASK_BIT         0x08
-#define V6_I2S_OVERFLOW_MASK_BIT         0x01
-
-#define V6_I2S_STREAM_START_BIT_REG  0x14
-#define V6_I2S_STREAM_END_BIT_REG    0x15
-#define I2S_RIGHT_JUSTIFIED     0
-#define I2S_LEFT_JUSTIFIED      1
-#define I2S_DATA_FORMAT         2
-
-#define V6_TUNER_LOOP_THRU_CONTROL_REG  0x09
-#define V6_ENABLE_LOOP_THRU               0x01
-
-#define TOTAL_NUM_IF_OUTPUT_FREQ       16
-
-#define TUNER_NORMAL_IF_SPECTRUM       0x0
-#define TUNER_INVERT_IF_SPECTRUM       0x10
-
-#define V6_TUNER_IF_SEL_REG              0x06
-#define V6_TUNER_IF_FCW_REG              0x3C
-#define V6_TUNER_IF_FCW_BYP_REG          0x3D
-#define V6_RF_LOCK_STATUS_REG            0x23
-
-#define NUM_DIG_TV_CHANNEL     1000
-
-#define V6_DIG_CLK_FREQ_SEL_REG  0x07
-#define V6_REF_SYNTH_INT_REG     0x5C
-#define V6_REF_SYNTH_REMAIN_REG  0x58
-#define V6_DIG_RFREFSELECT_REG   0x32
-#define V6_XTAL_CLK_OUT_GAIN_REG   0x31
-#define V6_TUNER_LOOP_THRU_CTRL_REG      0x09
-#define V6_DIG_XTAL_ENABLE_REG  0x06
-#define V6_DIG_XTAL_BIAS_REG  0x66
-#define V6_XTAL_CAP_REG    0x08
-
-#define V6_GPO_CTRL_REG     0x18
-#define MXL_GPO_0           0x00
-#define MXL_GPO_1           0x01
-#define V6_GPO_0_MASK       0x10
-#define V6_GPO_1_MASK       0x20
-
-#define V6_111SF_GPO_CTRL_REG     0x19
-#define MXL_111SF_GPO_1               0x00
-#define MXL_111SF_GPO_2               0x01
-#define MXL_111SF_GPO_3               0x02
-#define MXL_111SF_GPO_4               0x03
-#define MXL_111SF_GPO_5               0x04
-#define MXL_111SF_GPO_6               0x05
-#define MXL_111SF_GPO_7               0x06
-
-#define MXL_111SF_GPO_0_MASK          0x01
-#define MXL_111SF_GPO_1_MASK          0x02
-#define MXL_111SF_GPO_2_MASK          0x04
-#define MXL_111SF_GPO_3_MASK          0x08
-#define MXL_111SF_GPO_4_MASK          0x10
-#define MXL_111SF_GPO_5_MASK          0x20
-#define MXL_111SF_GPO_6_MASK          0x40
-
-#define V6_ATSC_CONFIG_REG  0x0A
-
-#define MXL_MODE_REG    0x03
-#define START_TUNE_REG  0x1C
-
-#define V6_IDAC_HYSTERESIS_REG    0x0B
-#define V6_IDAC_SETTINGS_REG      0x0C
-#define IDAC_MANUAL_CONTROL             1
-#define IDAC_CURRENT_SINKING_ENABLE     1
-#define IDAC_MANUAL_CONTROL_BIT_MASK      0x80
-#define IDAC_CURRENT_SINKING_BIT_MASK     0x40
-
-#define V8_SPI_MODE_REG  0xE9
-
-#define V6_DIG_RF_PWR_LSB_REG  0x46
-#define V6_DIG_RF_PWR_MSB_REG  0x47
-
-#endif /* _DVB_USB_MXL111SF_REG_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c
deleted file mode 100644 (file)
index ef4c65f..0000000
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- *  mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-tuner.h"
-#include "mxl111sf-phy.h"
-#include "mxl111sf-reg.h"
-
-/* debug */
-static int mxl111sf_tuner_debug;
-module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define mxl_dbg(fmt, arg...) \
-       if (mxl111sf_tuner_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define err pr_err
-
-/* ------------------------------------------------------------------------ */
-
-struct mxl111sf_tuner_state {
-       struct mxl111sf_state *mxl_state;
-
-       struct mxl111sf_tuner_config *cfg;
-
-       enum mxl_if_freq if_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
-                                  u8 addr, u8 *data)
-{
-       return (state->cfg->read_reg) ?
-               state->cfg->read_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
-                                   u8 addr, u8 data)
-{
-       return (state->cfg->write_reg) ?
-               state->cfg->write_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       return (state->cfg->program_regs) ?
-               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
-               -EINVAL;
-}
-
-static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
-                                         int onoff)
-{
-       return (state->cfg->top_master_ctrl) ?
-               state->cfg->top_master_ctrl(state->mxl_state, onoff) :
-               -EINVAL;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
-       {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
-                              DIG_MODEINDEX, _A, _CSF, */
-       {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
-       {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
-       {0,    0,    0}
-};
-
-/* ------------------------------------------------------------------------ */
-
-static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
-                                                                 u8 bw)
-{
-       u8 filt_bw;
-
-       /* set channel bandwidth */
-       switch (bw) {
-       case 0: /* ATSC */
-               filt_bw = 25;
-               break;
-       case 1: /* QAM */
-               filt_bw = 69;
-               break;
-       case 6:
-               filt_bw = 21;
-               break;
-       case 7:
-               filt_bw = 42;
-               break;
-       case 8:
-               filt_bw = 63;
-               break;
-       default:
-               err("%s: invalid bandwidth setting!", __func__);
-               return NULL;
-       }
-
-       /* calculate RF channel */
-       freq /= 1000000;
-
-       freq *= 64;
-#if 0
-       /* do round */
-       freq += 0.5;
-#endif
-       /* set bandwidth */
-       mxl_phy_tune_rf[0].data = filt_bw;
-
-       /* set RF */
-       mxl_phy_tune_rf[1].data = (freq & 0xff);
-       mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
-
-       /* start tune */
-       return mxl_phy_tune_rf;
-}
-
-static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
-{
-       int ret;
-       u8 ctrl;
-#if 0
-       u16 iffcw;
-       u32 if_freq;
-#endif
-       mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
-               state->cfg->invert_spectrum, state->cfg->if_freq);
-
-       /* set IF polarity */
-       ctrl = state->cfg->invert_spectrum;
-
-       ctrl |= state->cfg->if_freq;
-
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-#if 0
-       if_freq /= 1000000;
-
-       /* do round */
-       if_freq += 0.5;
-
-       if (MXL_IF_LO == state->cfg->if_freq) {
-               ctrl = 0x08;
-               iffcw = (u16)(if_freq / (108 * 4096));
-       } else if (MXL_IF_HI == state->cfg->if_freq) {
-               ctrl = 0x08;
-               iffcw = (u16)(if_freq / (216 * 4096));
-       } else {
-               ctrl = 0;
-               iffcw = 0;
-       }
-
-       ctrl |= (iffcw >> 8);
-#endif
-       ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ctrl &= 0xf0;
-       ctrl |= 0x90;
-
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-#if 0
-       ctrl = iffcw & 0x00ff;
-#endif
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->if_freq = state->cfg->if_freq;
-fail:
-       return ret;
-}
-
-static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
-       int ret;
-       u8 mxl_mode;
-
-       mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
-
-       /* stop tune */
-       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* check device mode */
-       ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* Fill out registers for channel tune */
-       reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
-       if (!reg_ctrl_array)
-               return -EINVAL;
-
-       ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
-               /* IF tuner mode only */
-               mxl1x1sf_tuner_top_master_ctrl(state, 0);
-               mxl1x1sf_tuner_top_master_ctrl(state, 1);
-               mxl1x1sf_tuner_set_if_output_freq(state);
-       }
-
-       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (state->cfg->ant_hunt)
-               state->cfg->ant_hunt(fe);
-fail:
-       return ret;
-}
-
-static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
-                                         int *rf_synth_lock,
-                                         int *ref_synth_lock)
-{
-       int ret;
-       u8 data;
-
-       *rf_synth_lock = 0;
-       *ref_synth_lock = 0;
-
-       ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
-       *rf_synth_lock  = ((data & 0x0c) == 0x0c) ? 1 : 0;
-fail:
-       return ret;
-}
-
-#if 0
-static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
-                                        int onoff)
-{
-       return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
-                                       onoff ? 1 : 0);
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys  = c->delivery_system;
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-       u8 bw;
-
-       mxl_dbg("()");
-
-       switch (delsys) {
-       case SYS_ATSC:
-       case SYS_ATSCMH:
-               bw = 0; /* ATSC */
-               break;
-       case SYS_DVBC_ANNEX_B:
-               bw = 1; /* US CABLE */
-               break;
-       case SYS_DVBT:
-               switch (c->bandwidth_hz) {
-               case 6000000:
-                       bw = 6;
-                       break;
-               case 7000000:
-                       bw = 7;
-                       break;
-               case 8000000:
-                       bw = 8;
-                       break;
-               default:
-                       err("%s: bandwidth not set!", __func__);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               err("%s: modulation type not supported!", __func__);
-               return -EINVAL;
-       }
-       ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->frequency = c->frequency;
-       state->bandwidth = c->bandwidth_hz;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#if 0
-static int mxl111sf_tuner_init(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-
-       /* wake from standby handled by usb driver */
-
-       return ret;
-}
-
-static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-
-       /* enter standby mode handled by usb driver */
-
-       return ret;
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int rf_locked, ref_locked, ret;
-
-       *status = 0;
-
-       ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
-       if (mxl_fail(ret))
-               goto fail;
-       mxl_info("%s%s", rf_locked ? "rf locked " : "",
-                ref_locked ? "ref locked" : "");
-
-       if ((rf_locked) || (ref_locked))
-               *status |= TUNER_STATUS_LOCKED;
-fail:
-       return ret;
-}
-
-static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       u8 val1, val2;
-       int ret;
-
-       *strength = 0;
-
-       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *strength = val1 | ((val2 & 0x07) << 8);
-fail:
-       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       *frequency = state->frequency;
-       return 0;
-}
-
-static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       *bandwidth = state->bandwidth;
-       return 0;
-}
-
-static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
-                                          u32 *frequency)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-
-       *frequency = 0;
-
-       switch (state->if_freq) {
-       case MXL_IF_4_0:   /* 4.0   MHz */
-               *frequency = 4000000;
-               break;
-       case MXL_IF_4_5:   /* 4.5   MHz */
-               *frequency = 4500000;
-               break;
-       case MXL_IF_4_57:  /* 4.57  MHz */
-               *frequency = 4570000;
-               break;
-       case MXL_IF_5_0:   /* 5.0   MHz */
-               *frequency = 5000000;
-               break;
-       case MXL_IF_5_38:  /* 5.38  MHz */
-               *frequency = 5380000;
-               break;
-       case MXL_IF_6_0:   /* 6.0   MHz */
-               *frequency = 6000000;
-               break;
-       case MXL_IF_6_28:  /* 6.28  MHz */
-               *frequency = 6280000;
-               break;
-       case MXL_IF_7_2:   /* 7.2   MHz */
-               *frequency = 7200000;
-               break;
-       case MXL_IF_35_25: /* 35.25 MHz */
-               *frequency = 35250000;
-               break;
-       case MXL_IF_36:    /* 36    MHz */
-               *frequency = 36000000;
-               break;
-       case MXL_IF_36_15: /* 36.15 MHz */
-               *frequency = 36150000;
-               break;
-       case MXL_IF_44:    /* 44    MHz */
-               *frequency = 44000000;
-               break;
-       }
-       return 0;
-}
-
-static int mxl111sf_tuner_release(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       mxl_dbg("()");
-       kfree(state);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
-       .info = {
-               .name = "MaxLinear MxL111SF",
-#if 0
-               .frequency_min  = ,
-               .frequency_max  = ,
-               .frequency_step = ,
-#endif
-       },
-#if 0
-       .init              = mxl111sf_tuner_init,
-       .sleep             = mxl111sf_tuner_sleep,
-#endif
-       .set_params        = mxl111sf_tuner_set_params,
-       .get_status        = mxl111sf_tuner_get_status,
-       .get_rf_strength   = mxl111sf_get_rf_strength,
-       .get_frequency     = mxl111sf_tuner_get_frequency,
-       .get_bandwidth     = mxl111sf_tuner_get_bandwidth,
-       .get_if_frequency  = mxl111sf_tuner_get_if_frequency,
-       .release           = mxl111sf_tuner_release,
-};
-
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg)
-{
-       struct mxl111sf_tuner_state *state = NULL;
-
-       mxl_dbg("()");
-
-       state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->mxl_state = mxl_state;
-       state->cfg = cfg;
-
-       memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = state;
-       return fe;
-}
-EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
-
-MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h
deleted file mode 100644 (file)
index ff33396..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 __MXL111SF_TUNER_H__
-#define __MXL111SF_TUNER_H__
-
-#include "dvb_frontend.h"
-
-#include "mxl111sf.h"
-
-enum mxl_if_freq {
-#if 0
-       MXL_IF_LO    = 0x00, /* other IF < 9MHz */
-#endif
-       MXL_IF_4_0   = 0x01, /* 4.0   MHz */
-       MXL_IF_4_5   = 0x02, /* 4.5   MHz */
-       MXL_IF_4_57  = 0x03, /* 4.57  MHz */
-       MXL_IF_5_0   = 0x04, /* 5.0   MHz */
-       MXL_IF_5_38  = 0x05, /* 5.38  MHz */
-       MXL_IF_6_0   = 0x06, /* 6.0   MHz */
-       MXL_IF_6_28  = 0x07, /* 6.28  MHz */
-       MXL_IF_7_2   = 0x08, /* 7.2   MHz */
-       MXL_IF_35_25 = 0x09, /* 35.25 MHz */
-       MXL_IF_36    = 0x0a, /* 36    MHz */
-       MXL_IF_36_15 = 0x0b, /* 36.15 MHz */
-       MXL_IF_44    = 0x0c, /* 44    MHz */
-#if 0
-       MXL_IF_HI    = 0x0f, /* other IF > 35 MHz and < 45 MHz */
-#endif
-};
-
-struct mxl111sf_tuner_config {
-       enum mxl_if_freq if_freq;
-       unsigned int invert_spectrum:1;
-
-       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
-       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
-       int (*program_regs)(struct mxl111sf_state *state,
-                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-       int (*top_master_ctrl)(struct mxl111sf_state *state, int onoff);
-       int (*ant_hunt)(struct dvb_frontend *fe);
-};
-
-/* ------------------------------------------------------------------------ */
-
-#if defined(CONFIG_DVB_USB_MXL111SF) || \
-       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
-extern
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg);
-#else
-static inline
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state
-                                          struct mxl111sf_tuner_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __MXL111SF_TUNER_H__ */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf.c
deleted file mode 100644 (file)
index efdcb15..0000000
+++ /dev/null
@@ -1,1431 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-
-#include <linux/vmalloc.h>
-#include <linux/i2c.h>
-
-#include "mxl111sf.h"
-#include "mxl111sf-reg.h"
-#include "mxl111sf-phy.h"
-#include "mxl111sf-i2c.h"
-#include "mxl111sf-gpio.h"
-
-#include "mxl111sf-demod.h"
-#include "mxl111sf-tuner.h"
-
-#include "lgdt3305.h"
-#include "lg2160.h"
-
-int dvb_usb_mxl111sf_debug;
-module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level "
-                "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
-
-int dvb_usb_mxl111sf_isoc;
-module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
-MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
-
-int dvb_usb_mxl111sf_spi;
-module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
-MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
-
-#define ANT_PATH_AUTO 0
-#define ANT_PATH_EXTERNAL 1
-#define ANT_PATH_INTERNAL 2
-
-int dvb_usb_mxl111sf_rfswitch =
-#if 0
-               ANT_PATH_AUTO;
-#else
-               ANT_PATH_EXTERNAL;
-#endif
-
-module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
-MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_info pr_debug
-#define deb_reg pr_debug
-#define deb_adv pr_debug
-#define err pr_err
-#define info pr_info
-
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
-                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       int wo = (rbuf == NULL || rlen == 0); /* write-only */
-       int ret;
-       u8 sndbuf[1+wlen];
-
-       deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
-
-       memset(sndbuf, 0, 1+wlen);
-
-       sndbuf[0] = cmd;
-       memcpy(&sndbuf[1], wbuf, wlen);
-
-       ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
-               dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#define MXL_CMD_REG_READ       0xaa
-#define MXL_CMD_REG_WRITE      0x55
-
-int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
-{
-       u8 buf[2];
-       int ret;
-
-       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
-       if (mxl_fail(ret)) {
-               mxl_debug("error reading reg: 0x%02x", addr);
-               goto fail;
-       }
-
-       if (buf[0] == addr)
-               *data = buf[1];
-       else {
-               err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
-                   addr, buf[0], buf[1]);
-               ret = -EINVAL;
-       }
-
-       deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
-fail:
-       return ret;
-}
-
-int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
-{
-       u8 buf[] = { addr, data };
-       int ret;
-
-       deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
-
-       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
-       if (mxl_fail(ret))
-               err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
-                                  u8 addr, u8 mask, u8 data)
-{
-       int ret;
-       u8 val;
-
-       if (mask != 0xff) {
-               ret = mxl111sf_read_reg(state, addr, &val);
-#if 1
-               /* dont know why this usually errors out on the first try */
-               if (mxl_fail(ret))
-                       err("error writing addr: 0x%02x, mask: 0x%02x, "
-                           "data: 0x%02x, retrying...", addr, mask, data);
-
-               ret = mxl111sf_read_reg(state, addr, &val);
-#endif
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-       val &= ~mask;
-       val |= data;
-
-       ret = mxl111sf_write_reg(state, addr, val);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       int i, ret = 0;
-
-       for (i = 0;  ctrl_reg_info[i].addr |
-                    ctrl_reg_info[i].mask |
-                    ctrl_reg_info[i].data;  i++) {
-
-               ret = mxl111sf_write_reg_mask(state,
-                                             ctrl_reg_info[i].addr,
-                                             ctrl_reg_info[i].mask,
-                                             ctrl_reg_info[i].data);
-               if (mxl_fail(ret)) {
-                       err("failed on reg #%d (0x%02x)", i,
-                           ctrl_reg_info[i].addr);
-                       break;
-               }
-       }
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 id, ver;
-       char *mxl_chip, *mxl_rev;
-
-       if ((state->chip_id) && (state->chip_ver))
-               return 0;
-
-       ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
-       if (mxl_fail(ret))
-               goto fail;
-       state->chip_id = id;
-
-       ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
-       if (mxl_fail(ret))
-               goto fail;
-       state->chip_ver = ver;
-
-       switch (id) {
-       case 0x61:
-               mxl_chip = "MxL101SF";
-               break;
-       case 0x63:
-               mxl_chip = "MxL111SF";
-               break;
-       default:
-               mxl_chip = "UNKNOWN MxL1X1";
-               break;
-       }
-       switch (ver) {
-       case 0x36:
-               state->chip_rev = MXL111SF_V6;
-               mxl_rev = "v6";
-               break;
-       case 0x08:
-               state->chip_rev = MXL111SF_V8_100;
-               mxl_rev = "v8_100";
-               break;
-       case 0x18:
-               state->chip_rev = MXL111SF_V8_200;
-               mxl_rev = "v8_200";
-               break;
-       default:
-               state->chip_rev = 0;
-               mxl_rev = "UNKNOWN REVISION";
-               break;
-       }
-       info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
-fail:
-       return ret;
-}
-
-#define get_chip_info(state)                                           \
-({                                                                     \
-       int ___ret;                                                     \
-       ___ret = mxl1x1sf_get_chip_info(state);                         \
-       if (mxl_fail(___ret)) {                                         \
-               mxl_debug("failed to get chip info"                     \
-                         " on first probe attempt");                   \
-               ___ret = mxl1x1sf_get_chip_info(state);                 \
-               if (mxl_fail(___ret))                                   \
-                       err("failed to get chip info during probe");    \
-               else                                                    \
-                       mxl_debug("probe needed a retry "               \
-                                 "in order to succeed.");              \
-       }                                                               \
-       ___ret;                                                         \
-})
-
-/* ------------------------------------------------------------------------ */
-#if 0
-static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       /* power control depends on which adapter is being woken:
-        * save this for init, instead, via mxl111sf_adap_fe_init */
-       return 0;
-}
-#endif
-
-static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
-{
-       struct dvb_usb_device *d = fe_to_d(fe);
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int err;
-
-       /* exit if we didnt initialize the driver yet */
-       if (!state->chip_id) {
-               mxl_debug("driver not yet initialized, exit.");
-               goto fail;
-       }
-
-       deb_info("%s()\n", __func__);
-
-       mutex_lock(&state->fe_lock);
-
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       err = mxl1x1sf_soft_reset(state);
-       mxl_fail(err);
-       err = mxl111sf_init_tuner_demod(state);
-       mxl_fail(err);
-       err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-
-       mxl_fail(err);
-       mxl111sf_enable_usb_output(state);
-       mxl_fail(err);
-       mxl1x1sf_top_master_ctrl(state, 1);
-       mxl_fail(err);
-
-       if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
-           (state->chip_rev > MXL111SF_V6)) {
-               mxl111sf_config_pin_mux_modes(state,
-                                             PIN_MUX_TS_SPI_IN_MODE_1);
-               mxl_fail(err);
-       }
-       err = mxl111sf_init_port_expander(state);
-       if (!mxl_fail(err)) {
-               state->gpio_mode = adap_state->gpio_mode;
-               err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-               mxl_fail(err);
-#if 0
-               err = fe->ops.init(fe);
-#endif
-               msleep(100); /* add short delay after enabling
-                             * the demod before touching it */
-       }
-
-       return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
-fail:
-       return -ENODEV;
-}
-
-static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int err;
-
-       /* exit if we didnt initialize the driver yet */
-       if (!state->chip_id) {
-               mxl_debug("driver not yet initialized, exit.");
-               goto fail;
-       }
-
-       deb_info("%s()\n", __func__);
-
-       err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
-
-       mutex_unlock(&state->fe_lock);
-
-       return err;
-fail:
-       return -ENODEV;
-}
-
-
-static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-               ret = mxl111sf_config_mpeg_in(state, 1, 1,
-                                             adap_state->ep6_clockphase,
-                                             0, 0);
-               mxl_fail(ret);
-#if 0
-       } else {
-               ret = mxl111sf_disable_656_port(state);
-               mxl_fail(ret);
-#endif
-       }
-
-       return ret;
-}
-
-static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-
-               ret = mxl111sf_init_i2s_port(state, 200);
-               mxl_fail(ret);
-               ret = mxl111sf_config_i2s(state, 0, 15);
-               mxl_fail(ret);
-       } else {
-               ret = mxl111sf_disable_i2s_port(state);
-               mxl_fail(ret);
-       }
-       if (state->chip_rev > MXL111SF_V6)
-               ret = mxl111sf_config_spi(state, onoff);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-       }
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct lgdt3305_config hauppauge_lgdt3305_config = {
-       .i2c_addr           = 0xb2 >> 1,
-       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
-       .tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
-       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .qam_if_khz         = 6000,
-       .vsb_if_khz         = 6000,
-};
-
-static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
-                                &hauppauge_lgdt3305_config,
-                                &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2160_config = {
-       .lg_chip            = LG2160,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-};
-
-static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             &hauppauge_lg2160_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_config = {
-       .lg_chip            = LG2161_1019,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 2, /* LG2161_OIF_SPI_MAS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_config = {
-       .lg_chip            = LG2161_1040,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 4, /* LG2161_OIF_SPI_MAS */
-};
-
-static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             (MXL111SF_V8_200 == state->chip_rev) ?
-                             &hauppauge_lg2161_1040_config :
-                             &hauppauge_lg2161_1019_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
-       .lg_chip            = LG2161_1019,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 1, /* LG2161_OIF_SERIAL_TS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
-       .lg_chip            = LG2161_1040,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 7, /* LG2161_OIF_SERIAL_TS */
-};
-
-static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 0;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             (MXL111SF_V8_200 == state->chip_rev) ?
-                             &hauppauge_lg2161_1040_ep6_config :
-                             &hauppauge_lg2161_1019_ep6_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct mxl111sf_demod_config mxl_demod_config = {
-       .read_reg        = mxl111sf_read_reg,
-       .write_reg       = mxl111sf_write_reg,
-       .program_regs    = mxl111sf_ctrl_program_regs,
-};
-
-static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_SOC_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* dont care if this fails */
-       mxl111sf_init_port_expander(state);
-
-       adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
-                             &mxl_demod_config);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
-                                       int antpath)
-{
-       return mxl111sf_idac_config(state, 1, 1,
-                                   (antpath == ANT_PATH_INTERNAL) ?
-                                   0x3f : 0x00, 0);
-}
-
-#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
-       err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
-           __func__, __LINE__, \
-           (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
-           pwr0, pwr1, pwr2, pwr3)
-
-#define ANT_HUNT_SLEEP 90
-#define ANT_EXT_TWEAK 0
-
-static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int antctrl = dvb_usb_mxl111sf_rfswitch;
-
-       u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
-
-       /* FIXME: must force EXTERNAL for QAM - done elsewhere */
-       mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
-                             ANT_PATH_EXTERNAL : antctrl);
-
-       if (antctrl == ANT_PATH_AUTO) {
-#if 0
-               msleep(ANT_HUNT_SLEEP);
-#endif
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
-
-               if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
-                       /* return with EXTERNAL enabled */
-                       mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-                       DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
-                                  rxPwr0, rxPwr1, rxPwr2);
-               } else {
-                       /* return with INTERNAL enabled */
-                       DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
-                                  rxPwr0, rxPwr1, rxPwr2);
-               }
-       }
-       return 0;
-}
-
-static struct mxl111sf_tuner_config mxl_tuner_config = {
-       .if_freq         = MXL_IF_6_0, /* applies to external IF output, only */
-       .invert_spectrum = 0,
-       .read_reg        = mxl111sf_read_reg,
-       .write_reg       = mxl111sf_write_reg,
-       .program_regs    = mxl111sf_ctrl_program_regs,
-       .top_master_ctrl = mxl1x1sf_top_master_ctrl,
-       .ant_hunt        = mxl111sf_ant_hunt,
-};
-
-static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
-{
-       struct mxl111sf_state *state = adap_to_priv(adap);
-       int i;
-
-       deb_adv("%s()\n", __func__);
-
-       for (i = 0; i < state->num_frontends; i++) {
-               if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
-                               &mxl_tuner_config) == NULL)
-                       return -EIO;
-               adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;
-       }
-
-       return 0;
-}
-
-static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-struct i2c_algorithm mxl111sf_i2c_algo = {
-       .master_xfer   = mxl111sf_i2c_xfer,
-       .functionality = mxl111sf_i2c_func,
-#ifdef NEED_ALGO_CONTROL
-       .algo_control = dummy_algo_control,
-#endif
-};
-
-static int mxl111sf_init(struct dvb_usb_device *d)
-{
-       struct mxl111sf_state *state = d_to_priv(d);
-       int ret;
-       static u8 eeprom[256];
-       struct i2c_client c;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               err("failed to get chip info during probe");
-
-       mutex_init(&state->fe_lock);
-
-       if (state->chip_rev > MXL111SF_V6)
-               mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
-
-       c.adapter = &d->i2c_adap;
-       c.addr = 0xa0 >> 1;
-
-       ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
-       if (mxl_fail(ret))
-               return 0;
-       tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
-                       eeprom + 0xa0 : eeprom + 0x80);
-#if 0
-       switch (state->tv.model) {
-       case 117001:
-       case 126001:
-       case 138001:
-               break;
-       default:
-               printk(KERN_WARNING "%s: warning: "
-                      "unknown hauppauge model #%d\n",
-                      __func__, state->tv.model);
-       }
-#endif
-       return 0;
-}
-
-static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_attach_demod(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_lgdt3305_frontend_attach(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_lg2160_frontend_attach(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_attach_demod(adap, 1);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_lg2160_frontend_attach(adap, 2);
-       if (ret < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_attach_demod(adap, 1);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
-       if (ret < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_attach_demod(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       if (dvb_usb_mxl111sf_spi)
-               ret = mxl111sf_lg2161_frontend_attach(adap, 1);
-       else
-               ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
-
-       return ret;
-}
-
-static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
-{
-       deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
-       stream->type = USB_BULK;
-       stream->count = 5;
-       stream->endpoint = endpoint;
-       stream->u.bulk.buffersize = 8192;
-}
-
-static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
-               u8 endpoint, int framesperurb, int framesize)
-{
-       deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
-                       framesperurb * framesize);
-       stream->type = USB_ISOC;
-       stream->count = 5;
-       stream->endpoint = endpoint;
-       stream->u.isoc.framesperurb = framesperurb;
-       stream->u.isoc.framesize = framesize;
-       stream->u.isoc.interval = 1;
-}
-
-/* DVB USB Driver stuff */
-
-/* dvbt       mxl111sf
- * bulk       EP4/BULK/5/8192
- * isoc       EP4/ISOC/5/96/564
- */
-static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_188;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-       else
-               mxl111sf_stream_config_bulk(stream, 4);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_dvbt,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep4_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_dvbt,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* atsc       lgdt3305
- * bulk       EP6/BULK/5/8192
- * isoc       EP6/ISOC/5/24/3072
- */
-static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_188;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-       else
-               mxl111sf_stream_config_bulk(stream, 6);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_atsc = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_atsc,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep6_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_atsc,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mh         lg2160
- * bulk       EP5/BULK/5/8192/RAW
- * isoc       EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-       else
-               mxl111sf_stream_config_bulk(stream, 5);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep5_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_mh,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* atsc mh    lgdt3305           mxl111sf          lg2160
- * bulk       EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * isoc       EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       } else if (fe->id == 1) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 2) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_atsc_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_atsc_mh,
-       .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mercury    lgdt3305           mxl111sf          lg2161
- * tp bulk    EP6/BULK/5/8192    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
- * tp isoc    EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
- * spi bulk   EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * spi isoc   EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       } else if (fe->id == 1) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mercury = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mercury,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury,
-       .get_stream_config = mxl111sf_get_stream_config_mercury,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mercury mh mxl111sf          lg2161
- * tp bulk    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
- * tp isoc    EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
- * spi bulk   EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * spi isoc   EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1  && dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mercury_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury_mh,
-       .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-static const struct usb_device_id mxl111sf_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
-
-static struct usb_driver mxl111sf_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = mxl111sf_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(mxl111sf_usb_driver);
-
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf.h
deleted file mode 100644 (file)
index 9816de8..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-
-#ifndef _DVB_USB_MXL111SF_H_
-#define _DVB_USB_MXL111SF_H_
-
-#ifdef DVB_USB_LOG_PREFIX
-#undef DVB_USB_LOG_PREFIX
-#endif
-#define DVB_USB_LOG_PREFIX "mxl111sf"
-#include "dvb_usb.h"
-#include <media/tveeprom.h>
-
-#define MXL_EP1_REG_READ     1
-#define MXL_EP2_REG_WRITE    2
-#define MXL_EP3_INTERRUPT    3
-#define MXL_EP4_MPEG2        4
-#define MXL_EP5_I2S          5
-#define MXL_EP6_656          6
-#define MXL_EP6_MPEG2        6
-
-#ifdef USING_ENUM_mxl111sf_current_mode
-enum mxl111sf_current_mode {
-       mxl_mode_dvbt = MXL_EP4_MPEG2,
-       mxl_mode_mh   = MXL_EP5_I2S,
-       mxl_mode_atsc = MXL_EP6_MPEG2,
-};
-#endif
-
-enum mxl111sf_gpio_port_expander {
-       mxl111sf_gpio_hw,
-       mxl111sf_PCA9534,
-};
-
-struct mxl111sf_adap_state {
-       int alt_mode;
-       int gpio_mode;
-       int device_mode;
-       int ep6_clockphase;
-       int (*fe_init)(struct dvb_frontend *);
-       int (*fe_sleep)(struct dvb_frontend *);
-};
-
-struct mxl111sf_state {
-       struct dvb_usb_device *d;
-
-       enum mxl111sf_gpio_port_expander gpio_port_expander;
-       u8 port_expander_addr;
-
-       u8 chip_id;
-       u8 chip_ver;
-#define MXL111SF_V6     1
-#define MXL111SF_V8_100 2
-#define MXL111SF_V8_200 3
-       u8 chip_rev;
-
-#ifdef USING_ENUM_mxl111sf_current_mode
-       enum mxl111sf_current_mode current_mode;
-#endif
-
-#define MXL_TUNER_MODE         0
-#define MXL_SOC_MODE           1
-#define MXL_DEV_MODE_MASK      0x01
-#if 1
-       int device_mode;
-#endif
-       /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t),
-                                    EP5 BULK transfer (atsc-mh),
-                                    EP6 BULK transfer (atsc/qam),
-          use usb alt setting 2 for EP4 BULK transfer (dvb-t),
-                                    EP5 ISOC transfer (atsc-mh),
-                                    EP6 ISOC transfer (atsc/qam),
-        */
-       int alt_mode;
-       int gpio_mode;
-       struct tveeprom tv;
-
-       struct mutex fe_lock;
-       u8 num_frontends;
-       struct mxl111sf_adap_state adap_state[3];
-};
-
-int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
-int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data);
-
-struct mxl111sf_reg_ctrl_info {
-       u8 addr;
-       u8 mask;
-       u8 data;
-};
-
-int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
-                           u8 addr, u8 mask, u8 data);
-int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-
-/* needed for hardware i2c functions in mxl111sf-i2c.c:
- * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
-                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
-
-#define mxl_printk(kern, fmt, arg...) \
-       printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define mxl_info(fmt, arg...) \
-       mxl_printk(KERN_INFO, fmt, ##arg)
-
-extern int dvb_usb_mxl111sf_debug;
-#define mxl_debug(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define MXL_I2C_DBG 0x04
-#define MXL_ADV_DBG 0x10
-#define mxl_debug_adv(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug & MXL_ADV_DBG) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define mxl_i2c(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug & MXL_I2C_DBG) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define mxl_i2c_adv(fmt, arg...) \
-       if ((dvb_usb_mxl111sf_debug & (MXL_I2C_DBG | MXL_ADV_DBG)) == \
-               (MXL_I2C_DBG | MXL_ADV_DBG)) \
-                       mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-/* The following allows the mxl_fail() macro defined below to work
- * in externel modules, such as mxl111sf-tuner.ko, even though
- * dvb_usb_mxl111sf_debug is not defined within those modules */
-#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
-#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
-#else
-#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
-#endif
-
-#define mxl_fail(ret)                                                  \
-({                                                                     \
-       int __ret;                                                      \
-       __ret = (ret < 0);                                              \
-       if ((__ret) && (MXL_ADV_DEBUG_ENABLED & MXL_ADV_DBG))           \
-               mxl_printk(KERN_ERR, "error %d on line %d",             \
-                          ret, __LINE__);                              \
-       __ret;                                                          \
-})
-
-#endif /* _DVB_USB_MXL111SF_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb-v2/rtl28xxu.c b/drivers/media/dvb/dvb-usb-v2/rtl28xxu.c
deleted file mode 100644 (file)
index a2d1e5b..0000000
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * Realtek RTL28xxU DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Thomas Mair <thomas.mair86@googlemail.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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "rtl28xxu.h"
-
-#include "rtl2830.h"
-#include "rtl2832.h"
-
-#include "qt1010.h"
-#include "mt2060.h"
-#include "mxl5005s.h"
-#include "fc0012.h"
-#include "fc0013.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
-{
-       int ret;
-       unsigned int pipe;
-       u8 requesttype;
-       u8 *buf;
-
-       buf = kmalloc(req->size, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       if (req->index & CMD_WR_FLAG) {
-               /* write */
-               memcpy(buf, req->data, req->size);
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {
-               /* read */
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
-                       req->index, buf, req->size, 1000);
-       if (ret > 0)
-               ret = 0;
-
-       deb_dump(0, requesttype, req->value, req->index, buf, req->size);
-
-       /* read request, copy returned data to return buf */
-       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
-               memcpy(req->data, buf, req->size);
-
-       kfree(buf);
-
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
-{
-       struct rtl28xxu_req req;
-
-       if (reg < 0x3000)
-               req.index = CMD_USB_WR;
-       else if (reg < 0x4000)
-               req.index = CMD_SYS_WR;
-       else
-               req.index = CMD_IR_WR;
-
-       req.value = reg;
-       req.size = len;
-       req.data = val;
-
-       return rtl28xxu_ctrl_msg(d, &req);
-}
-
-static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
-{
-       struct rtl28xxu_req req;
-
-       if (reg < 0x3000)
-               req.index = CMD_USB_RD;
-       else if (reg < 0x4000)
-               req.index = CMD_SYS_RD;
-       else
-               req.index = CMD_IR_RD;
-
-       req.value = reg;
-       req.size = len;
-       req.data = val;
-
-       return rtl28xxu_ctrl_msg(d, &req);
-}
-
-static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
-{
-       return rtl28xx_wr_regs(d, reg, &val, 1);
-}
-
-static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
-{
-       return rtl2831_rd_regs(d, reg, val, 1);
-}
-
-/* I2C */
-static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-       int num)
-{
-       int ret;
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct rtl28xxu_priv *priv = d->priv;
-       struct rtl28xxu_req req;
-
-       /*
-        * It is not known which are real I2C bus xfer limits, but testing
-        * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes.
-        * TODO: find out RTL2832U lens
-        */
-
-       /*
-        * I2C adapter logic looks rather complicated due to fact it handles
-        * three different access methods. Those methods are;
-        * 1) integrated demod access
-        * 2) old I2C access
-        * 3) new I2C access
-        *
-        * Used method is selected in order 1, 2, 3. Method 3 can handle all
-        * requests but there is two reasons why not use it always;
-        * 1) It is most expensive, usually two USB messages are needed
-        * 2) At least RTL2831U does not support it
-        *
-        * Method 3 is needed in case of I2C write+read (typical register read)
-        * where write is more than one byte.
-        */
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
-               (msg[1].flags & I2C_M_RD)) {
-               if (msg[0].len > 24 || msg[1].len > 24) {
-                       /* TODO: check msg[0].len max */
-                       ret = -EOPNOTSUPP;
-                       goto err_mutex_unlock;
-               } else if (msg[0].addr == 0x10) {
-                       /* method 1 - integrated demod */
-                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
-                       req.index = CMD_DEMOD_RD | priv->page;
-                       req.size = msg[1].len;
-                       req.data = &msg[1].buf[0];
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-               } else if (msg[0].len < 2) {
-                       /* method 2 - old I2C */
-                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
-                       req.index = CMD_I2C_RD;
-                       req.size = msg[1].len;
-                       req.data = &msg[1].buf[0];
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-               } else {
-                       /* method 3 - new I2C */
-                       req.value = (msg[0].addr << 1);
-                       req.index = CMD_I2C_DA_WR;
-                       req.size = msg[0].len;
-                       req.data = msg[0].buf;
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-                       if (ret)
-                               goto err_mutex_unlock;
-
-                       req.value = (msg[0].addr << 1);
-                       req.index = CMD_I2C_DA_RD;
-                       req.size = msg[1].len;
-                       req.data = msg[1].buf;
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-               }
-       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
-               if (msg[0].len > 22) {
-                       /* TODO: check msg[0].len max */
-                       ret = -EOPNOTSUPP;
-                       goto err_mutex_unlock;
-               } else if (msg[0].addr == 0x10) {
-                       /* method 1 - integrated demod */
-                       if (msg[0].buf[0] == 0x00) {
-                               /* save demod page for later demod access */
-                               priv->page = msg[0].buf[1];
-                               ret = 0;
-                       } else {
-                               req.value = (msg[0].buf[0] << 8) |
-                                       (msg[0].addr << 1);
-                               req.index = CMD_DEMOD_WR | priv->page;
-                               req.size = msg[0].len-1;
-                               req.data = &msg[0].buf[1];
-                               ret = rtl28xxu_ctrl_msg(d, &req);
-                       }
-               } else if (msg[0].len < 23) {
-                       /* method 2 - old I2C */
-                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
-                       req.index = CMD_I2C_WR;
-                       req.size = msg[0].len-1;
-                       req.data = &msg[0].buf[1];
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-               } else {
-                       /* method 3 - new I2C */
-                       req.value = (msg[0].addr << 1);
-                       req.index = CMD_I2C_DA_WR;
-                       req.size = msg[0].len;
-                       req.data = msg[0].buf;
-                       ret = rtl28xxu_ctrl_msg(d, &req);
-               }
-       } else {
-               ret = -EINVAL;
-       }
-
-err_mutex_unlock:
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret ? ret : num;
-}
-
-static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm rtl28xxu_i2c_algo = {
-       .master_xfer   = rtl28xxu_i2c_xfer,
-       .functionality = rtl28xxu_i2c_func,
-};
-
-static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .ts_mode = 0,
-       .spec_inv = 1,
-       .if_dvbt = 36150000,
-       .vtop = 0x20,
-       .krf = 0x04,
-       .agc_targ_val = 0x2d,
-
-};
-
-static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .ts_mode = 0,
-       .spec_inv = 1,
-       .if_dvbt = 36125000,
-       .vtop = 0x20,
-       .krf = 0x04,
-       .agc_targ_val = 0x2d,
-};
-
-static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .ts_mode = 0,
-       .spec_inv = 0,
-       .if_dvbt = 4570000,
-       .vtop = 0x3f,
-       .krf = 0x04,
-       .agc_targ_val = 0x3e,
-};
-
-static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct rtl28xxu_priv *priv = d_to_priv(d);
-       u8 buf[1];
-       struct rtl2830_config *rtl2830_config;
-       /* open RTL2831U/RTL2830 I2C gate */
-       struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
-       /* for MT2060 tuner probe */
-       struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
-       /* for QT1010 tuner probe */
-       struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
-
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /*
-        * RTL2831U GPIOs
-        * =========================================================
-        * GPIO0 | tuner#0 | 0 off | 1 on  | MXL5005S (?)
-        * GPIO2 | LED     | 0 off | 1 on  |
-        * GPIO4 | tuner#1 | 0 on  | 1 off | MT2060
-        */
-
-       /* GPIO direction */
-       ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, 0x0a);
-       if (ret)
-               goto err;
-
-       /* enable as output GPIO0, GPIO2, GPIO4 */
-       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, 0x15);
-       if (ret)
-               goto err;
-
-       /*
-        * Probe used tuner. We need to know used tuner before demod attach
-        * since there is some demod params needed to set according to tuner.
-        */
-
-       /* demod needs some time to wake up */
-       msleep(20);
-
-       /* open demod I2C gate */
-       ret = rtl28xxu_ctrl_msg(d, &req_gate);
-       if (ret)
-               goto err;
-
-       /* check QT1010 ID(?) register; reg=0f val=2c */
-       ret = rtl28xxu_ctrl_msg(d, &req_qt1010);
-       if (ret == 0 && buf[0] == 0x2c) {
-               priv->tuner = TUNER_RTL2830_QT1010;
-               rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
-               dev_dbg(&d->udev->dev, "%s: QT1010\n", __func__);
-               goto found;
-       } else {
-               dev_dbg(&d->udev->dev, "%s: QT1010 probe failed=%d - %02x\n",
-                               __func__, ret, buf[0]);
-       }
-
-       /* open demod I2C gate */
-       ret = rtl28xxu_ctrl_msg(d, &req_gate);
-       if (ret)
-               goto err;
-
-       /* check MT2060 ID register; reg=00 val=63 */
-       ret = rtl28xxu_ctrl_msg(d, &req_mt2060);
-       if (ret == 0 && buf[0] == 0x63) {
-               priv->tuner = TUNER_RTL2830_MT2060;
-               rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
-               dev_dbg(&d->udev->dev, "%s: MT2060\n", __func__);
-               goto found;
-       } else {
-               dev_dbg(&d->udev->dev, "%s: MT2060 probe failed=%d - %02x\n",
-                               __func__, ret, buf[0]);
-       }
-
-       /* assume MXL5005S */
-       ret = 0;
-       priv->tuner = TUNER_RTL2830_MXL5005S;
-       rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
-       dev_dbg(&d->udev->dev, "%s: MXL5005S\n", __func__);
-       goto found;
-
-found:
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(rtl2830_attach, rtl2830_config,
-               &d->i2c_adap);
-       if (adap->fe[0] == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .if_dvbt = 0,
-       .tuner = TUNER_RTL2832_FC0012
-};
-
-static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
-       .i2c_addr = 0x10, /* 0x20 */
-       .xtal = 28800000,
-       .if_dvbt = 0,
-       .tuner = TUNER_RTL2832_FC0013
-};
-
-static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
-               int cmd, int arg)
-{
-       int ret;
-       u8 val;
-
-       dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
-
-       switch (cmd) {
-       case FC_FE_CALLBACK_VHF_ENABLE:
-               /* set output values */
-               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-               if (ret)
-                       goto err;
-
-               if (arg)
-                       val &= 0xbf; /* set GPIO6 low */
-               else
-                       val |= 0x40; /* set GPIO6 high */
-
-
-               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
-               if (ret)
-                       goto err;
-               break;
-       default:
-               ret = -EINVAL;
-               goto err;
-       }
-       return 0;
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-
-static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d,
-               int cmd, int arg)
-{
-       /* TODO implement*/
-       return 0;
-}
-
-static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
-{
-       struct rtl28xxu_priv *priv = d->priv;
-
-       switch (priv->tuner) {
-       case TUNER_RTL2832_FC0012:
-               return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
-
-       case TUNER_RTL2832_FC0013:
-               return rtl2832u_fc0013_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -ENODEV;
-}
-
-static int rtl2832u_frontend_callback(void *adapter_priv, int component,
-                                   int cmd, int arg)
-{
-       struct i2c_adapter *adap = adapter_priv;
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
-       switch (component) {
-       case DVB_FRONTEND_COMPONENT_TUNER:
-               return rtl2832u_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct rtl2832_config *rtl2832_config;
-       u8 buf[2], val;
-       /* open RTL2832U/RTL2832 I2C gate */
-       struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
-       /* close RTL2832U/RTL2832 I2C gate */
-       struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
-       /* for FC0012 tuner probe */
-       struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf};
-       /* for FC0013 tuner probe */
-       struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf};
-       /* for MT2266 tuner probe */
-       struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf};
-       /* for FC2580 tuner probe */
-       struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
-       /* for MT2063 tuner probe */
-       struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf};
-       /* for MAX3543 tuner probe */
-       struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf};
-       /* for TUA9001 tuner probe */
-       struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf};
-       /* for MXL5007T tuner probe */
-       struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
-       /* for E4000 tuner probe */
-       struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
-       /* for TDA18272 tuner probe */
-       struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
-
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val);
-       if (ret)
-               goto err;
-
-       val &= 0xbf;
-
-       ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val);
-       if (ret)
-               goto err;
-
-       /* enable as output GPIO3 and GPIO6*/
-       ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val);
-       if (ret)
-               goto err;
-
-       val |= 0x48;
-
-       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val);
-       if (ret)
-               goto err;
-
-       /*
-        * Probe used tuner. We need to know used tuner before demod attach
-        * since there is some demod params needed to set according to tuner.
-        */
-
-       /* open demod I2C gate */
-       ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
-       if (ret)
-               goto err;
-
-       priv->tuner = TUNER_NONE;
-
-       /* check FC0012 ID register; reg=00 val=a1 */
-       ret = rtl28xxu_ctrl_msg(d, &req_fc0012);
-       if (ret == 0 && buf[0] == 0xa1) {
-               priv->tuner = TUNER_RTL2832_FC0012;
-               rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
-               dev_info(&d->udev->dev, "%s: FC0012 tuner found",
-                               KBUILD_MODNAME);
-               goto found;
-       }
-
-       /* check FC0013 ID register; reg=00 val=a3 */
-       ret = rtl28xxu_ctrl_msg(d, &req_fc0013);
-       if (ret == 0 && buf[0] == 0xa3) {
-               priv->tuner = TUNER_RTL2832_FC0013;
-               rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
-               dev_info(&d->udev->dev, "%s: FC0013 tuner found",
-                               KBUILD_MODNAME);
-               goto found;
-       }
-
-       /* check MT2266 ID register; reg=00 val=85 */
-       ret = rtl28xxu_ctrl_msg(d, &req_mt2266);
-       if (ret == 0 && buf[0] == 0x85) {
-               priv->tuner = TUNER_RTL2832_MT2266;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: MT2266 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check FC2580 ID register; reg=01 val=56 */
-       ret = rtl28xxu_ctrl_msg(d, &req_fc2580);
-       if (ret == 0 && buf[0] == 0x56) {
-               priv->tuner = TUNER_RTL2832_FC2580;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: FC2580 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check MT2063 ID register; reg=00 val=9e || 9c */
-       ret = rtl28xxu_ctrl_msg(d, &req_mt2063);
-       if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
-               priv->tuner = TUNER_RTL2832_MT2063;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: MT2063 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check MAX3543 ID register; reg=00 val=38 */
-       ret = rtl28xxu_ctrl_msg(d, &req_max3543);
-       if (ret == 0 && buf[0] == 0x38) {
-               priv->tuner = TUNER_RTL2832_MAX3543;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: MAX3534 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check TUA9001 ID register; reg=7e val=2328 */
-       ret = rtl28xxu_ctrl_msg(d, &req_tua9001);
-       if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
-               priv->tuner = TUNER_RTL2832_TUA9001;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: TUA9001 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check MXL5007R ID register; reg=d9 val=14 */
-       ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t);
-       if (ret == 0 && buf[0] == 0x14) {
-               priv->tuner = TUNER_RTL2832_MXL5007T;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: MXL5007T tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check E4000 ID register; reg=02 val=40 */
-       ret = rtl28xxu_ctrl_msg(d, &req_e4000);
-       if (ret == 0 && buf[0] == 0x40) {
-               priv->tuner = TUNER_RTL2832_E4000;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: E4000 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-       /* check TDA18272 ID register; reg=00 val=c760  */
-       ret = rtl28xxu_ctrl_msg(d, &req_tda18272);
-       if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
-               priv->tuner = TUNER_RTL2832_TDA18272;
-               /* TODO implement tuner */
-               dev_info(&d->udev->dev, "%s: TDA18272 tuner found",
-                               KBUILD_MODNAME);
-               goto unsupported;
-       }
-
-unsupported:
-       /* close demod I2C gate */
-       ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
-       if (ret)
-               goto err;
-
-       /* tuner not found */
-       dev_dbg(&d->udev->dev, "%s: No compatible tuner found\n", __func__);
-       ret = -ENODEV;
-       return ret;
-
-found:
-       /* close demod I2C gate */
-       ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
-       if (ret)
-               goto err;
-
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config,
-               &d->i2c_adap);
-               if (adap->fe[0] == NULL) {
-                       ret = -ENODEV;
-                       goto err;
-               }
-
-       /* set fe callbacks */
-       adap->fe[0]->callback = rtl2832u_frontend_callback;
-
-       return ret;
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static struct qt1010_config rtl28xxu_qt1010_config = {
-       .i2c_address = 0x62, /* 0xc4 */
-};
-
-static struct mt2060_config rtl28xxu_mt2060_config = {
-       .i2c_address = 0x60, /* 0xc0 */
-       .clock_out = 0,
-};
-
-static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
-       .i2c_address     = 0x63, /* 0xc6 */
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_C_H,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct i2c_adapter *rtl2830_tuner_i2c;
-       struct dvb_frontend *fe;
-
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
-       rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe[0]);
-
-       switch (priv->tuner) {
-       case TUNER_RTL2830_QT1010:
-               fe = dvb_attach(qt1010_attach, adap->fe[0],
-                               rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
-               break;
-       case TUNER_RTL2830_MT2060:
-               fe = dvb_attach(mt2060_attach, adap->fe[0],
-                               rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
-                               1220);
-               break;
-       case TUNER_RTL2830_MXL5005S:
-               fe = dvb_attach(mxl5005s_attach, adap->fe[0],
-                               rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
-               break;
-       default:
-               fe = NULL;
-               dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
-                               priv->tuner);
-       }
-
-       if (fe == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct dvb_frontend *fe;
-
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       switch (priv->tuner) {
-       case TUNER_RTL2832_FC0012:
-               fe = dvb_attach(fc0012_attach, adap->fe[0],
-                       &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
-
-               /* since fc0012 includs reading the signal strength delegate
-                * that to the tuner driver */
-               adap->fe[0]->ops.read_signal_strength =
-                               adap->fe[0]->ops.tuner_ops.get_rf_strength;
-               return 0;
-               break;
-       case TUNER_RTL2832_FC0013:
-               fe = dvb_attach(fc0013_attach, adap->fe[0],
-                       &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
-
-               /* fc0013 also supports signal strength reading */
-               adap->fe[0]->ops.read_signal_strength =
-                               adap->fe[0]->ops.tuner_ops.get_rf_strength;
-               return 0;
-       default:
-               fe = NULL;
-               dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
-                               priv->tuner);
-       }
-
-       if (fe == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl28xxu_init(struct dvb_usb_device *d)
-{
-       int ret;
-       u8 val;
-
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* init USB endpoints */
-       ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
-       if (ret)
-               goto err;
-
-       /* enable DMA and Full Packet Mode*/
-       val |= 0x09;
-       ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
-       if (ret)
-               goto err;
-
-       /* set EPA maximum packet size to 0x0200 */
-       ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
-       if (ret)
-               goto err;
-
-       /* change EPA FIFO length */
-       ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl28xxu_streaming_ctrl(struct dvb_frontend *fe , int onoff)
-{
-       int ret;
-       u8 buf[2];
-       struct dvb_usb_device *d = fe_to_d(fe);
-
-       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
-
-       if (onoff) {
-               buf[0] = 0x00;
-               buf[1] = 0x00;
-       } else {
-               buf[0] = 0x10; /* stall EPA */
-               buf[1] = 0x02; /* reset EPA */
-       }
-
-       ret = rtl28xx_wr_regs(d, USB_EPA_CTL, buf, 2);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-       u8 gpio, sys0;
-
-       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
-
-       /* demod adc */
-       ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0);
-       if (ret)
-               goto err;
-
-       /* tuner power, read GPIOs */
-       ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
-       if (ret)
-               goto err;
-
-       dev_dbg(&d->udev->dev, "%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
-                       sys0, gpio);
-
-       if (onoff) {
-               gpio |= 0x01; /* GPIO0 = 1 */
-               gpio &= (~0x10); /* GPIO4 = 0 */
-               gpio |= 0x04; /* GPIO2 = 1, LED on */
-               sys0 = sys0 & 0x0f;
-               sys0 |= 0xe0;
-       } else {
-               gpio &= (~0x01); /* GPIO0 = 0 */
-               gpio |= 0x10; /* GPIO4 = 1 */
-               gpio &= (~0x04); /* GPIO2 = 1, LED off */
-               sys0 = sys0 & (~0xc0);
-       }
-
-       dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
-                       sys0, gpio);
-
-       /* demod adc */
-       ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0);
-       if (ret)
-               goto err;
-
-       /* tuner power, write GPIOs */
-       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-       u8 val;
-
-       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
-
-       if (onoff) {
-               /* set output values */
-               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-               if (ret)
-                       goto err;
-
-               val |= 0x08;
-               val &= 0xef;
-
-               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
-               if (ret)
-                       goto err;
-
-               /* demod_ctl_1 */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
-               if (ret)
-                       goto err;
-
-               val &= 0xef;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
-               if (ret)
-                       goto err;
-
-               /* demod control */
-               /* PLL enable */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-               if (ret)
-                       goto err;
-
-               /* bit 7 to 1 */
-               val |= 0x80;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-               if (ret)
-                       goto err;
-
-               /* demod HW reset */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-               if (ret)
-                       goto err;
-               /* bit 5 to 0 */
-               val &= 0xdf;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-               if (ret)
-                       goto err;
-
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-               if (ret)
-                       goto err;
-
-               val |= 0x20;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-               if (ret)
-                       goto err;
-
-               mdelay(5);
-
-               /*enable ADC_Q and ADC_I */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-               if (ret)
-                       goto err;
-
-               val |= 0x48;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-               if (ret)
-                       goto err;
-
-
-       } else {
-               /* demod_ctl_1 */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
-               if (ret)
-                       goto err;
-
-               val |= 0x0c;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
-               if (ret)
-                       goto err;
-
-               /* set output values */
-               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-               if (ret)
-                               goto err;
-
-               val |= 0x10;
-
-               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
-               if (ret)
-                       goto err;
-
-               /* demod control */
-               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-               if (ret)
-                       goto err;
-
-               val &= 0x37;
-
-               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-               if (ret)
-                       goto err;
-
-       }
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-
-static int rtl2831u_rc_query(struct dvb_usb_device *d)
-{
-       int ret, i;
-       struct rtl28xxu_priv *priv = d->priv;
-       u8 buf[5];
-       u32 rc_code;
-       struct rtl28xxu_reg_val rc_nec_tab[] = {
-               { 0x3033, 0x80 },
-               { 0x3020, 0x43 },
-               { 0x3021, 0x16 },
-               { 0x3022, 0x16 },
-               { 0x3023, 0x5a },
-               { 0x3024, 0x2d },
-               { 0x3025, 0x16 },
-               { 0x3026, 0x01 },
-               { 0x3028, 0xb0 },
-               { 0x3029, 0x04 },
-               { 0x302c, 0x88 },
-               { 0x302e, 0x13 },
-               { 0x3030, 0xdf },
-               { 0x3031, 0x05 },
-       };
-
-       /* init remote controller */
-       if (!priv->rc_active) {
-               for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
-                       ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
-                                       rc_nec_tab[i].val);
-                       if (ret)
-                               goto err;
-               }
-               priv->rc_active = true;
-       }
-
-       ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5);
-       if (ret)
-               goto err;
-
-       if (buf[4] & 0x01) {
-               if (buf[2] == (u8) ~buf[3]) {
-                       if (buf[0] == (u8) ~buf[1]) {
-                               /* NEC standard (16 bit) */
-                               rc_code = buf[0] << 8 | buf[2];
-                       } else {
-                               /* NEC extended (24 bit) */
-                               rc_code = buf[0] << 16 |
-                                               buf[1] << 8 | buf[2];
-                       }
-               } else {
-                       /* NEC full (32 bit) */
-                       rc_code = buf[0] << 24 | buf[1] << 16 |
-                                       buf[2] << 8 | buf[3];
-               }
-
-               rc_keydown(d->rc_dev, rc_code, 0);
-
-               ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
-               if (ret)
-                       goto err;
-
-               /* repeated intentionally to avoid extra keypress */
-               ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
-               if (ret)
-                       goto err;
-       }
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
-               struct dvb_usb_rc *rc)
-{
-       rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query = rtl2831u_rc_query;
-       rc->interval = 400;
-
-       return 0;
-}
-
-static int rtl2832u_rc_query(struct dvb_usb_device *d)
-{
-       int ret, i;
-       struct rtl28xxu_priv *priv = d->priv;
-       u8 buf[128];
-       int len;
-       struct rtl28xxu_reg_val rc_nec_tab[] = {
-               { IR_RX_CTRL,             0x20 },
-               { IR_RX_BUF_CTRL,         0x80 },
-               { IR_RX_IF,               0xff },
-               { IR_RX_IE,               0xff },
-               { IR_MAX_DURATION0,       0xd0 },
-               { IR_MAX_DURATION1,       0x07 },
-               { IR_IDLE_LEN0,           0xc0 },
-               { IR_IDLE_LEN1,           0x00 },
-               { IR_GLITCH_LEN,          0x03 },
-               { IR_RX_CLK,              0x09 },
-               { IR_RX_CFG,              0x1c },
-               { IR_MAX_H_TOL_LEN,       0x1e },
-               { IR_MAX_L_TOL_LEN,       0x1e },
-               { IR_RX_CTRL,             0x80 },
-       };
-
-       /* init remote controller */
-       if (!priv->rc_active) {
-               for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
-                       ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
-                                       rc_nec_tab[i].val);
-                       if (ret)
-                               goto err;
-               }
-               priv->rc_active = true;
-       }
-
-       ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]);
-       if (ret)
-               goto err;
-
-       if (buf[0] != 0x83)
-               goto exit;
-
-       ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
-       if (ret)
-               goto err;
-
-       len = buf[0];
-       ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
-
-       /* TODO: pass raw IR to Kernel IR decoder */
-
-       ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
-       ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
-       ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
-
-exit:
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
-               struct dvb_usb_rc *rc)
-{
-       rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query = rtl2832u_rc_query;
-       rc->interval = 400;
-
-       return 0;
-}
-
-static const struct dvb_usb_device_properties rtl2831u_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct rtl28xxu_priv),
-
-       .power_ctrl = rtl2831u_power_ctrl,
-       .i2c_algo = &rtl28xxu_i2c_algo,
-       .frontend_attach = rtl2831u_frontend_attach,
-       .tuner_attach = rtl2831u_tuner_attach,
-       .init = rtl28xxu_init,
-       .get_rc_config = rtl2831u_get_rc_config,
-       .streaming_ctrl = rtl28xxu_streaming_ctrl,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
-               },
-       },
-};
-
-static const struct dvb_usb_device_properties rtl2832u_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct rtl28xxu_priv),
-
-       .power_ctrl = rtl2832u_power_ctrl,
-       .i2c_algo = &rtl28xxu_i2c_algo,
-       .frontend_attach = rtl2832u_frontend_attach,
-       .tuner_attach = rtl2832u_tuner_attach,
-       .init = rtl28xxu_init,
-       .get_rc_config = rtl2832u_get_rc_config,
-       .streaming_ctrl = rtl28xxu_streaming_ctrl,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
-               },
-       },
-};
-
-static const struct usb_device_id rtl28xxu_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U,
-               &rtl2831u_props, "Realtek RTL2831U reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT,
-               &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
-       { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2,
-               &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
-
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
-               &rtl2832u_props, "Terratec Cinergy T Stick Black", NULL) },
-       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
-               &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
-               &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
-
-static struct usb_driver rtl28xxu_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = rtl28xxu_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(rtl28xxu_usb_driver);
-
-MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_AUTHOR("Thomas Mair <thomas.mair86@googlemail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/rtl28xxu.h b/drivers/media/dvb/dvb-usb-v2/rtl28xxu.h
deleted file mode 100644 (file)
index 575edbf..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Realtek RTL28xxU DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef RTL28XXU_H
-#define RTL28XXU_H
-
-#include "dvb_usb.h"
-
-#define deb_dump(r, t, v, i, b, l) { \
-       char *direction; \
-       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
-               direction = ">>>"; \
-       else \
-               direction = "<<<"; \
-       dev_dbg(&d->udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
-                       "%s [%d bytes]\n",  __func__, t, r, v & 0xff, v >> 8, \
-                       i & 0xff, i >> 8, l & 0xff, l >> 8, direction, l); \
-}
-
-/*
- * USB commands
- * (usb_control_msg() index parameter)
- */
-
-#define DEMOD            0x0000
-#define USB              0x0100
-#define SYS              0x0200
-#define I2C              0x0300
-#define I2C_DA           0x0600
-
-#define CMD_WR_FLAG      0x0010
-#define CMD_DEMOD_RD     0x0000
-#define CMD_DEMOD_WR     0x0010
-#define CMD_USB_RD       0x0100
-#define CMD_USB_WR       0x0110
-#define CMD_SYS_RD       0x0200
-#define CMD_IR_RD        0x0201
-#define CMD_IR_WR        0x0211
-#define CMD_SYS_WR       0x0210
-#define CMD_I2C_RD       0x0300
-#define CMD_I2C_WR       0x0310
-#define CMD_I2C_DA_RD    0x0600
-#define CMD_I2C_DA_WR    0x0610
-
-
-struct rtl28xxu_priv {
-       u8 chip_id;
-       u8 tuner;
-       u8 page; /* integrated demod active register page */
-       bool rc_active;
-};
-
-enum rtl28xxu_chip_id {
-       CHIP_ID_NONE,
-       CHIP_ID_RTL2831U,
-       CHIP_ID_RTL2832U,
-};
-
-enum rtl28xxu_tuner {
-       TUNER_NONE,
-
-       TUNER_RTL2830_QT1010,
-       TUNER_RTL2830_MT2060,
-       TUNER_RTL2830_MXL5005S,
-
-       TUNER_RTL2832_MT2266,
-       TUNER_RTL2832_FC2580,
-       TUNER_RTL2832_MT2063,
-       TUNER_RTL2832_MAX3543,
-       TUNER_RTL2832_TUA9001,
-       TUNER_RTL2832_MXL5007T,
-       TUNER_RTL2832_FC0012,
-       TUNER_RTL2832_E4000,
-       TUNER_RTL2832_TDA18272,
-       TUNER_RTL2832_FC0013,
-};
-
-struct rtl28xxu_req {
-       u16 value;
-       u16 index;
-       u16 size;
-       u8 *data;
-};
-
-struct rtl28xxu_reg_val {
-       u16 reg;
-       u8 val;
-};
-
-/*
- * memory map
- *
- * 0x0000 DEMOD : demodulator
- * 0x2000 USB   : SIE, USB endpoint, debug, DMA
- * 0x3000 SYS   : system
- * 0xfc00 RC    : remote controller (not RTL2831U)
- */
-
-/*
- * USB registers
- */
-/* SIE Control Registers */
-#define USB_SYSCTL         0x2000 /* USB system control */
-#define USB_SYSCTL_0       0x2000 /* USB system control */
-#define USB_SYSCTL_1       0x2001 /* USB system control */
-#define USB_SYSCTL_2       0x2002 /* USB system control */
-#define USB_SYSCTL_3       0x2003 /* USB system control */
-#define USB_IRQSTAT        0x2008 /* SIE interrupt status */
-#define USB_IRQEN          0x200C /* SIE interrupt enable */
-#define USB_CTRL           0x2010 /* USB control */
-#define USB_STAT           0x2014 /* USB status */
-#define USB_DEVADDR        0x2018 /* USB device address */
-#define USB_TEST           0x201C /* USB test mode */
-#define USB_FRAME_NUMBER   0x2020 /* frame number */
-#define USB_FIFO_ADDR      0x2028 /* address of SIE FIFO RAM */
-#define USB_FIFO_CMD       0x202A /* SIE FIFO RAM access command */
-#define USB_FIFO_DATA      0x2030 /* SIE FIFO RAM data */
-/* Endpoint Registers */
-#define EP0_SETUPA         0x20F8 /* EP 0 setup packet lower byte */
-#define EP0_SETUPB         0x20FC /* EP 0 setup packet higher byte */
-#define USB_EP0_CFG        0x2104 /* EP 0 configure */
-#define USB_EP0_CTL        0x2108 /* EP 0 control */
-#define USB_EP0_STAT       0x210C /* EP 0 status */
-#define USB_EP0_IRQSTAT    0x2110 /* EP 0 interrupt status */
-#define USB_EP0_IRQEN      0x2114 /* EP 0 interrupt enable */
-#define USB_EP0_MAXPKT     0x2118 /* EP 0 max packet size */
-#define USB_EP0_BC         0x2120 /* EP 0 FIFO byte counter */
-#define USB_EPA_CFG        0x2144 /* EP A configure */
-#define USB_EPA_CFG_0      0x2144 /* EP A configure */
-#define USB_EPA_CFG_1      0x2145 /* EP A configure */
-#define USB_EPA_CFG_2      0x2146 /* EP A configure */
-#define USB_EPA_CFG_3      0x2147 /* EP A configure */
-#define USB_EPA_CTL        0x2148 /* EP A control */
-#define USB_EPA_CTL_0      0x2148 /* EP A control */
-#define USB_EPA_CTL_1      0x2149 /* EP A control */
-#define USB_EPA_CTL_2      0x214A /* EP A control */
-#define USB_EPA_CTL_3      0x214B /* EP A control */
-#define USB_EPA_STAT       0x214C /* EP A status */
-#define USB_EPA_IRQSTAT    0x2150 /* EP A interrupt status */
-#define USB_EPA_IRQEN      0x2154 /* EP A interrupt enable */
-#define USB_EPA_MAXPKT     0x2158 /* EP A max packet size */
-#define USB_EPA_MAXPKT_0   0x2158 /* EP A max packet size */
-#define USB_EPA_MAXPKT_1   0x2159 /* EP A max packet size */
-#define USB_EPA_MAXPKT_2   0x215A /* EP A max packet size */
-#define USB_EPA_MAXPKT_3   0x215B /* EP A max packet size */
-#define USB_EPA_FIFO_CFG   0x2160 /* EP A FIFO configure */
-#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */
-#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */
-#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */
-#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */
-/* Debug Registers */
-#define USB_PHYTSTDIS      0x2F04 /* PHY test disable */
-#define USB_TOUT_VAL       0x2F08 /* USB time-out time */
-#define USB_VDRCTRL        0x2F10 /* UTMI vendor signal control */
-#define USB_VSTAIN         0x2F14 /* UTMI vendor signal status in */
-#define USB_VLOADM         0x2F18 /* UTMI load vendor signal status in */
-#define USB_VSTAOUT        0x2F1C /* UTMI vendor signal status out */
-#define USB_UTMI_TST       0x2F80 /* UTMI test */
-#define USB_UTMI_STATUS    0x2F84 /* UTMI status */
-#define USB_TSTCTL         0x2F88 /* test control */
-#define USB_TSTCTL2        0x2F8C /* test control 2 */
-#define USB_PID_FORCE      0x2F90 /* force PID */
-#define USB_PKTERR_CNT     0x2F94 /* packet error counter */
-#define USB_RXERR_CNT      0x2F98 /* RX error counter */
-#define USB_MEM_BIST       0x2F9C /* MEM BIST test */
-#define USB_SLBBIST        0x2FA0 /* self-loop-back BIST */
-#define USB_CNTTEST        0x2FA4 /* counter test */
-#define USB_PHYTST         0x2FC0 /* USB PHY test */
-#define USB_DBGIDX         0x2FF0 /* select individual block debug signal */
-#define USB_DBGMUX         0x2FF4 /* debug signal module mux */
-
-/*
- * SYS registers
- */
-/* demod control registers */
-#define SYS_SYS0           0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */
-#define SYS_DEMOD_CTL      0x3000 /* control register for DVB-T demodulator */
-/* GPIO registers */
-#define SYS_GPIO_OUT_VAL   0x3001 /* output value of GPIO */
-#define SYS_GPIO_IN_VAL    0x3002 /* input value of GPIO */
-#define SYS_GPIO_OUT_EN    0x3003 /* output enable of GPIO */
-#define SYS_SYS1           0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */
-#define SYS_GPIO_DIR       0x3004 /* direction control for GPIO */
-#define SYS_SYSINTE        0x3005 /* system interrupt enable */
-#define SYS_SYSINTS        0x3006 /* system interrupt status */
-#define SYS_GPIO_CFG0      0x3007 /* PAD configuration for GPIO0-GPIO3 */
-#define SYS_SYS2           0x3008 /* include GP_CFG1 and 3 reserved bytes */
-#define SYS_GPIO_CFG1      0x3008 /* PAD configuration for GPIO4 */
-#define SYS_DEMOD_CTL1     0x300B
-
-/* IrDA registers */
-#define SYS_IRRC_PSR       0x3020 /* IR protocol selection */
-#define SYS_IRRC_PER       0x3024 /* IR protocol extension */
-#define SYS_IRRC_SF        0x3028 /* IR sampling frequency */
-#define SYS_IRRC_DPIR      0x302C /* IR data package interval */
-#define SYS_IRRC_CR        0x3030 /* IR control */
-#define SYS_IRRC_RP        0x3034 /* IR read port */
-#define SYS_IRRC_SR        0x3038 /* IR status */
-/* I2C master registers */
-#define SYS_I2CCR          0x3040 /* I2C clock */
-#define SYS_I2CMCR         0x3044 /* I2C master control */
-#define SYS_I2CMSTR        0x3048 /* I2C master SCL timing */
-#define SYS_I2CMSR         0x304C /* I2C master status */
-#define SYS_I2CMFR         0x3050 /* I2C master FIFO */
-
-/*
- * IR registers
- */
-#define IR_RX_BUF          0xFC00
-#define IR_RX_IE           0xFD00
-#define IR_RX_IF           0xFD01
-#define IR_RX_CTRL         0xFD02
-#define IR_RX_CFG          0xFD03
-#define IR_MAX_DURATION0   0xFD04
-#define IR_MAX_DURATION1   0xFD05
-#define IR_IDLE_LEN0       0xFD06
-#define IR_IDLE_LEN1       0xFD07
-#define IR_GLITCH_LEN      0xFD08
-#define IR_RX_BUF_CTRL     0xFD09
-#define IR_RX_BUF_DATA     0xFD0A
-#define IR_RX_BC           0xFD0B
-#define IR_RX_CLK          0xFD0C
-#define IR_RX_C_COUNT_L    0xFD0D
-#define IR_RX_C_COUNT_H    0xFD0E
-#define IR_SUSPEND_CTRL    0xFD10
-#define IR_ERR_TOL_CTRL    0xFD11
-#define IR_UNIT_LEN        0xFD12
-#define IR_ERR_TOL_LEN     0xFD13
-#define IR_MAX_H_TOL_LEN   0xFD14
-#define IR_MAX_L_TOL_LEN   0xFD15
-#define IR_MASK_CTRL       0xFD16
-#define IR_MASK_DATA       0xFD17
-#define IR_RES_MASK_ADDR   0xFD18
-#define IR_RES_MASK_T_LEN  0xFD19
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/usb_urb.c b/drivers/media/dvb/dvb-usb-v2/usb_urb.c
deleted file mode 100644 (file)
index eaf673a..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/* usb-urb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file keeps functions for initializing and handling the
- * BULK and ISOC USB data transfers in a generic way.
- * Can be used for DVB-only and also, that's the plan, for
- * Hybrid USB devices (analog and DVB).
- */
-#include "dvb_usb_common.h"
-
-/* URB stuff for streaming */
-
-int usb_urb_reconfig(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props);
-
-static void usb_urb_complete(struct urb *urb)
-{
-       struct usb_data_stream *stream = urb->context;
-       int ptype = usb_pipetype(urb->pipe);
-       int i;
-       u8 *b;
-
-       dev_dbg(&stream->udev->dev, "%s: %s urb completed status=%d " \
-                       "length=%d/%d pack_num=%d errors=%d\n", __func__,
-                       ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
-                       urb->status, urb->actual_length,
-                       urb->transfer_buffer_length,
-                       urb->number_of_packets, urb->error_count);
-
-       switch (urb->status) {
-       case 0:         /* success */
-       case -ETIMEDOUT:    /* NAK */
-               break;
-       case -ECONNRESET:   /* kill */
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       default:        /* error */
-               dev_dbg(&stream->udev->dev, "%s: urb completition failed=%d\n",
-                               __func__, urb->status);
-               break;
-       }
-
-       b = (u8 *) urb->transfer_buffer;
-       switch (ptype) {
-       case PIPE_ISOCHRONOUS:
-               for (i = 0; i < urb->number_of_packets; i++) {
-                       if (urb->iso_frame_desc[i].status != 0)
-                               dev_dbg(&stream->udev->dev, "%s: iso frame " \
-                                               "descriptor has an error=%d\n",
-                                               __func__,
-                                               urb->iso_frame_desc[i].status);
-                       else if (urb->iso_frame_desc[i].actual_length > 0)
-                               stream->complete(stream,
-                                       b + 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;
-               }
-               break;
-       case PIPE_BULK:
-               if (urb->actual_length > 0)
-                       stream->complete(stream, b, urb->actual_length);
-               break;
-       default:
-               dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
-                               "completition handler\n", KBUILD_MODNAME);
-               return;
-       }
-       usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-int usb_urb_killv2(struct usb_data_stream *stream)
-{
-       int i;
-       for (i = 0; i < stream->urbs_submitted; i++) {
-               dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
-               /* stop the URB */
-               usb_kill_urb(stream->urb_list[i]);
-       }
-       stream->urbs_submitted = 0;
-       return 0;
-}
-
-int usb_urb_submitv2(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props)
-{
-       int i, ret;
-
-       if (props) {
-               ret = usb_urb_reconfig(stream, props);
-               if (ret < 0)
-                       return ret;
-       }
-
-       for (i = 0; i < stream->urbs_initialized; i++) {
-               dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
-               ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
-               if (ret) {
-                       dev_err(&stream->udev->dev, "%s: could not submit " \
-                                       "urb no. %d - get them all back\n",
-                                       KBUILD_MODNAME, i);
-                       usb_urb_killv2(stream);
-                       return ret;
-               }
-               stream->urbs_submitted++;
-       }
-       return 0;
-}
-
-int usb_urb_free_urbs(struct usb_data_stream *stream)
-{
-       int i;
-
-       usb_urb_killv2(stream);
-
-       for (i = stream->urbs_initialized - 1; i >= 0; i--) {
-               if (stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
-                                       __func__, i);
-                       /* free the URBs */
-                       usb_free_urb(stream->urb_list[i]);
-               }
-       }
-       stream->urbs_initialized = 0;
-
-       return 0;
-}
-
-static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
-{
-       int i, j;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
-               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-               usb_fill_bulk_urb(stream->urb_list[i],
-                               stream->udev,
-                               usb_rcvbulkpipe(stream->udev,
-                                               stream->props.endpoint),
-                               stream->buf_list[i],
-                               stream->props.u.bulk.buffersize,
-                               usb_urb_complete, stream);
-
-               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
-{
-       int i, j;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               struct urb *urb;
-               int frame_offset = 0;
-               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
-               stream->urb_list[i] = usb_alloc_urb(
-                               stream->props.u.isoc.framesperurb, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-
-               urb = stream->urb_list[i];
-
-               urb->dev = stream->udev;
-               urb->context = stream;
-               urb->complete = usb_urb_complete;
-               urb->pipe = usb_rcvisocpipe(stream->udev,
-                               stream->props.endpoint);
-               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-               urb->interval = stream->props.u.isoc.interval;
-               urb->number_of_packets = stream->props.u.isoc.framesperurb;
-               urb->transfer_buffer_length = stream->props.u.isoc.framesize *
-                               stream->props.u.isoc.framesperurb;
-               urb->transfer_buffer = stream->buf_list[i];
-               urb->transfer_dma = stream->dma_addr[i];
-
-               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length =
-                                       stream->props.u.isoc.framesize;
-                       frame_offset += stream->props.u.isoc.framesize;
-               }
-
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-int usb_free_stream_buffers(struct usb_data_stream *stream)
-{
-       if (stream->state & USB_STATE_URB_BUF) {
-               while (stream->buf_num) {
-                       stream->buf_num--;
-                       dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
-                               __func__, stream->buf_num);
-                       usb_free_coherent(stream->udev, stream->buf_size,
-                                         stream->buf_list[stream->buf_num],
-                                         stream->dma_addr[stream->buf_num]);
-               }
-       }
-
-       stream->state &= ~USB_STATE_URB_BUF;
-
-       return 0;
-}
-
-int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
-               unsigned long size)
-{
-       stream->buf_num = 0;
-       stream->buf_size = size;
-
-       dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
-                       "streaming\n", __func__,  num * size);
-
-       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
-               stream->buf_list[stream->buf_num] = usb_alloc_coherent(
-                               stream->udev, size, GFP_ATOMIC,
-                               &stream->dma_addr[stream->buf_num]);
-               if (!stream->buf_list[stream->buf_num]) {
-                       dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
-                                       __func__, stream->buf_num);
-                       usb_free_stream_buffers(stream);
-                       return -ENOMEM;
-               }
-
-               dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
-                               __func__, stream->buf_num,
-                               stream->buf_list[stream->buf_num],
-                               (long long)stream->dma_addr[stream->buf_num]);
-               memset(stream->buf_list[stream->buf_num], 0, size);
-               stream->state |= USB_STATE_URB_BUF;
-       }
-
-       return 0;
-}
-
-int usb_urb_reconfig(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props)
-{
-       int buf_size;
-
-       if (!props)
-               return 0;
-
-       /* check allocated buffers are large enough for the request */
-       if (props->type == USB_BULK) {
-               buf_size = stream->props.u.bulk.buffersize;
-       } else if (props->type == USB_ISOC) {
-               buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
-       } else {
-               dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
-                               KBUILD_MODNAME, props->type);
-               return -EINVAL;
-       }
-
-       if (stream->buf_num < props->count || stream->buf_size < buf_size) {
-               dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
-                               "allocated buffers are too small\n",
-                               KBUILD_MODNAME);
-               return -EINVAL;
-       }
-
-       /* check if all fields are same */
-       if (stream->props.type == props->type &&
-                       stream->props.count == props->count &&
-                       stream->props.endpoint == props->endpoint) {
-               if (props->type == USB_BULK &&
-                               props->u.bulk.buffersize ==
-                               stream->props.u.bulk.buffersize)
-                       return 0;
-               else if (props->type == USB_ISOC &&
-                               props->u.isoc.framesperurb ==
-                               stream->props.u.isoc.framesperurb &&
-                               props->u.isoc.framesize ==
-                               stream->props.u.isoc.framesize &&
-                               props->u.isoc.interval ==
-                               stream->props.u.isoc.interval)
-                       return 0;
-       }
-
-       dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
-
-       usb_urb_free_urbs(stream);
-       memcpy(&stream->props, props, sizeof(*props));
-       if (props->type == USB_BULK)
-               return usb_urb_alloc_bulk_urbs(stream);
-       else if (props->type == USB_ISOC)
-               return usb_urb_alloc_isoc_urbs(stream);
-
-       return 0;
-}
-
-int usb_urb_initv2(struct usb_data_stream *stream,
-               const struct usb_data_stream_properties *props)
-{
-       int ret;
-
-       if (!stream || !props)
-               return -EINVAL;
-
-       memcpy(&stream->props, props, sizeof(*props));
-
-       if (!stream->complete) {
-               dev_err(&stream->udev->dev, "%s: there is no data callback - " \
-                               "this doesn't make sense\n", KBUILD_MODNAME);
-               return -EINVAL;
-       }
-
-       switch (stream->props.type) {
-       case USB_BULK:
-               ret = usb_alloc_stream_buffers(stream, stream->props.count,
-                               stream->props.u.bulk.buffersize);
-               if (ret < 0)
-                       return ret;
-
-               return usb_urb_alloc_bulk_urbs(stream);
-       case USB_ISOC:
-               ret = usb_alloc_stream_buffers(stream, stream->props.count,
-                               stream->props.u.isoc.framesize *
-                               stream->props.u.isoc.framesperurb);
-               if (ret < 0)
-                       return ret;
-
-               return usb_urb_alloc_isoc_urbs(stream);
-       default:
-               dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
-                               "transfer\n", KBUILD_MODNAME);
-               return -EINVAL;
-       }
-}
-
-int usb_urb_exitv2(struct usb_data_stream *stream)
-{
-       usb_urb_free_urbs(stream);
-       usb_free_stream_buffers(stream);
-
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
deleted file mode 100644 (file)
index 00173ee..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-config DVB_USB
-       tristate "Support for various USB DVB devices"
-       depends on DVB_CORE && USB && I2C && RC_CORE
-       help
-         By enabling this you will be able to choose the various supported
-         USB1.1 and USB2.0 DVB devices.
-
-         Almost every USB device needs a firmware, please look into
-         <file:Documentation/dvb/README.dvb-usb>.
-
-         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
-         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
-
-         Say Y if you own a USB DVB device.
-
-config DVB_USB_DEBUG
-       bool "Enable extended debug support for all DVB-USB devices"
-       depends on DVB_USB
-       help
-         Say Y if you want to enable debugging. See modinfo dvb-usb (and the
-         appropriate drivers) for debug levels.
-
-config DVB_USB_A800
-       tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
-       depends on DVB_USB
-       select DVB_DIB3000MC
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
-
-config DVB_USB_DIBUSB_MB
-       tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
-       depends on DVB_USB
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_DIB3000MB
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
-         DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
-
-         For an up-to-date list of devices supported by this driver, have a look
-         on the Linux-DVB Wiki at www.linuxtv.org.
-
-         Say Y if you own such a device and want to use it. You should build it as
-         a module.
-
-config DVB_USB_DIBUSB_MB_FAULTY
-       bool "Support faulty USB IDs"
-       depends on DVB_USB_DIBUSB_MB
-       help
-         Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
-
-config DVB_USB_DIBUSB_MC
-       tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
-       depends on DVB_USB
-       select DVB_DIB3000MC
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Support for USB2.0 DVB-T receivers based on reference designs made by
-         DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
-
-         For an up-to-date list of devices supported by this driver, have a look
-         on the Linux-DVB Wiki at www.linuxtv.org.
-
-         Say Y if you own such a device and want to use it. You should build it as
-         a module.
-
-config DVB_USB_DIB0700
-       tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
-       depends on DVB_USB
-       select DVB_DIB7000P if !DVB_FE_CUSTOMISE
-       select DVB_DIB7000M if !DVB_FE_CUSTOMISE
-       select DVB_DIB8000 if !DVB_FE_CUSTOMISE
-       select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
-       select DVB_S5H1411 if !DVB_FE_CUSTOMISE
-       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
-       select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
-       select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
-       help
-         Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
-         USB bridge is also present in devices having the DiB7700 DVB-T-USB
-         silicon. This chip can be found in devices offered by Hauppauge,
-         Avermedia and other big and small companies.
-
-         For an up-to-date list of devices supported by this driver, have a look
-         on the LinuxTV Wiki at www.linuxtv.org.
-
-         Say Y if you own such a device and want to use it. You should build it as
-         a module.
-
-config DVB_USB_UMT_010
-       tristate "HanfTek UMT-010 DVB-T USB2.0 support"
-       depends on DVB_USB
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_DIB3000MC
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
-
-config DVB_USB_CXUSB
-       tristate "Conexant USB2.0 hybrid reference design support"
-       depends on DVB_USB
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_CX22702 if !DVB_FE_CUSTOMISE
-       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select DVB_DIB7000P if !DVB_FE_CUSTOMISE
-       select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
-       select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
-       select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Conexant USB2.0 hybrid reference design.
-         Currently, only DVB and ATSC modes are supported, analog mode
-         shall be added in the future. Devices that require this module:
-
-         Medion MD95700 hybrid USB2.0 device.
-         DViCO FusionHDTV (Bluebird) USB2.0 devices
-
-config DVB_USB_M920X
-       tristate "Uli m920x DVB-T USB2.0 support"
-       depends on DVB_USB
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
-         Currently, only devices with a product id of
-         "DTV USB MINI" (in cold state) are supported.
-         Firmware required.
-
-config DVB_USB_DIGITV
-       tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
-       depends on DVB_USB
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_NXT6000 if !DVB_FE_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
-
-config DVB_USB_VP7045
-       tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
-       depends on DVB_USB
-       help
-         Say Y here to support the
-
-           TwinhanDTV Alpha (stick) (VP-7045),
-               TwinhanDTV MagicBox II (VP-7046),
-               DigitalNow TinyUSB 2 DVB-t,
-               DigitalRise USB 2.0 Ter (Beetle) and
-               TYPHOON DVB-T USB DRIVE
-
-         DVB-T USB2.0 receivers.
-
-config DVB_USB_VP702X
-       tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
-       depends on DVB_USB
-       help
-         Say Y here to support the
-
-           TwinhanDTV StarBox,
-               DigitalRise USB Starbox and
-               TYPHOON DVB-S USB 2.0 BOX
-
-         DVB-S USB2.0 receivers.
-
-config DVB_USB_GP8PSK
-       tristate "GENPIX 8PSK->USB module support"
-       depends on DVB_USB
-       help
-         Say Y here to support the
-           GENPIX 8psk module
-
-         DVB-S USB2.0 receivers.
-
-config DVB_USB_NOVA_T_USB2
-       tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
-       depends on DVB_USB
-       select DVB_DIB3000MC
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
-
-config DVB_USB_TTUSB2
-       tristate "Pinnacle 400e DVB-S USB2.0 support"
-       depends on DVB_USB
-       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       select DVB_TDA826X if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
-         firmware protocol used by this module is similar to the one used by the
-         old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
-
-config DVB_USB_DTT200U
-       tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
-       depends on DVB_USB
-       help
-         Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
-
-         The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
-
-         The WT-220U and its clones are pen-sized.
-
-config DVB_USB_OPERA1
-       tristate "Opera1 DVB-S USB2.0 receiver"
-       depends on DVB_USB
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Opera DVB-S USB2.0 receiver.
-
-config DVB_USB_AF9005
-       tristate "Afatech AF9005 DVB-T USB1.1 support"
-       depends on DVB_USB && EXPERIMENTAL
-       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
-         and the TerraTec Cinergy T USB XE (Rev.1)
-
-config DVB_USB_AF9005_REMOTE
-       tristate "Afatech AF9005 default remote control support"
-       depends on DVB_USB_AF9005
-       help
-         Say Y here to support the default remote control decoding for the
-         Afatech AF9005 based receiver.
-
-config DVB_USB_PCTV452E
-       tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
-       depends on DVB_USB
-       select TTPCI_EEPROM
-       select DVB_LNBP22 if !DVB_FE_CUSTOMISE
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
-       help
-         Support for external USB adapter designed by Pinnacle,
-         shipped under the brand name 'PCTV HDTV Pro USB'.
-         Also supports TT Connect S2-3600/3650 cards.
-         Say Y if you own such a device and want to use it.
-
-config DVB_USB_DW2102
-       tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
-       depends on DVB_USB
-       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_TDA10023 if !DVB_FE_CUSTOMISE
-       select DVB_MT312 if !DVB_FE_CUSTOMISE
-       select DVB_ZL10039 if !DVB_FE_CUSTOMISE
-       select DVB_DS3000 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
-       select DVB_STV6110 if !DVB_FE_CUSTOMISE
-       select DVB_STV0900 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
-         receivers.
-
-config DVB_USB_CINERGY_T2
-       tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
-       depends on DVB_USB
-       help
-         Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
-
-         Say Y if you own such a device and want to use it.
-
-config DVB_USB_DTV5100
-       tristate "AME DTV-5100 USB2.0 DVB-T support"
-       depends on DVB_USB
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
-
-config DVB_USB_FRIIO
-       tristate "Friio ISDB-T USB2.0 Receiver support"
-       depends on DVB_USB
-       help
-         Say Y here to support the Japanese DTV receiver Friio.
-
-config DVB_USB_AZ6027
-       tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
-       depends on DVB_USB
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the AZ6027 device
-
-config DVB_USB_TECHNISAT_USB2
-       tristate "Technisat DVB-S/S2 USB2.0 support"
-       depends on DVB_USB
-       select DVB_STV090x if !DVB_FE_CUSTOMISE
-       select DVB_STV6110x if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
deleted file mode 100644 (file)
index a5630e3..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
-obj-$(CONFIG_DVB_USB) += dvb-usb.o
-
-dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
-obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
-
-dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
-obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
-
-dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
-obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
-
-dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
-obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
-
-dvb-usb-dibusb-common-objs = dibusb-common.o
-
-dvb-usb-a800-objs = a800.o
-obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
-
-dvb-usb-dibusb-mb-objs = dibusb-mb.o
-obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
-
-dvb-usb-dibusb-mc-objs = dibusb-mc.o
-obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
-
-dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
-obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
-
-dvb-usb-umt-010-objs = umt-010.o
-obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
-
-dvb-usb-m920x-objs = m920x.o
-obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
-
-dvb-usb-digitv-objs = digitv.o
-obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
-
-dvb-usb-cxusb-objs = cxusb.o
-obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
-
-dvb-usb-ttusb2-objs = ttusb2.o
-obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
-
-dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
-obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
-
-dvb-usb-opera-objs = opera1.o
-obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
-
-dvb-usb-af9005-objs = af9005.o af9005-fe.o
-obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
-
-dvb-usb-af9005-remote-objs = af9005-remote.o
-obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
-
-dvb-usb-pctv452e-objs = pctv452e.o
-obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
-
-dvb-usb-dw2102-objs = dw2102.o
-obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
-
-dvb-usb-dtv5100-objs = dtv5100.o
-obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
-
-dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
-obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
-
-dvb-usb-friio-objs = friio.o friio-fe.o
-obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
-
-dvb-usb-az6027-objs = az6027.o
-obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
-
-dvb-usb-technisat-usb2-objs = technisat-usb2.o
-obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
-
-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
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
deleted file mode 100644 (file)
index 8d7fef8..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
- * USB2.0 (A800) DVB-T receiver.
- *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * Thanks to
- *   - AVerMedia who kindly provided information and
- *   - Glen Harris who suffered from my mistakes during development.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_rc(args...)   dprintk(debug,0x01,args)
-
-static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       /* do nothing for the AVerMedia */
-       return 0;
-}
-
-/* assure to put cold to 0 for iManufacturer == 1 */
-static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
-       struct dvb_usb_device_description **desc, int *cold)
-{
-       *cold = udev->descriptor.iManufacturer != 1;
-       return 0;
-}
-
-static struct rc_map_table rc_map_a800_table[] = {
-       { 0x0201, KEY_MODE },      /* SOURCE */
-       { 0x0200, KEY_POWER2 },      /* POWER */
-       { 0x0205, KEY_1 },           /* 1 */
-       { 0x0206, KEY_2 },           /* 2 */
-       { 0x0207, KEY_3 },           /* 3 */
-       { 0x0209, KEY_4 },           /* 4 */
-       { 0x020a, KEY_5 },           /* 5 */
-       { 0x020b, KEY_6 },           /* 6 */
-       { 0x020d, KEY_7 },           /* 7 */
-       { 0x020e, KEY_8 },           /* 8 */
-       { 0x020f, KEY_9 },           /* 9 */
-       { 0x0212, KEY_LEFT },        /* L / DISPLAY */
-       { 0x0211, KEY_0 },           /* 0 */
-       { 0x0213, KEY_RIGHT },       /* R / CH RTN */
-       { 0x0217, KEY_CAMERA },      /* SNAP SHOT */
-       { 0x0210, KEY_LAST },        /* 16-CH PREV */
-       { 0x021e, KEY_VOLUMEDOWN },  /* VOL DOWN */
-       { 0x020c, KEY_ZOOM },        /* FULL SCREEN */
-       { 0x021f, KEY_VOLUMEUP },    /* VOL UP */
-       { 0x0214, KEY_MUTE },        /* MUTE */
-       { 0x0208, KEY_AUDIO },       /* AUDIO */
-       { 0x0219, KEY_RECORD },      /* RECORD */
-       { 0x0218, KEY_PLAY },        /* PLAY */
-       { 0x021b, KEY_STOP },        /* STOP */
-       { 0x021a, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
-       { 0x021d, KEY_BACK },        /* << / RED */
-       { 0x021c, KEY_FORWARD },     /* >> / YELLOW */
-       { 0x0203, KEY_TEXT },        /* TELETEXT */
-       { 0x0204, KEY_EPG },         /* EPG */
-       { 0x0215, KEY_MENU },        /* MENU */
-
-       { 0x0303, KEY_CHANNELUP },   /* CH UP */
-       { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
-       { 0x0301, KEY_FIRST },       /* |<< / GREEN */
-       { 0x0300, KEY_LAST },        /* >>| / BLUE */
-
-};
-
-static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       int ret;
-       u8 *key = kmalloc(5, GFP_KERNEL);
-       if (!key)
-               return -ENOMEM;
-
-       if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
-                               0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
-                               2000) != 5) {
-               ret = -ENODEV;
-               goto out;
-       }
-
-       /* call the universal NEC remote processor, to find out the key's state and event */
-       dvb_usb_nec_rc_key_to_event(d,key,event,state);
-       if (key[0] != 0)
-               deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
-       ret = 0;
-out:
-       kfree(key);
-       return ret;
-}
-
-/* USB Driver stuff */
-static struct dvb_usb_device_properties a800_properties;
-
-static int a800_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &a800_properties,
-                                  THIS_MODULE, NULL, adapter_nr);
-}
-
-/* do not change the order of the ID table */
-static struct usb_device_id a800_table [] = {
-/* 00 */       { USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
-/* 01 */       { USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
-                       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, a800_table);
-
-static struct dvb_usb_device_properties a800_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-avertv-a800-02.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-
-                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
-                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                                       .stream = {
-                                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               },
-       },
-
-       .power_ctrl       = a800_power_ctrl,
-       .identify_state   = a800_identify_state,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_a800_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_a800_table),
-               .rc_query         = a800_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-       .num_device_descs = 1,
-       .devices = {
-               {   "AVerMedia AverTV DVB-T USB 2.0 (A800)",
-                       { &a800_table[0], NULL },
-                       { &a800_table[1], NULL },
-               },
-       }
-};
-
-static struct usb_driver a800_driver = {
-       .name           = "dvb_usb_a800",
-       .probe          = a800_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = a800_table,
-};
-
-module_usb_driver(a800_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
deleted file mode 100644 (file)
index 740f3f4..0000000
+++ /dev/null
@@ -1,1487 +0,0 @@
-/* Frontend part of the Linux driver for the Afatech 9005
- * USB1.1 DVB-T receiver.
- *
- * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
- *
- * Thanks to Afatech who kindly provided information.
- *
- * 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.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "af9005.h"
-#include "af9005-script.h"
-#include "mt2060.h"
-#include "qt1010.h"
-#include <asm/div64.h>
-
-struct af9005_fe_state {
-       struct dvb_usb_device *d;
-       fe_status_t stat;
-
-       /* retraining parameters */
-       u32 original_fcw;
-       u16 original_rf_top;
-       u16 original_if_top;
-       u16 original_if_min;
-       u16 original_aci0_if_top;
-       u16 original_aci1_if_top;
-       u16 original_aci0_if_min;
-       u8 original_if_unplug_th;
-       u8 original_rf_unplug_th;
-       u8 original_dtop_if_unplug_th;
-       u8 original_dtop_rf_unplug_th;
-
-       /* statistics */
-       u32 pre_vit_error_count;
-       u32 pre_vit_bit_count;
-       u32 ber;
-       u32 post_vit_error_count;
-       u32 post_vit_bit_count;
-       u32 unc;
-       u16 abort_count;
-
-       int opened;
-       int strong;
-       unsigned long next_status_check;
-       struct dvb_frontend frontend;
-};
-
-static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi,
-                                u16 reglo, u8 pos, u8 len, u16 value)
-{
-       int ret;
-
-       if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))
-               return ret;
-       return af9005_write_register_bits(d, reghi, pos, len,
-                                         (u8) ((value & 0x300) >> 8));
-}
-
-static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,
-                               u16 reglo, u8 pos, u8 len, u16 * value)
-{
-       int ret;
-       u8 temp0, temp1;
-
-       if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))
-               return ret;
-       if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))
-               return ret;
-       switch (pos) {
-       case 0:
-               *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;
-               break;
-       case 2:
-               *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;
-               break;
-       case 4:
-               *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;
-               break;
-       case 6:
-               *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;
-               break;
-       default:
-               err("invalid pos in read word agc");
-               return -EINVAL;
-       }
-       return 0;
-
-}
-
-static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 temp;
-
-       *available = false;
-
-       ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
-                                       fec_vtb_rsd_mon_en_pos,
-                                       fec_vtb_rsd_mon_en_len, &temp);
-       if (ret)
-               return ret;
-       if (temp & 1) {
-               ret =
-                   af9005_read_register_bits(state->d,
-                                             xd_p_reg_ofsm_read_rbc_en,
-                                             reg_ofsm_read_rbc_en_pos,
-                                             reg_ofsm_read_rbc_en_len, &temp);
-               if (ret)
-                       return ret;
-               if ((temp & 1) == 0)
-                       *available = true;
-
-       }
-       return 0;
-}
-
-static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,
-                                           u32 * post_err_count,
-                                           u32 * post_cw_count,
-                                           u16 * abort_count)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u32 err_count;
-       u32 cw_count;
-       u8 temp, temp0, temp1, temp2;
-       u16 loc_abort_count;
-
-       *post_err_count = 0;
-       *post_cw_count = 0;
-
-       /* check if error bit count is ready */
-       ret =
-           af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,
-                                     fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       if (!temp) {
-               deb_info("rsd counter not ready\n");
-               return 100;
-       }
-       /* get abort count */
-       ret =
-           af9005_read_ofdm_register(state->d,
-                                     xd_r_fec_rsd_abort_packet_cnt_7_0,
-                                     &temp0);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d,
-                                     xd_r_fec_rsd_abort_packet_cnt_15_8,
-                                     &temp1);
-       if (ret)
-               return ret;
-       loc_abort_count = ((u16) temp1 << 8) + temp0;
-
-       /* get error count */
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,
-                                     &temp0);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,
-                                     &temp1);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,
-                                     &temp2);
-       if (ret)
-               return ret;
-       err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
-       *post_err_count = err_count - (u32) loc_abort_count *8 * 8;
-
-       /* get RSD packet number */
-       ret =
-           af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
-                                     &temp0);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
-                                     &temp1);
-       if (ret)
-               return ret;
-       cw_count = ((u32) temp1 << 8) + temp0;
-       if (cw_count == 0) {
-               err("wrong RSD packet count");
-               return -EIO;
-       }
-       deb_info("POST abort count %d err count %d rsd packets %d\n",
-                loc_abort_count, err_count, cw_count);
-       *post_cw_count = cw_count - (u32) loc_abort_count;
-       *abort_count = loc_abort_count;
-       return 0;
-
-}
-
-static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
-                                  u32 * post_err_count, u32 * post_cw_count,
-                                  u16 * abort_count)
-{
-       u32 loc_cw_count = 0, loc_err_count;
-       u16 loc_abort_count = 0;
-       int ret;
-
-       ret =
-           af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,
-                                            &loc_abort_count);
-       if (ret)
-               return ret;
-       *post_err_count = loc_err_count;
-       *post_cw_count = loc_cw_count * 204 * 8;
-       *abort_count = loc_abort_count;
-
-       return 0;
-}
-
-static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,
-                                           u32 * pre_err_count,
-                                           u32 * pre_bit_count)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       u8 temp, temp0, temp1, temp2;
-       u32 super_frame_count, x, bits;
-       int ret;
-
-       ret =
-           af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,
-                                     fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       if (!temp) {
-               deb_info("viterbi counter not ready\n");
-               return 101;     /* ERR_APO_VTB_COUNTER_NOT_READY; */
-       }
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,
-                                     &temp0);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,
-                                     &temp1);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,
-                                     &temp2);
-       if (ret)
-               return ret;
-       *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
-
-       ret =
-           af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
-                                     &temp0);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
-                                     &temp1);
-       if (ret)
-               return ret;
-       super_frame_count = ((u32) temp1 << 8) + temp0;
-       if (super_frame_count == 0) {
-               deb_info("super frame count 0\n");
-               return 102;
-       }
-
-       /* read fft mode */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
-                                     reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       if (temp == 0) {
-               /* 2K */
-               x = 1512;
-       } else if (temp == 1) {
-               /* 8k */
-               x = 6048;
-       } else {
-               err("Invalid fft mode");
-               return -EINVAL;
-       }
-
-       /* read modulation mode */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
-                                     reg_tpsd_const_pos, reg_tpsd_const_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       switch (temp) {
-       case 0:         /* QPSK */
-               bits = 2;
-               break;
-       case 1:         /* QAM_16 */
-               bits = 4;
-               break;
-       case 2:         /* QAM_64 */
-               bits = 6;
-               break;
-       default:
-               err("invalid modulation mode");
-               return -EINVAL;
-       }
-       *pre_bit_count = super_frame_count * 68 * 4 * x * bits;
-       deb_info("PRE err count %d frame count %d bit count %d\n",
-                *pre_err_count, super_frame_count, *pre_bit_count);
-       return 0;
-}
-
-static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-
-       /* set super frame count to 1 */
-       ret =
-           af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
-                                      1 & 0xff);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
-                                        1 >> 8);
-       if (ret)
-               return ret;
-       /* reset pre viterbi error count */
-       ret =
-           af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,
-                                      fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,
-                                      1);
-
-       return ret;
-}
-
-static int af9005_reset_post_viterbi(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-
-       /* set packet unit */
-       ret =
-           af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
-                                      10000 & 0xff);
-       if (ret)
-               return ret;
-       ret =
-           af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
-                                      10000 >> 8);
-       if (ret)
-               return ret;
-       /* reset post viterbi error count */
-       ret =
-           af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,
-                                      fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,
-                                      1);
-
-       return ret;
-}
-
-static int af9005_get_statistic(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret, fecavailable;
-       u64 numerator, denominator;
-
-       deb_info("GET STATISTIC\n");
-       ret = af9005_is_fecmon_available(fe, &fecavailable);
-       if (ret)
-               return ret;
-       if (!fecavailable) {
-               deb_info("fecmon not available\n");
-               return 0;
-       }
-
-       ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,
-                                              &state->pre_vit_bit_count);
-       if (ret == 0) {
-               af9005_reset_pre_viterbi(fe);
-               if (state->pre_vit_bit_count > 0) {
-                       /* according to v 0.0.4 of the dvb api ber should be a multiple
-                          of 10E-9 so we have to multiply the error count by
-                          10E9=1000000000 */
-                       numerator =
-                           (u64) state->pre_vit_error_count * (u64) 1000000000;
-                       denominator = (u64) state->pre_vit_bit_count;
-                       state->ber = do_div(numerator, denominator);
-               } else {
-                       state->ber = 0xffffffff;
-               }
-       }
-
-       ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,
-                                     &state->post_vit_bit_count,
-                                     &state->abort_count);
-       if (ret == 0) {
-               ret = af9005_reset_post_viterbi(fe);
-               state->unc += state->abort_count;
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static int af9005_fe_refresh_state(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       if (time_after(jiffies, state->next_status_check)) {
-               deb_info("REFRESH STATE\n");
-
-               /* statistics */
-               if (af9005_get_statistic(fe))
-                       err("get_statistic_failed");
-               state->next_status_check = jiffies + 250 * HZ / 1000;
-       }
-       return 0;
-}
-
-static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       u8 temp;
-       int ret;
-
-       if (fe->ops.tuner_ops.release == NULL)
-               return -ENODEV;
-
-       *stat = 0;
-       ret = af9005_read_register_bits(state->d, xd_p_agc_lock,
-                                       agc_lock_pos, agc_lock_len, &temp);
-       if (ret)
-               return ret;
-       if (temp)
-               *stat |= FE_HAS_SIGNAL;
-
-       ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,
-                                       fd_tpsd_lock_pos, fd_tpsd_lock_len,
-                                       &temp);
-       if (ret)
-               return ret;
-       if (temp)
-               *stat |= FE_HAS_CARRIER;
-
-       ret = af9005_read_register_bits(state->d,
-                                       xd_r_mp2if_sync_byte_locked,
-                                       mp2if_sync_byte_locked_pos,
-                                       mp2if_sync_byte_locked_pos, &temp);
-       if (ret)
-               return ret;
-       if (temp)
-               *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
-       if (state->opened)
-               af9005_led_control(state->d, *stat & FE_HAS_LOCK);
-
-       ret =
-           af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,
-                                     reg_strong_sginal_detected_pos,
-                                     reg_strong_sginal_detected_len, &temp);
-       if (ret)
-               return ret;
-       if (temp != state->strong) {
-               deb_info("adjust for strong signal %d\n", temp);
-                       state->strong = temp;
-       }
-       return 0;
-}
-
-static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       if (fe->ops.tuner_ops.release  == NULL)
-               return -ENODEV;
-       af9005_fe_refresh_state(fe);
-       *ber = state->ber;
-       return 0;
-}
-
-static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       if (fe->ops.tuner_ops.release == NULL)
-               return -ENODEV;
-       af9005_fe_refresh_state(fe);
-       *unc = state->unc;
-       return 0;
-}
-
-static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
-                                         u16 * strength)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 if_gain, rf_gain;
-
-       if (fe->ops.tuner_ops.release == NULL)
-               return -ENODEV;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
-                                     &rf_gain);
-       if (ret)
-               return ret;
-       ret =
-           af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,
-                                     &if_gain);
-       if (ret)
-               return ret;
-       /* this value has no real meaning, but i don't have the tables that relate
-          the rf and if gain with the dbm, so I just scale the value */
-       *strength = (512 - rf_gain - if_gain) << 7;
-       return 0;
-}
-
-static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       /* the snr can be derived from the ber and the modulation
-          but I don't think this kind of complex calculations belong
-          in the driver. I may be wrong.... */
-       return -ENOSYS;
-}
-
-static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw)
-{
-       u8 temp0, temp1, temp2, temp3, buf[4];
-       int ret;
-       u32 NS_coeff1_2048Nu;
-       u32 NS_coeff1_8191Nu;
-       u32 NS_coeff1_8192Nu;
-       u32 NS_coeff1_8193Nu;
-       u32 NS_coeff2_2k;
-       u32 NS_coeff2_8k;
-
-       switch (bw) {
-       case 6000000:
-               NS_coeff1_2048Nu = 0x2ADB6DC;
-               NS_coeff1_8191Nu = 0xAB7313;
-               NS_coeff1_8192Nu = 0xAB6DB7;
-               NS_coeff1_8193Nu = 0xAB685C;
-               NS_coeff2_2k = 0x156DB6E;
-               NS_coeff2_8k = 0x55B6DC;
-               break;
-
-       case 7000000:
-               NS_coeff1_2048Nu = 0x3200001;
-               NS_coeff1_8191Nu = 0xC80640;
-               NS_coeff1_8192Nu = 0xC80000;
-               NS_coeff1_8193Nu = 0xC7F9C0;
-               NS_coeff2_2k = 0x1900000;
-               NS_coeff2_8k = 0x640000;
-               break;
-
-       case 8000000:
-               NS_coeff1_2048Nu = 0x3924926;
-               NS_coeff1_8191Nu = 0xE4996E;
-               NS_coeff1_8192Nu = 0xE49249;
-               NS_coeff1_8193Nu = 0xE48B25;
-               NS_coeff2_2k = 0x1C92493;
-               NS_coeff2_8k = 0x724925;
-               break;
-       default:
-               err("Invalid bandwidth %d.", bw);
-               return -EINVAL;
-       }
-
-       /*
-        *  write NS_coeff1_2048Nu
-        */
-
-       temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);
-       temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);
-       temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);
-       temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       /*  cfoe_NS_2k_coeff1_25_24 */
-       ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);
-       if (ret)
-               return ret;
-
-       /*  cfoe_NS_2k_coeff1_23_16 */
-       ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);
-       if (ret)
-               return ret;
-
-       /*  cfoe_NS_2k_coeff1_15_8 */
-       ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);
-       if (ret)
-               return ret;
-
-       /*  cfoe_NS_2k_coeff1_7_0 */
-       ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);
-       if (ret)
-               return ret;
-
-       /*
-        *  write NS_coeff2_2k
-        */
-
-       temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));
-       temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);
-       temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);
-       temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);
-       if (ret)
-               return ret;
-
-       /*
-        *  write NS_coeff1_8191Nu
-        */
-
-       temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));
-       temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);
-       temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);
-       temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);
-       if (ret)
-               return ret;
-
-       /*
-        *  write NS_coeff1_8192Nu
-        */
-
-       temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);
-       temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);
-       temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);
-       temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);
-       if (ret)
-               return ret;
-
-       /*
-        *  write NS_coeff1_8193Nu
-        */
-
-       temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));
-       temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);
-       temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);
-       temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);
-       if (ret)
-               return ret;
-
-       /*
-        *  write NS_coeff2_8k
-        */
-
-       temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));
-       temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);
-       temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);
-       temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);
-
-       /*  big endian to make 8051 happy */
-       buf[0] = temp3;
-       buf[1] = temp2;
-       buf[2] = temp1;
-       buf[3] = temp0;
-
-       ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);
-       if (ret)
-               return ret;
-
-       ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);
-       return ret;
-
-}
-
-static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw)
-{
-       u8 temp;
-       switch (bw) {
-       case 6000000:
-               temp = 0;
-               break;
-       case 7000000:
-               temp = 1;
-               break;
-       case 8000000:
-               temp = 2;
-               break;
-       default:
-               err("Invalid bandwidth %d.", bw);
-               return -EINVAL;
-       }
-       return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,
-                                         reg_bw_len, temp);
-}
-
-static int af9005_fe_power(struct dvb_frontend *fe, int on)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       u8 temp = on;
-       int ret;
-       deb_info("power %s tuner\n", on ? "on" : "off");
-       ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
-       return ret;
-}
-
-static struct mt2060_config af9005_mt2060_config = {
-       0xC0
-};
-
-static struct qt1010_config af9005_qt1010_config = {
-       0xC4
-};
-
-static int af9005_fe_init(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       int ret, i, scriptlen;
-       u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
-       u8 buf[2];
-       u16 if1;
-
-       deb_info("in af9005_fe_init\n");
-
-       /* reset */
-       deb_info("reset\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,
-                                       4, 1, 0x01)))
-               return ret;
-       if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))
-               return ret;
-       /* clear ofdm reset */
-       deb_info("clear ofdm reset\n");
-       for (i = 0; i < 150; i++) {
-               if ((ret =
-                    af9005_read_ofdm_register(state->d,
-                                              xd_I2C_reg_ofdm_rst, &temp)))
-                       return ret;
-               if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))
-                       break;
-               msleep(10);
-       }
-       if (i == 150)
-               return -ETIMEDOUT;
-
-       /*FIXME in the dump
-          write B200 A9
-          write xd_g_reg_ofsm_clk 7
-          read eepr c6 (2)
-          read eepr c7 (2)
-          misc ctrl 3 -> 1
-          read eepr ca (6)
-          write xd_g_reg_ofsm_clk 0
-          write B200 a1
-        */
-       ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);
-       if (ret)
-               return ret;
-       temp = 0x01;
-       ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);
-       if (ret)
-               return ret;
-
-       temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
-                                       reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
-               return ret;
-       ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
-                                        reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
-
-       if (ret)
-               return ret;
-       /* don't know what register aefc is, but this is what the windows driver does */
-       ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);
-       if (ret)
-               return ret;
-
-       /* set stand alone chip */
-       deb_info("set stand alone chip\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,
-                                       reg_dca_stand_alone_pos,
-                                       reg_dca_stand_alone_len, 1)))
-               return ret;
-
-       /* set dca upper & lower chip */
-       deb_info("set dca upper & lower chip\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,
-                                       reg_dca_upper_chip_pos,
-                                       reg_dca_upper_chip_len, 0)))
-               return ret;
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,
-                                       reg_dca_lower_chip_pos,
-                                       reg_dca_lower_chip_len, 0)))
-               return ret;
-
-       /* set 2wire master clock to 0x14 (for 60KHz) */
-       deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");
-       if ((ret =
-            af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))
-               return ret;
-
-       /* clear dca enable chip */
-       deb_info("clear dca enable chip\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_dca_en,
-                                       reg_dca_en_pos, reg_dca_en_len, 0)))
-               return ret;
-       /* FIXME these are register bits, but I don't know which ones */
-       ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);
-       if (ret)
-               return ret;
-
-       /* init other parameters: program cfoe and select bandwidth */
-       deb_info("program cfoe\n");
-       ret = af9005_fe_program_cfoe(state->d, 6000000);
-       if (ret)
-               return ret;
-       /* set read-update bit for modulation */
-       deb_info("set read-update bit for modulation\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,
-                                       reg_feq_read_update_pos,
-                                       reg_feq_read_update_len, 1)))
-               return ret;
-
-       /* sample code has a set MPEG TS code here
-          but sniffing reveals that it doesn't do it */
-
-       /* set read-update bit to 1 for DCA modulation */
-       deb_info("set read-update bit 1 for DCA modulation\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,
-                                       reg_dca_read_update_pos,
-                                       reg_dca_read_update_len, 1)))
-               return ret;
-
-       /* enable fec monitor */
-       deb_info("enable fec monitor\n");
-       if ((ret =
-            af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
-                                       fec_vtb_rsd_mon_en_pos,
-                                       fec_vtb_rsd_mon_en_len, 1)))
-               return ret;
-
-       /* FIXME should be register bits, I don't know which ones */
-       ret = af9005_write_ofdm_register(state->d, 0xa601, 0);
-
-       /* set api_retrain_never_freeze */
-       deb_info("set api_retrain_never_freeze\n");
-       if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
-               return ret;
-
-       /* load init script */
-       deb_info("load init script\n");
-       scriptlen = sizeof(script) / sizeof(RegDesc);
-       for (i = 0; i < scriptlen; i++) {
-               if ((ret =
-                    af9005_write_register_bits(state->d, script[i].reg,
-                                               script[i].pos,
-                                               script[i].len, script[i].val)))
-                       return ret;
-               /* save 3 bytes of original fcw */
-               if (script[i].reg == 0xae18)
-                       temp2 = script[i].val;
-               if (script[i].reg == 0xae19)
-                       temp1 = script[i].val;
-               if (script[i].reg == 0xae1a)
-                       temp0 = script[i].val;
-
-               /* save original unplug threshold */
-               if (script[i].reg == xd_p_reg_unplug_th)
-                       state->original_if_unplug_th = script[i].val;
-               if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
-                       state->original_rf_unplug_th = script[i].val;
-               if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
-                       state->original_dtop_if_unplug_th = script[i].val;
-               if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
-                       state->original_dtop_rf_unplug_th = script[i].val;
-
-       }
-       state->original_fcw =
-           ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
-
-
-       /* save original TOPs */
-       deb_info("save original TOPs\n");
-
-       /*  RF TOP */
-       ret =
-           af9005_read_word_agc(state->d,
-                                xd_p_reg_aagc_rf_top_numerator_9_8,
-                                xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
-                                &state->original_rf_top);
-       if (ret)
-               return ret;
-
-       /*  IF TOP */
-       ret =
-           af9005_read_word_agc(state->d,
-                                xd_p_reg_aagc_if_top_numerator_9_8,
-                                xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
-                                &state->original_if_top);
-       if (ret)
-               return ret;
-
-       /*  ACI 0 IF TOP */
-       ret =
-           af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
-                                &state->original_aci0_if_top);
-       if (ret)
-               return ret;
-
-       /*  ACI 1 IF TOP */
-       ret =
-           af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
-                                &state->original_aci1_if_top);
-       if (ret)
-               return ret;
-
-       /* attach tuner and init */
-       if (fe->ops.tuner_ops.release == NULL) {
-               /* read tuner and board id from eeprom */
-               ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
-               if (ret) {
-                       err("Impossible to read EEPROM\n");
-                       return ret;
-               }
-               deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);
-               switch (buf[0]) {
-               case 2: /* MT2060 */
-                       /* read if1 from eeprom */
-                       ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);
-                       if (ret) {
-                               err("Impossible to read EEPROM\n");
-                               return ret;
-                       }
-                       if1 = (u16) (buf[0] << 8) + buf[1];
-                       if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
-                                        &af9005_mt2060_config, if1) == NULL) {
-                               deb_info("MT2060 attach failed\n");
-                               return -ENODEV;
-                       }
-                       break;
-               case 3: /* QT1010 */
-               case 9: /* QT1010B */
-                       if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
-                                       &af9005_qt1010_config) ==NULL) {
-                               deb_info("QT1010 attach failed\n");
-                               return -ENODEV;
-                       }
-                       break;
-               default:
-                       err("Unsupported tuner type %d", buf[0]);
-                       return -ENODEV;
-               }
-               ret = fe->ops.tuner_ops.init(fe);
-               if (ret)
-                       return ret;
-       }
-
-       deb_info("profit!\n");
-       return 0;
-}
-
-static int af9005_fe_sleep(struct dvb_frontend *fe)
-{
-       return af9005_fe_power(fe, 0);
-}
-
-static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
-{
-       struct af9005_fe_state *state = fe->demodulator_priv;
-
-       if (acquire) {
-               state->opened++;
-       } else {
-
-               state->opened--;
-               if (!state->opened)
-                       af9005_led_control(state->d, 0);
-       }
-       return 0;
-}
-
-static int af9005_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 temp, temp0, temp1, temp2;
-
-       deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
-                fep->bandwidth_hz);
-       if (fe->ops.tuner_ops.release == NULL) {
-               err("Tuner not attached");
-               return -ENODEV;
-       }
-
-       deb_info("turn off led\n");
-       /* not in the log */
-       ret = af9005_led_control(state->d, 0);
-       if (ret)
-               return ret;
-       /* not sure about the bits */
-       ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);
-       if (ret)
-               return ret;
-
-       /* set FCW to default value */
-       deb_info("set FCW to default value\n");
-       temp0 = (u8) (state->original_fcw & 0x000000ff);
-       temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);
-       temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);
-       ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);
-       if (ret)
-               return ret;
-       ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);
-       if (ret)
-               return ret;
-
-       /* restore original TOPs */
-       deb_info("restore original TOPs\n");
-       ret =
-           af9005_write_word_agc(state->d,
-                                 xd_p_reg_aagc_rf_top_numerator_9_8,
-                                 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
-                                 state->original_rf_top);
-       if (ret)
-               return ret;
-       ret =
-           af9005_write_word_agc(state->d,
-                                 xd_p_reg_aagc_if_top_numerator_9_8,
-                                 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
-                                 state->original_if_top);
-       if (ret)
-               return ret;
-       ret =
-           af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
-                                 state->original_aci0_if_top);
-       if (ret)
-               return ret;
-       ret =
-           af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
-                                 state->original_aci1_if_top);
-       if (ret)
-               return ret;
-
-       /* select bandwidth */
-       deb_info("select bandwidth");
-       ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz);
-       if (ret)
-               return ret;
-       ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz);
-       if (ret)
-               return ret;
-
-       /* clear easy mode flag */
-       deb_info("clear easy mode flag\n");
-       ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);
-       if (ret)
-               return ret;
-
-       /* set unplug threshold to original value */
-       deb_info("set unplug threshold to original value\n");
-       ret =
-           af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,
-                                      state->original_if_unplug_th);
-       if (ret)
-               return ret;
-       /* set tuner */
-       deb_info("set tuner\n");
-       ret = fe->ops.tuner_ops.set_params(fe);
-       if (ret)
-               return ret;
-
-       /* trigger ofsm */
-       deb_info("trigger ofsm\n");
-       temp = 0;
-       ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);
-       if (ret)
-               return ret;
-
-       /* clear retrain and freeze flag */
-       deb_info("clear retrain and freeze flag\n");
-       ret =
-           af9005_write_register_bits(state->d,
-                                      xd_p_reg_api_retrain_request,
-                                      reg_api_retrain_request_pos, 2, 0);
-       if (ret)
-               return ret;
-
-       /* reset pre viterbi and post viterbi registers and statistics */
-       af9005_reset_pre_viterbi(fe);
-       af9005_reset_post_viterbi(fe);
-       state->pre_vit_error_count = 0;
-       state->pre_vit_bit_count = 0;
-       state->ber = 0;
-       state->post_vit_error_count = 0;
-       /* state->unc = 0; commented out since it should be ever increasing */
-       state->abort_count = 0;
-
-       state->next_status_check = jiffies;
-       state->strong = -1;
-
-       return 0;
-}
-
-static int af9005_fe_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct af9005_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 temp;
-
-       /* mode */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
-                                     reg_tpsd_const_pos, reg_tpsd_const_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       deb_info("===== fe_get_frontend_legacy = =============\n");
-       deb_info("CONSTELLATION ");
-       switch (temp) {
-       case 0:
-               fep->modulation = QPSK;
-               deb_info("QPSK\n");
-               break;
-       case 1:
-               fep->modulation = QAM_16;
-               deb_info("QAM_16\n");
-               break;
-       case 2:
-               fep->modulation = QAM_64;
-               deb_info("QAM_64\n");
-               break;
-       }
-
-       /* tps hierarchy and alpha value */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,
-                                     reg_tpsd_hier_pos, reg_tpsd_hier_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       deb_info("HIERARCHY ");
-       switch (temp) {
-       case 0:
-               fep->hierarchy = HIERARCHY_NONE;
-               deb_info("NONE\n");
-               break;
-       case 1:
-               fep->hierarchy = HIERARCHY_1;
-               deb_info("1\n");
-               break;
-       case 2:
-               fep->hierarchy = HIERARCHY_2;
-               deb_info("2\n");
-               break;
-       case 3:
-               fep->hierarchy = HIERARCHY_4;
-               deb_info("4\n");
-               break;
-       }
-
-       /*  high/low priority     */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_dec_pri,
-                                     reg_dec_pri_pos, reg_dec_pri_len, &temp);
-       if (ret)
-               return ret;
-       /* if temp is set = high priority */
-       deb_info("PRIORITY %s\n", temp ? "high" : "low");
-
-       /* high coderate */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,
-                                     reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       deb_info("CODERATE HP ");
-       switch (temp) {
-       case 0:
-               fep->code_rate_HP = FEC_1_2;
-               deb_info("FEC_1_2\n");
-               break;
-       case 1:
-               fep->code_rate_HP = FEC_2_3;
-               deb_info("FEC_2_3\n");
-               break;
-       case 2:
-               fep->code_rate_HP = FEC_3_4;
-               deb_info("FEC_3_4\n");
-               break;
-       case 3:
-               fep->code_rate_HP = FEC_5_6;
-               deb_info("FEC_5_6\n");
-               break;
-       case 4:
-               fep->code_rate_HP = FEC_7_8;
-               deb_info("FEC_7_8\n");
-               break;
-       }
-
-       /* low coderate */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,
-                                     reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       deb_info("CODERATE LP ");
-       switch (temp) {
-       case 0:
-               fep->code_rate_LP = FEC_1_2;
-               deb_info("FEC_1_2\n");
-               break;
-       case 1:
-               fep->code_rate_LP = FEC_2_3;
-               deb_info("FEC_2_3\n");
-               break;
-       case 2:
-               fep->code_rate_LP = FEC_3_4;
-               deb_info("FEC_3_4\n");
-               break;
-       case 3:
-               fep->code_rate_LP = FEC_5_6;
-               deb_info("FEC_5_6\n");
-               break;
-       case 4:
-               fep->code_rate_LP = FEC_7_8;
-               deb_info("FEC_7_8\n");
-               break;
-       }
-
-       /* guard interval */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,
-                                     reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
-       if (ret)
-               return ret;
-       deb_info("GUARD INTERVAL ");
-       switch (temp) {
-       case 0:
-               fep->guard_interval = GUARD_INTERVAL_1_32;
-               deb_info("1_32\n");
-               break;
-       case 1:
-               fep->guard_interval = GUARD_INTERVAL_1_16;
-               deb_info("1_16\n");
-               break;
-       case 2:
-               fep->guard_interval = GUARD_INTERVAL_1_8;
-               deb_info("1_8\n");
-               break;
-       case 3:
-               fep->guard_interval = GUARD_INTERVAL_1_4;
-               deb_info("1_4\n");
-               break;
-       }
-
-       /* fft */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
-                                     reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
-                                     &temp);
-       if (ret)
-               return ret;
-       deb_info("TRANSMISSION MODE ");
-       switch (temp) {
-       case 0:
-               fep->transmission_mode = TRANSMISSION_MODE_2K;
-               deb_info("2K\n");
-               break;
-       case 1:
-               fep->transmission_mode = TRANSMISSION_MODE_8K;
-               deb_info("8K\n");
-               break;
-       }
-
-       /* bandwidth      */
-       ret =
-           af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,
-                                     reg_bw_len, &temp);
-       deb_info("BANDWIDTH ");
-       switch (temp) {
-       case 0:
-               fep->bandwidth_hz = 6000000;
-               deb_info("6\n");
-               break;
-       case 1:
-               fep->bandwidth_hz = 7000000;
-               deb_info("7\n");
-               break;
-       case 2:
-               fep->bandwidth_hz = 8000000;
-               deb_info("8\n");
-               break;
-       }
-       return 0;
-}
-
-static void af9005_fe_release(struct dvb_frontend *fe)
-{
-       struct af9005_fe_state *state =
-           (struct af9005_fe_state *)fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops af9005_fe_ops;
-
-struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
-{
-       struct af9005_fe_state *state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       deb_info("attaching frontend af9005\n");
-
-       state->d = d;
-       state->opened = 0;
-
-       memcpy(&state->frontend.ops, &af9005_fe_ops,
-              sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-      error:
-       return NULL;
-}
-
-static struct dvb_frontend_ops af9005_fe_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-                .name = "AF9005 USB DVB-T",
-                .frequency_min = 44250000,
-                .frequency_max = 867250000,
-                .frequency_stepsize = 250000,
-                .caps = FE_CAN_INVERSION_AUTO |
-                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
-                FE_CAN_HIERARCHY_AUTO,
-                },
-
-       .release = af9005_fe_release,
-
-       .init = af9005_fe_init,
-       .sleep = af9005_fe_sleep,
-       .ts_bus_ctrl = af9005_ts_bus_ctrl,
-
-       .set_frontend = af9005_fe_set_frontend,
-       .get_frontend = af9005_fe_get_frontend,
-
-       .read_status = af9005_fe_read_status,
-       .read_ber = af9005_fe_read_ber,
-       .read_signal_strength = af9005_fe_read_signal_strength,
-       .read_snr = af9005_fe_read_snr,
-       .read_ucblocks = af9005_fe_read_unc_blocks,
-};
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
deleted file mode 100644 (file)
index 7e3961d..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* DVB USB compliant Linux driver for the Afatech 9005
- * USB1.1 DVB-T receiver.
- *
- * Standard remote decode function
- *
- * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
- *
- * Thanks to Afatech who kindly provided information.
- *
- * 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.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "af9005.h"
-/* debug */
-static int dvb_usb_af9005_remote_debug;
-module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
-MODULE_PARM_DESC(debug,
-                "enable (1) or disable (0) debug messages."
-                DVB_USB_DEBUG_STATUS);
-
-#define deb_decode(args...)   dprintk(dvb_usb_af9005_remote_debug,0x01,args)
-
-struct rc_map_table rc_map_af9005_table[] = {
-
-       {0x01b7, KEY_POWER},
-       {0x01a7, KEY_VOLUMEUP},
-       {0x0187, KEY_CHANNELUP},
-       {0x017f, KEY_MUTE},
-       {0x01bf, KEY_VOLUMEDOWN},
-       {0x013f, KEY_CHANNELDOWN},
-       {0x01df, KEY_1},
-       {0x015f, KEY_2},
-       {0x019f, KEY_3},
-       {0x011f, KEY_4},
-       {0x01ef, KEY_5},
-       {0x016f, KEY_6},
-       {0x01af, KEY_7},
-       {0x0127, KEY_8},
-       {0x0107, KEY_9},
-       {0x01cf, KEY_ZOOM},
-       {0x014f, KEY_0},
-       {0x018f, KEY_GOTO},     /* marked jump on the remote */
-
-       {0x00bd, KEY_POWER},
-       {0x007d, KEY_VOLUMEUP},
-       {0x00fd, KEY_CHANNELUP},
-       {0x009d, KEY_MUTE},
-       {0x005d, KEY_VOLUMEDOWN},
-       {0x00dd, KEY_CHANNELDOWN},
-       {0x00ad, KEY_1},
-       {0x006d, KEY_2},
-       {0x00ed, KEY_3},
-       {0x008d, KEY_4},
-       {0x004d, KEY_5},
-       {0x00cd, KEY_6},
-       {0x00b5, KEY_7},
-       {0x0075, KEY_8},
-       {0x00f5, KEY_9},
-       {0x0095, KEY_ZOOM},
-       {0x0055, KEY_0},
-       {0x00d5, KEY_GOTO},     /* marked jump on the remote */
-};
-
-int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
-
-static int repeatable_keys[] = {
-       KEY_VOLUMEUP,
-       KEY_VOLUMEDOWN,
-       KEY_CHANNELUP,
-       KEY_CHANNELDOWN
-};
-
-int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
-                    int *state)
-{
-       u16 mark, space;
-       u32 result;
-       u8 cust, dat, invdat;
-       int i;
-
-       if (len >= 6) {
-               mark = (u16) (data[0] << 8) + data[1];
-               space = (u16) (data[2] << 8) + data[3];
-               if (space * 3 < mark) {
-                       for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
-                               if (d->last_event == repeatable_keys[i]) {
-                                       *state = REMOTE_KEY_REPEAT;
-                                       *event = d->last_event;
-                                       deb_decode("repeat key, event %x\n",
-                                                  *event);
-                                       return 0;
-                               }
-                       }
-                       deb_decode("repeated key ignored (non repeatable)\n");
-                       return 0;
-               } else if (len >= 33 * 4) {     /*32 bits + start code */
-                       result = 0;
-                       for (i = 4; i < 4 + 32 * 4; i += 4) {
-                               result <<= 1;
-                               mark = (u16) (data[i] << 8) + data[i + 1];
-                               mark >>= 1;
-                               space = (u16) (data[i + 2] << 8) + data[i + 3];
-                               space >>= 1;
-                               if (mark * 2 > space)
-                                       result += 1;
-                       }
-                       deb_decode("key pressed, raw value %x\n", result);
-                       if ((result & 0xff000000) != 0xfe000000) {
-                               deb_decode
-                                   ("doesn't start with 0xfe, ignored\n");
-                               return 0;
-                       }
-                       cust = (result >> 16) & 0xff;
-                       dat = (result >> 8) & 0xff;
-                       invdat = (~result) & 0xff;
-                       if (dat != invdat) {
-                               deb_decode("code != inverted code\n");
-                               return 0;
-                       }
-                       for (i = 0; i < rc_map_af9005_table_size; i++) {
-                               if (rc5_custom(&rc_map_af9005_table[i]) == cust
-                                   && rc5_data(&rc_map_af9005_table[i]) == dat) {
-                                       *event = rc_map_af9005_table[i].keycode;
-                                       *state = REMOTE_KEY_PRESSED;
-                                       deb_decode
-                                           ("key pressed, event %x\n", *event);
-                                       return 0;
-                               }
-                       }
-                       deb_decode("not found in table\n");
-               }
-       }
-       return 0;
-}
-
-EXPORT_SYMBOL(rc_map_af9005_table);
-EXPORT_SYMBOL(rc_map_af9005_table_size);
-EXPORT_SYMBOL(af9005_rc_decode);
-
-MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
-MODULE_DESCRIPTION
-    ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h
deleted file mode 100644 (file)
index 4d69045..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
-File automatically generated by createinit.py using data
-extracted from AF05BDA.sys (windows driver):
-
-dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110
-python createinit.py > af9005-script.h
-
-*/
-
-typedef struct {
-       u16 reg;
-       u8 pos;
-       u8 len;
-       u8 val;
-} RegDesc;
-
-static RegDesc script[] = {
-       {0xa180, 0x0, 0x8, 0xa},
-       {0xa181, 0x0, 0x8, 0xd7},
-       {0xa182, 0x0, 0x8, 0xa3},
-       {0xa0a0, 0x0, 0x8, 0x0},
-       {0xa0a1, 0x0, 0x5, 0x0},
-       {0xa0a1, 0x5, 0x1, 0x1},
-       {0xa0c0, 0x0, 0x4, 0x1},
-       {0xa20e, 0x4, 0x4, 0xa},
-       {0xa20f, 0x0, 0x8, 0x40},
-       {0xa210, 0x0, 0x8, 0x8},
-       {0xa32a, 0x0, 0x4, 0xa},
-       {0xa32c, 0x0, 0x8, 0x20},
-       {0xa32b, 0x0, 0x8, 0x15},
-       {0xa1a0, 0x1, 0x1, 0x1},
-       {0xa000, 0x0, 0x1, 0x1},
-       {0xa000, 0x1, 0x1, 0x0},
-       {0xa001, 0x1, 0x1, 0x1},
-       {0xa001, 0x0, 0x1, 0x0},
-       {0xa001, 0x5, 0x1, 0x0},
-       {0xa00e, 0x0, 0x5, 0x10},
-       {0xa00f, 0x0, 0x3, 0x4},
-       {0xa00f, 0x3, 0x3, 0x5},
-       {0xa010, 0x0, 0x3, 0x4},
-       {0xa010, 0x3, 0x3, 0x5},
-       {0xa016, 0x4, 0x4, 0x3},
-       {0xa01f, 0x0, 0x6, 0xa},
-       {0xa020, 0x0, 0x6, 0xa},
-       {0xa2bc, 0x0, 0x1, 0x1},
-       {0xa2bc, 0x5, 0x1, 0x1},
-       {0xa015, 0x0, 0x8, 0x50},
-       {0xa016, 0x0, 0x1, 0x0},
-       {0xa02a, 0x0, 0x8, 0x50},
-       {0xa029, 0x0, 0x8, 0x4b},
-       {0xa614, 0x0, 0x8, 0x46},
-       {0xa002, 0x0, 0x5, 0x19},
-       {0xa003, 0x0, 0x5, 0x1a},
-       {0xa004, 0x0, 0x5, 0x19},
-       {0xa005, 0x0, 0x5, 0x1a},
-       {0xa008, 0x0, 0x8, 0x69},
-       {0xa009, 0x0, 0x2, 0x2},
-       {0xae1b, 0x0, 0x8, 0x69},
-       {0xae1c, 0x0, 0x8, 0x2},
-       {0xae1d, 0x0, 0x8, 0x2a},
-       {0xa022, 0x0, 0x8, 0xaa},
-       {0xa006, 0x0, 0x8, 0xc8},
-       {0xa007, 0x0, 0x2, 0x0},
-       {0xa00c, 0x0, 0x8, 0xba},
-       {0xa00d, 0x0, 0x2, 0x2},
-       {0xa608, 0x0, 0x8, 0xba},
-       {0xa60e, 0x0, 0x2, 0x2},
-       {0xa609, 0x0, 0x8, 0x80},
-       {0xa60e, 0x2, 0x2, 0x3},
-       {0xa00a, 0x0, 0x8, 0xb6},
-       {0xa00b, 0x0, 0x2, 0x0},
-       {0xa011, 0x0, 0x8, 0xb9},
-       {0xa012, 0x0, 0x2, 0x0},
-       {0xa013, 0x0, 0x8, 0xbd},
-       {0xa014, 0x0, 0x2, 0x2},
-       {0xa366, 0x0, 0x1, 0x1},
-       {0xa2bc, 0x3, 0x1, 0x0},
-       {0xa2bd, 0x0, 0x8, 0xa},
-       {0xa2be, 0x0, 0x8, 0x14},
-       {0xa2bf, 0x0, 0x8, 0x8},
-       {0xa60a, 0x0, 0x8, 0xbd},
-       {0xa60e, 0x4, 0x2, 0x2},
-       {0xa60b, 0x0, 0x8, 0x86},
-       {0xa60e, 0x6, 0x2, 0x3},
-       {0xa001, 0x2, 0x2, 0x1},
-       {0xa1c7, 0x0, 0x8, 0xf5},
-       {0xa03d, 0x0, 0x8, 0xb1},
-       {0xa616, 0x0, 0x8, 0xff},
-       {0xa617, 0x0, 0x8, 0xad},
-       {0xa618, 0x0, 0x8, 0xad},
-       {0xa61e, 0x3, 0x1, 0x1},
-       {0xae1a, 0x0, 0x8, 0x0},
-       {0xae19, 0x0, 0x8, 0xc8},
-       {0xae18, 0x0, 0x8, 0x61},
-       {0xa140, 0x0, 0x8, 0x0},
-       {0xa141, 0x0, 0x8, 0xc8},
-       {0xa142, 0x0, 0x7, 0x61},
-       {0xa023, 0x0, 0x8, 0xff},
-       {0xa021, 0x0, 0x8, 0xad},
-       {0xa026, 0x0, 0x1, 0x0},
-       {0xa024, 0x0, 0x8, 0xff},
-       {0xa025, 0x0, 0x8, 0xff},
-       {0xa1c8, 0x0, 0x8, 0xf},
-       {0xa2bc, 0x1, 0x1, 0x0},
-       {0xa60c, 0x0, 0x4, 0x5},
-       {0xa60c, 0x4, 0x4, 0x6},
-       {0xa60d, 0x0, 0x8, 0xa},
-       {0xa371, 0x0, 0x1, 0x1},
-       {0xa366, 0x1, 0x3, 0x7},
-       {0xa338, 0x0, 0x8, 0x10},
-       {0xa339, 0x0, 0x6, 0x7},
-       {0xa33a, 0x0, 0x6, 0x1f},
-       {0xa33b, 0x0, 0x8, 0xf6},
-       {0xa33c, 0x3, 0x5, 0x4},
-       {0xa33d, 0x4, 0x4, 0x0},
-       {0xa33d, 0x1, 0x1, 0x1},
-       {0xa33d, 0x2, 0x1, 0x1},
-       {0xa33d, 0x3, 0x1, 0x1},
-       {0xa16d, 0x0, 0x4, 0xf},
-       {0xa161, 0x0, 0x5, 0x5},
-       {0xa162, 0x0, 0x4, 0x5},
-       {0xa165, 0x0, 0x8, 0xff},
-       {0xa166, 0x0, 0x8, 0x9c},
-       {0xa2c3, 0x0, 0x4, 0x5},
-       {0xa61a, 0x0, 0x6, 0xf},
-       {0xb200, 0x0, 0x8, 0xa1},
-       {0xb201, 0x0, 0x8, 0x7},
-       {0xa093, 0x0, 0x1, 0x0},
-       {0xa093, 0x1, 0x5, 0xf},
-       {0xa094, 0x0, 0x8, 0xff},
-       {0xa095, 0x0, 0x8, 0xf},
-       {0xa080, 0x2, 0x5, 0x3},
-       {0xa081, 0x0, 0x4, 0x0},
-       {0xa081, 0x4, 0x4, 0x9},
-       {0xa082, 0x0, 0x5, 0x1f},
-       {0xa08d, 0x0, 0x8, 0x1},
-       {0xa083, 0x0, 0x8, 0x32},
-       {0xa084, 0x0, 0x1, 0x0},
-       {0xa08e, 0x0, 0x8, 0x3},
-       {0xa085, 0x0, 0x8, 0x32},
-       {0xa086, 0x0, 0x3, 0x0},
-       {0xa087, 0x0, 0x8, 0x6e},
-       {0xa088, 0x0, 0x5, 0x15},
-       {0xa089, 0x0, 0x8, 0x0},
-       {0xa08a, 0x0, 0x5, 0x19},
-       {0xa08b, 0x0, 0x8, 0x92},
-       {0xa08c, 0x0, 0x5, 0x1c},
-       {0xa120, 0x0, 0x8, 0x0},
-       {0xa121, 0x0, 0x5, 0x10},
-       {0xa122, 0x0, 0x8, 0x0},
-       {0xa123, 0x0, 0x7, 0x40},
-       {0xa123, 0x7, 0x1, 0x0},
-       {0xa124, 0x0, 0x8, 0x13},
-       {0xa125, 0x0, 0x7, 0x10},
-       {0xa1c0, 0x0, 0x8, 0x0},
-       {0xa1c1, 0x0, 0x5, 0x4},
-       {0xa1c2, 0x0, 0x8, 0x0},
-       {0xa1c3, 0x0, 0x5, 0x10},
-       {0xa1c3, 0x5, 0x3, 0x0},
-       {0xa1c4, 0x0, 0x6, 0x0},
-       {0xa1c5, 0x0, 0x7, 0x10},
-       {0xa100, 0x0, 0x8, 0x0},
-       {0xa101, 0x0, 0x5, 0x10},
-       {0xa102, 0x0, 0x8, 0x0},
-       {0xa103, 0x0, 0x7, 0x40},
-       {0xa103, 0x7, 0x1, 0x0},
-       {0xa104, 0x0, 0x8, 0x18},
-       {0xa105, 0x0, 0x7, 0xa},
-       {0xa106, 0x0, 0x8, 0x20},
-       {0xa107, 0x0, 0x8, 0x40},
-       {0xa108, 0x0, 0x4, 0x0},
-       {0xa38c, 0x0, 0x8, 0xfc},
-       {0xa38d, 0x0, 0x8, 0x0},
-       {0xa38e, 0x0, 0x8, 0x7e},
-       {0xa38f, 0x0, 0x8, 0x0},
-       {0xa390, 0x0, 0x8, 0x2f},
-       {0xa60f, 0x5, 0x1, 0x1},
-       {0xa170, 0x0, 0x8, 0xdc},
-       {0xa171, 0x0, 0x2, 0x0},
-       {0xa2ae, 0x0, 0x1, 0x1},
-       {0xa2ae, 0x1, 0x1, 0x1},
-       {0xa392, 0x0, 0x1, 0x1},
-       {0xa391, 0x2, 0x1, 0x0},
-       {0xabc1, 0x0, 0x8, 0xff},
-       {0xabc2, 0x0, 0x8, 0x0},
-       {0xabc8, 0x0, 0x8, 0x8},
-       {0xabca, 0x0, 0x8, 0x10},
-       {0xabcb, 0x0, 0x1, 0x0},
-       {0xabc3, 0x5, 0x3, 0x7},
-       {0xabc0, 0x6, 0x1, 0x0},
-       {0xabc0, 0x4, 0x2, 0x0},
-       {0xa344, 0x4, 0x4, 0x1},
-       {0xabc0, 0x7, 0x1, 0x1},
-       {0xabc0, 0x2, 0x1, 0x1},
-       {0xa345, 0x0, 0x8, 0x66},
-       {0xa346, 0x0, 0x8, 0x66},
-       {0xa347, 0x0, 0x4, 0x0},
-       {0xa343, 0x0, 0x4, 0xa},
-       {0xa347, 0x4, 0x4, 0x2},
-       {0xa348, 0x0, 0x4, 0xc},
-       {0xa348, 0x4, 0x4, 0x7},
-       {0xa349, 0x0, 0x6, 0x2},
-};
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
deleted file mode 100644 (file)
index af176b6..0000000
+++ /dev/null
@@ -1,1117 +0,0 @@
-/* DVB USB compliant Linux driver for the Afatech 9005
- * USB1.1 DVB-T receiver.
- *
- * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
- *
- * Thanks to Afatech who kindly provided information.
- *
- * 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.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "af9005.h"
-
-/* debug */
-int dvb_usb_af9005_debug;
-module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
-MODULE_PARM_DESC(debug,
-                "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
-                DVB_USB_DEBUG_STATUS);
-/* enable obnoxious led */
-bool dvb_usb_af9005_led = 1;
-module_param_named(led, dvb_usb_af9005_led, bool, 0644);
-MODULE_PARM_DESC(led, "enable led (default: 1).");
-
-/* eeprom dump */
-static int dvb_usb_af9005_dump_eeprom;
-module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
-MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* remote control decoder */
-static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
-               u32 *event, int *state);
-static void *rc_keys;
-static int *rc_keys_size;
-
-u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
-
-struct af9005_device_state {
-       u8 sequence;
-       int led_state;
-};
-
-static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
-                             int readwrite, int type, u8 * values, int len)
-{
-       struct af9005_device_state *st = d->priv;
-       u8 obuf[16] = { 0 };
-       u8 ibuf[17] = { 0 };
-       u8 command;
-       int i;
-       int ret;
-
-       if (len < 1) {
-               err("generic read/write, less than 1 byte. Makes no sense.");
-               return -EINVAL;
-       }
-       if (len > 8) {
-               err("generic read/write, more than 8 bytes. Not supported.");
-               return -EINVAL;
-       }
-
-       obuf[0] = 14;           /* rest of buffer length low */
-       obuf[1] = 0;            /* rest of buffer length high */
-
-       obuf[2] = AF9005_REGISTER_RW;   /* register operation */
-       obuf[3] = 12;           /* rest of buffer length */
-
-       obuf[4] = st->sequence++;       /* sequence number */
-
-       obuf[5] = (u8) (reg >> 8);      /* register address */
-       obuf[6] = (u8) (reg & 0xff);
-
-       if (type == AF9005_OFDM_REG) {
-               command = AF9005_CMD_OFDM_REG;
-       } else {
-               command = AF9005_CMD_TUNER;
-       }
-
-       if (len > 1)
-               command |=
-                   AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
-       command |= readwrite;
-       if (readwrite == AF9005_CMD_WRITE)
-               for (i = 0; i < len; i++)
-                       obuf[8 + i] = values[i];
-       else if (type == AF9005_TUNER_REG)
-               /* read command for tuner, the first byte contains the i2c address */
-               obuf[8] = values[0];
-       obuf[7] = command;
-
-       ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
-       if (ret)
-               return ret;
-
-       /* sanity check */
-       if (ibuf[2] != AF9005_REGISTER_RW_ACK) {
-               err("generic read/write, wrong reply code.");
-               return -EIO;
-       }
-       if (ibuf[3] != 0x0d) {
-               err("generic read/write, wrong length in reply.");
-               return -EIO;
-       }
-       if (ibuf[4] != obuf[4]) {
-               err("generic read/write, wrong sequence in reply.");
-               return -EIO;
-       }
-       /*
-          Windows driver doesn't check these fields, in fact sometimes
-          the register in the reply is different that what has been sent
-
-          if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {
-          err("generic read/write, wrong register in reply.");
-          return -EIO;
-          }
-          if (ibuf[7] != command) {
-          err("generic read/write wrong command in reply.");
-          return -EIO;
-          }
-        */
-       if (ibuf[16] != 0x01) {
-               err("generic read/write wrong status code in reply.");
-               return -EIO;
-       }
-       if (readwrite == AF9005_CMD_READ)
-               for (i = 0; i < len; i++)
-                       values[i] = ibuf[8 + i];
-
-       return 0;
-
-}
-
-int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
-{
-       int ret;
-       deb_reg("read register %x ", reg);
-       ret = af9005_generic_read_write(d, reg,
-                                       AF9005_CMD_READ, AF9005_OFDM_REG,
-                                       value, 1);
-       if (ret)
-               deb_reg("failed\n");
-       else
-               deb_reg("value %x\n", *value);
-       return ret;
-}
-
-int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
-                              u8 * values, int len)
-{
-       int ret;
-       deb_reg("read %d registers %x ", len, reg);
-       ret = af9005_generic_read_write(d, reg,
-                                       AF9005_CMD_READ, AF9005_OFDM_REG,
-                                       values, len);
-       if (ret)
-               deb_reg("failed\n");
-       else
-               debug_dump(values, len, deb_reg);
-       return ret;
-}
-
-int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
-{
-       int ret;
-       u8 temp = value;
-       deb_reg("write register %x value %x ", reg, value);
-       ret = af9005_generic_read_write(d, reg,
-                                       AF9005_CMD_WRITE, AF9005_OFDM_REG,
-                                       &temp, 1);
-       if (ret)
-               deb_reg("failed\n");
-       else
-               deb_reg("ok\n");
-       return ret;
-}
-
-int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
-                               u8 * values, int len)
-{
-       int ret;
-       deb_reg("write %d registers %x values ", len, reg);
-       debug_dump(values, len, deb_reg);
-
-       ret = af9005_generic_read_write(d, reg,
-                                       AF9005_CMD_WRITE, AF9005_OFDM_REG,
-                                       values, len);
-       if (ret)
-               deb_reg("failed\n");
-       else
-               deb_reg("ok\n");
-       return ret;
-}
-
-int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
-                             u8 len, u8 * value)
-{
-       u8 temp;
-       int ret;
-       deb_reg("read bits %x %x %x", reg, pos, len);
-       ret = af9005_read_ofdm_register(d, reg, &temp);
-       if (ret) {
-               deb_reg(" failed\n");
-               return ret;
-       }
-       *value = (temp >> pos) & regmask[len - 1];
-       deb_reg(" value %x\n", *value);
-       return 0;
-
-}
-
-int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
-                              u8 len, u8 value)
-{
-       u8 temp, mask;
-       int ret;
-       deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
-       if (pos == 0 && len == 8)
-               return af9005_write_ofdm_register(d, reg, value);
-       ret = af9005_read_ofdm_register(d, reg, &temp);
-       if (ret)
-               return ret;
-       mask = regmask[len - 1] << pos;
-       temp = (temp & ~mask) | ((value << pos) & mask);
-       return af9005_write_ofdm_register(d, reg, temp);
-
-}
-
-static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
-                                          u16 reg, u8 * values, int len)
-{
-       return af9005_generic_read_write(d, reg,
-                                        AF9005_CMD_READ, AF9005_TUNER_REG,
-                                        values, len);
-}
-
-static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
-                                           u16 reg, u8 * values, int len)
-{
-       return af9005_generic_read_write(d, reg,
-                                        AF9005_CMD_WRITE,
-                                        AF9005_TUNER_REG, values, len);
-}
-
-int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
-                                u8 * values, int len)
-{
-       /* don't let the name of this function mislead you: it's just used
-          as an interface from the firmware to the i2c bus. The actual
-          i2c addresses are contained in the data */
-       int ret, i, done = 0, fail = 0;
-       u8 temp;
-       ret = af9005_usb_write_tuner_registers(d, reg, values, len);
-       if (ret)
-               return ret;
-       if (reg != 0xffff) {
-               /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
-               for (i = 0; i < 200; i++) {
-                       ret =
-                           af9005_read_ofdm_register(d,
-                                                     xd_I2C_i2c_m_status_wdat_done,
-                                                     &temp);
-                       if (ret)
-                               return ret;
-                       done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
-                                      << i2c_m_status_wdat_done_pos);
-                       if (done)
-                               break;
-                       fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
-                                      << i2c_m_status_wdat_fail_pos);
-                       if (fail)
-                               break;
-                       msleep(50);
-               }
-               if (i == 200)
-                       return -ETIMEDOUT;
-               if (fail) {
-                       /* clear write fail bit */
-                       af9005_write_register_bits(d,
-                                                  xd_I2C_i2c_m_status_wdat_fail,
-                                                  i2c_m_status_wdat_fail_pos,
-                                                  i2c_m_status_wdat_fail_len,
-                                                  1);
-                       return -EIO;
-               }
-               /* clear write done bit */
-               ret =
-                   af9005_write_register_bits(d,
-                                              xd_I2C_i2c_m_status_wdat_fail,
-                                              i2c_m_status_wdat_done_pos,
-                                              i2c_m_status_wdat_done_len, 1);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
-                               u8 * values, int len)
-{
-       /* don't let the name of this function mislead you: it's just used
-          as an interface from the firmware to the i2c bus. The actual
-          i2c addresses are contained in the data */
-       int ret, i;
-       u8 temp, buf[2];
-
-       buf[0] = addr;          /* tuner i2c address */
-       buf[1] = values[0];     /* tuner register */
-
-       values[0] = addr + 0x01;        /* i2c read address */
-
-       if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
-               /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
-               ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
-               if (ret)
-                       return ret;
-       }
-
-       /* send read command to ofsm */
-       ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
-       if (ret)
-               return ret;
-
-       /* check if read done */
-       for (i = 0; i < 200; i++) {
-               ret = af9005_read_ofdm_register(d, 0xa408, &temp);
-               if (ret)
-                       return ret;
-               if (temp & 0x01)
-                       break;
-               msleep(50);
-       }
-       if (i == 200)
-               return -ETIMEDOUT;
-
-       /* clear read done bit (by writing 1) */
-       ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
-       if (ret)
-               return ret;
-
-       /* get read data (available from 0xa400) */
-       for (i = 0; i < len; i++) {
-               ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
-               if (ret)
-                       return ret;
-               values[i] = temp;
-       }
-       return 0;
-}
-
-static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
-                           u8 * data, int len)
-{
-       int ret, i;
-       u8 buf[3];
-       deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
-               reg, len);
-       debug_dump(data, len, deb_i2c);
-
-       for (i = 0; i < len; i++) {
-               buf[0] = i2caddr;
-               buf[1] = reg + (u8) i;
-               buf[2] = data[i];
-               ret =
-                   af9005_write_tuner_registers(d,
-                                                APO_REG_I2C_RW_SILICON_TUNER,
-                                                buf, 3);
-               if (ret) {
-                       deb_i2c("i2c_write failed\n");
-                       return ret;
-               }
-       }
-       deb_i2c("i2c_write ok\n");
-       return 0;
-}
-
-static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
-                          u8 * data, int len)
-{
-       int ret, i;
-       u8 temp;
-       deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
-       for (i = 0; i < len; i++) {
-               temp = reg + i;
-               ret =
-                   af9005_read_tuner_registers(d,
-                                               APO_REG_I2C_RW_SILICON_TUNER,
-                                               i2caddr, &temp, 1);
-               if (ret) {
-                       deb_i2c("i2c_read failed\n");
-                       return ret;
-               }
-               data[i] = temp;
-       }
-       deb_i2c("i2c data read: ");
-       debug_dump(data, len, deb_i2c);
-       return 0;
-}
-
-static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                          int num)
-{
-       /* only implements what the mt2060 module does, don't know how
-          to make it really generic */
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int ret;
-       u8 reg, addr;
-       u8 *value;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       if (num > 2)
-               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
-       if (num == 2) {
-               /* reads a single register */
-               reg = *msg[0].buf;
-               addr = msg[0].addr;
-               value = msg[1].buf;
-               ret = af9005_i2c_read(d, addr, reg, value, 1);
-               if (ret == 0)
-                       ret = 2;
-       } else {
-               /* write one or more registers */
-               reg = msg[0].buf[0];
-               addr = msg[0].addr;
-               value = &msg[0].buf[1];
-               ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
-               if (ret == 0)
-                       ret = 1;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret;
-}
-
-static u32 af9005_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9005_i2c_algo = {
-       .master_xfer = af9005_i2c_xfer,
-       .functionality = af9005_i2c_func,
-};
-
-int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
-                       int wlen, u8 * rbuf, int rlen)
-{
-       struct af9005_device_state *st = d->priv;
-
-       int ret, i, packet_len;
-       u8 buf[64];
-       u8 ibuf[64];
-
-       if (wlen < 0) {
-               err("send command, wlen less than 0 bytes. Makes no sense.");
-               return -EINVAL;
-       }
-       if (wlen > 54) {
-               err("send command, wlen more than 54 bytes. Not supported.");
-               return -EINVAL;
-       }
-       if (rlen > 54) {
-               err("send command, rlen more than 54 bytes. Not supported.");
-               return -EINVAL;
-       }
-       packet_len = wlen + 5;
-       buf[0] = (u8) (packet_len & 0xff);
-       buf[1] = (u8) ((packet_len & 0xff00) >> 8);
-
-       buf[2] = 0x26;          /* packet type */
-       buf[3] = wlen + 3;
-       buf[4] = st->sequence++;
-       buf[5] = command;
-       buf[6] = wlen;
-       for (i = 0; i < wlen; i++)
-               buf[7 + i] = wbuf[i];
-       ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);
-       if (ret)
-               return ret;
-       if (ibuf[2] != 0x27) {
-               err("send command, wrong reply code.");
-               return -EIO;
-       }
-       if (ibuf[4] != buf[4]) {
-               err("send command, wrong sequence in reply.");
-               return -EIO;
-       }
-       if (ibuf[5] != 0x01) {
-               err("send command, wrong status code in reply.");
-               return -EIO;
-       }
-       if (ibuf[6] != rlen) {
-               err("send command, invalid data length in reply.");
-               return -EIO;
-       }
-       for (i = 0; i < rlen; i++)
-               rbuf[i] = ibuf[i + 7];
-       return 0;
-}
-
-int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
-                      int len)
-{
-       struct af9005_device_state *st = d->priv;
-       u8 obuf[16], ibuf[14];
-       int ret, i;
-
-       memset(obuf, 0, sizeof(obuf));
-       memset(ibuf, 0, sizeof(ibuf));
-
-       obuf[0] = 14;           /* length of rest of packet low */
-       obuf[1] = 0;            /* length of rest of packer high */
-
-       obuf[2] = 0x2a;         /* read/write eeprom */
-
-       obuf[3] = 12;           /* size */
-
-       obuf[4] = st->sequence++;
-
-       obuf[5] = 0;            /* read */
-
-       obuf[6] = len;
-       obuf[7] = address;
-       ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);
-       if (ret)
-               return ret;
-       if (ibuf[2] != 0x2b) {
-               err("Read eeprom, invalid reply code");
-               return -EIO;
-       }
-       if (ibuf[3] != 10) {
-               err("Read eeprom, invalid reply length");
-               return -EIO;
-       }
-       if (ibuf[4] != obuf[4]) {
-               err("Read eeprom, wrong sequence in reply ");
-               return -EIO;
-       }
-       if (ibuf[5] != 1) {
-               err("Read eeprom, wrong status in reply ");
-               return -EIO;
-       }
-       for (i = 0; i < len; i++) {
-               values[i] = ibuf[6 + i];
-       }
-       return 0;
-}
-
-static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
-{
-       u8 buf[FW_BULKOUT_SIZE + 2];
-       u16 checksum;
-       int act_len, i, ret;
-       memset(buf, 0, sizeof(buf));
-       buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
-       buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
-       switch (type) {
-       case FW_CONFIG:
-               buf[2] = 0x11;
-               buf[3] = 0x04;
-               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
-               buf[5] = 0x03;
-               checksum = buf[4] + buf[5];
-               buf[6] = (u8) ((checksum >> 8) & 0xff);
-               buf[7] = (u8) (checksum & 0xff);
-               break;
-       case FW_CONFIRM:
-               buf[2] = 0x11;
-               buf[3] = 0x04;
-               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
-               buf[5] = 0x01;
-               checksum = buf[4] + buf[5];
-               buf[6] = (u8) ((checksum >> 8) & 0xff);
-               buf[7] = (u8) (checksum & 0xff);
-               break;
-       case FW_BOOT:
-               buf[2] = 0x10;
-               buf[3] = 0x08;
-               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
-               buf[5] = 0x97;
-               buf[6] = 0xaa;
-               buf[7] = 0x55;
-               buf[8] = 0xa5;
-               buf[9] = 0x5a;
-               checksum = 0;
-               for (i = 4; i <= 9; i++)
-                       checksum += buf[i];
-               buf[10] = (u8) ((checksum >> 8) & 0xff);
-               buf[11] = (u8) (checksum & 0xff);
-               break;
-       default:
-               err("boot packet invalid boot packet type");
-               return -EINVAL;
-       }
-       deb_fw(">>> ");
-       debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
-
-       ret = usb_bulk_msg(udev,
-                          usb_sndbulkpipe(udev, 0x02),
-                          buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
-       if (ret)
-               err("boot packet bulk message failed: %d (%d/%d)", ret,
-                   FW_BULKOUT_SIZE + 2, act_len);
-       else
-               ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
-       if (ret)
-               return ret;
-       memset(buf, 0, 9);
-       ret = usb_bulk_msg(udev,
-                          usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
-       if (ret) {
-               err("boot packet recv bulk message failed: %d", ret);
-               return ret;
-       }
-       deb_fw("<<< ");
-       debug_dump(buf, act_len, deb_fw);
-       checksum = 0;
-       switch (type) {
-       case FW_CONFIG:
-               if (buf[2] != 0x11) {
-                       err("boot bad config header.");
-                       return -EIO;
-               }
-               if (buf[3] != 0x05) {
-                       err("boot bad config size.");
-                       return -EIO;
-               }
-               if (buf[4] != 0x00) {
-                       err("boot bad config sequence.");
-                       return -EIO;
-               }
-               if (buf[5] != 0x04) {
-                       err("boot bad config subtype.");
-                       return -EIO;
-               }
-               for (i = 4; i <= 6; i++)
-                       checksum += buf[i];
-               if (buf[7] * 256 + buf[8] != checksum) {
-                       err("boot bad config checksum.");
-                       return -EIO;
-               }
-               *reply = buf[6];
-               break;
-       case FW_CONFIRM:
-               if (buf[2] != 0x11) {
-                       err("boot bad confirm header.");
-                       return -EIO;
-               }
-               if (buf[3] != 0x05) {
-                       err("boot bad confirm size.");
-                       return -EIO;
-               }
-               if (buf[4] != 0x00) {
-                       err("boot bad confirm sequence.");
-                       return -EIO;
-               }
-               if (buf[5] != 0x02) {
-                       err("boot bad confirm subtype.");
-                       return -EIO;
-               }
-               for (i = 4; i <= 6; i++)
-                       checksum += buf[i];
-               if (buf[7] * 256 + buf[8] != checksum) {
-                       err("boot bad confirm checksum.");
-                       return -EIO;
-               }
-               *reply = buf[6];
-               break;
-       case FW_BOOT:
-               if (buf[2] != 0x10) {
-                       err("boot bad boot header.");
-                       return -EIO;
-               }
-               if (buf[3] != 0x05) {
-                       err("boot bad boot size.");
-                       return -EIO;
-               }
-               if (buf[4] != 0x00) {
-                       err("boot bad boot sequence.");
-                       return -EIO;
-               }
-               if (buf[5] != 0x01) {
-                       err("boot bad boot pattern 01.");
-                       return -EIO;
-               }
-               if (buf[6] != 0x10) {
-                       err("boot bad boot pattern 10.");
-                       return -EIO;
-               }
-               for (i = 4; i <= 6; i++)
-                       checksum += buf[i];
-               if (buf[7] * 256 + buf[8] != checksum) {
-                       err("boot bad boot checksum.");
-                       return -EIO;
-               }
-               break;
-
-       }
-
-       return 0;
-}
-
-static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
-{
-       int i, packets, ret, act_len;
-
-       u8 buf[FW_BULKOUT_SIZE + 2];
-       u8 reply;
-
-       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
-       if (ret)
-               return ret;
-       if (reply != 0x01) {
-               err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
-               return -EIO;
-       }
-       packets = fw->size / FW_BULKOUT_SIZE;
-       buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
-       buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
-       for (i = 0; i < packets; i++) {
-               memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
-                      FW_BULKOUT_SIZE);
-               deb_fw(">>> ");
-               debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
-               ret = usb_bulk_msg(udev,
-                                  usb_sndbulkpipe(udev, 0x02),
-                                  buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
-               if (ret) {
-                       err("firmware download failed at packet %d with code %d", i, ret);
-                       return ret;
-               }
-       }
-       ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);
-       if (ret)
-               return ret;
-       if (reply != (u8) (packets & 0xff)) {
-               err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
-               return -EIO;
-       }
-       ret = af9005_boot_packet(udev, FW_BOOT, &reply);
-       if (ret)
-               return ret;
-       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
-       if (ret)
-               return ret;
-       if (reply != 0x02) {
-               err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
-               return -EIO;
-       }
-
-       return 0;
-
-}
-
-int af9005_led_control(struct dvb_usb_device *d, int onoff)
-{
-       struct af9005_device_state *st = d->priv;
-       int temp, ret;
-
-       if (onoff && dvb_usb_af9005_led)
-               temp = 1;
-       else
-               temp = 0;
-       if (st->led_state != temp) {
-               ret =
-                   af9005_write_register_bits(d, xd_p_reg_top_locken1,
-                                              reg_top_locken1_pos,
-                                              reg_top_locken1_len, temp);
-               if (ret)
-                       return ret;
-               ret =
-                   af9005_write_register_bits(d, xd_p_reg_top_lock1,
-                                              reg_top_lock1_pos,
-                                              reg_top_lock1_len, temp);
-               if (ret)
-                       return ret;
-               st->led_state = temp;
-       }
-       return 0;
-}
-
-static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       u8 buf[8];
-       int i;
-
-       /* without these calls the first commands after downloading
-          the firmware fail. I put these calls here to simulate
-          what it is done in dvb-usb-init.c.
-        */
-       struct usb_device *udev = adap->dev->udev;
-       usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
-       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
-       if (dvb_usb_af9005_dump_eeprom) {
-               printk("EEPROM DUMP\n");
-               for (i = 0; i < 255; i += 8) {
-                       af9005_read_eeprom(adap->dev, i, buf, 8);
-                       printk("ADDR %x ", i);
-                       debug_dump(buf, 8, printk);
-               }
-       }
-       adap->fe_adap[0].fe = af9005_fe_attach(adap->dev);
-       return 0;
-}
-
-static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
-{
-       struct af9005_device_state *st = d->priv;
-       int ret, len;
-
-       u8 obuf[5];
-       u8 ibuf[256];
-
-       *state = REMOTE_NO_KEY_PRESSED;
-       if (rc_decode == NULL) {
-               /* it shouldn't never come here */
-               return 0;
-       }
-       /* deb_info("rc_query\n"); */
-       obuf[0] = 3;            /* rest of packet length low */
-       obuf[1] = 0;            /* rest of packet lentgh high */
-       obuf[2] = 0x40;         /* read remote */
-       obuf[3] = 1;            /* rest of packet length */
-       obuf[4] = st->sequence++;       /* sequence number */
-       ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);
-       if (ret) {
-               err("rc query failed");
-               return ret;
-       }
-       if (ibuf[2] != 0x41) {
-               err("rc query bad header.");
-               return -EIO;
-       }
-       if (ibuf[4] != obuf[4]) {
-               err("rc query bad sequence.");
-               return -EIO;
-       }
-       len = ibuf[5];
-       if (len > 246) {
-               err("rc query invalid length");
-               return -EIO;
-       }
-       if (len > 0) {
-               deb_rc("rc data (%d) ", len);
-               debug_dump((ibuf + 6), len, deb_rc);
-               ret = rc_decode(d, &ibuf[6], len, event, state);
-               if (ret) {
-                       err("rc_decode failed");
-                       return ret;
-               } else {
-                       deb_rc("rc_decode state %x event %x\n", *state, *event);
-                       if (*state == REMOTE_KEY_REPEAT)
-                               *event = d->last_event;
-               }
-       }
-       return 0;
-}
-
-static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-
-       return 0;
-}
-
-static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-       deb_info("pid filter control  onoff %d\n", onoff);
-       if (onoff) {
-               ret =
-                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
-               if (ret)
-                       return ret;
-               ret =
-                   af9005_write_register_bits(adap->dev,
-                                              XD_MP2IF_DMX_CTRL, 1, 1, 1);
-               if (ret)
-                       return ret;
-               ret =
-                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
-       } else
-               ret =
-                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
-       if (ret)
-               return ret;
-       deb_info("pid filter control ok\n");
-       return 0;
-}
-
-static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
-                            u16 pid, int onoff)
-{
-       u8 cmd = index & 0x1f;
-       int ret;
-       deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
-                pid, onoff);
-       if (onoff) {
-               /* cannot use it as pid_filter_ctrl since it has to be done
-                  before setting the first pid */
-               if (adap->feedcount == 1) {
-                       deb_info("first pid set, enable pid table\n");
-                       ret = af9005_pid_filter_control(adap, onoff);
-                       if (ret)
-                               return ret;
-               }
-               ret =
-                   af9005_write_ofdm_register(adap->dev,
-                                              XD_MP2IF_PID_DATA_L,
-                                              (u8) (pid & 0xff));
-               if (ret)
-                       return ret;
-               ret =
-                   af9005_write_ofdm_register(adap->dev,
-                                              XD_MP2IF_PID_DATA_H,
-                                              (u8) (pid >> 8));
-               if (ret)
-                       return ret;
-               cmd |= 0x20 | 0x40;
-       } else {
-               if (adap->feedcount == 0) {
-                       deb_info("last pid unset, disable pid table\n");
-                       ret = af9005_pid_filter_control(adap, onoff);
-                       if (ret)
-                               return ret;
-               }
-       }
-       ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
-       if (ret)
-               return ret;
-       deb_info("set pid ok\n");
-       return 0;
-}
-
-static int af9005_identify_state(struct usb_device *udev,
-                                struct dvb_usb_device_properties *props,
-                                struct dvb_usb_device_description **desc,
-                                int *cold)
-{
-       int ret;
-       u8 reply;
-       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
-       if (ret)
-               return ret;
-       deb_info("result of FW_CONFIG in identify state %d\n", reply);
-       if (reply == 0x01)
-               *cold = 1;
-       else if (reply == 0x02)
-               *cold = 0;
-       else
-               return -EIO;
-       deb_info("Identify state cold = %d\n", *cold);
-       return 0;
-}
-
-static struct dvb_usb_device_properties af9005_properties;
-
-static int af9005_usb_probe(struct usb_interface *intf,
-                           const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &af9005_properties,
-                                  THIS_MODULE, NULL, adapter_nr);
-}
-
-enum af9005_usb_table_entry {
-       AFATECH_AF9005,
-       TERRATEC_AF9005,
-       ANSONIC_AF9005,
-};
-
-static struct usb_device_id af9005_usb_table[] = {
-       [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
-                               USB_PID_AFATECH_AF9005)},
-       [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
-                               USB_PID_TERRATEC_CINERGY_T_USB_XE)},
-       [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
-                               USB_PID_ANSONIC_DVBT_USB)},
-       { }
-};
-
-MODULE_DEVICE_TABLE(usb, af9005_usb_table);
-
-static struct dvb_usb_device_properties af9005_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "af9005.fw",
-       .download_firmware = af9005_download_firmware,
-       .no_reconnect = 1,
-
-       .size_of_priv = sizeof(struct af9005_device_state),
-
-       .num_adapters = 1,
-       .adapter = {
-                   {
-                   .num_frontends = 1,
-                   .fe = {{
-                    .caps =
-                    DVB_USB_ADAP_HAS_PID_FILTER |
-                    DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                    .pid_filter_count = 32,
-                    .pid_filter = af9005_pid_filter,
-                    /* .pid_filter_ctrl = af9005_pid_filter_control, */
-                    .frontend_attach = af9005_frontend_attach,
-                    /* .tuner_attach     = af9005_tuner_attach, */
-                    /* parameter for the MPEG2-data transfer */
-                    .stream = {
-                               .type = USB_BULK,
-                               .count = 10,
-                               .endpoint = 0x04,
-                               .u = {
-                                     .bulk = {
-                                              .buffersize = 4096,      /* actual size seen is 3948 */
-                                              }
-                                     }
-                               },
-                    }},
-                    }
-                   },
-       .power_ctrl = af9005_power_ctrl,
-       .identify_state = af9005_identify_state,
-
-       .i2c_algo = &af9005_i2c_algo,
-
-       .rc.legacy = {
-               .rc_interval = 200,
-               .rc_map_table = NULL,
-               .rc_map_size = 0,
-               .rc_query = af9005_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint          = 2,
-       .generic_bulk_ctrl_endpoint_response = 1,
-
-       .num_device_descs = 3,
-       .devices = {
-                   {.name = "Afatech DVB-T USB1.1 stick",
-                    .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
-                    .warm_ids = {NULL},
-                    },
-                   {.name = "TerraTec Cinergy T USB XE",
-                    .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
-                    .warm_ids = {NULL},
-                    },
-                   {.name = "Ansonic DVB-T USB1.1 stick",
-                    .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
-                    .warm_ids = {NULL},
-                    },
-                   {NULL},
-                   }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver af9005_usb_driver = {
-       .name = "dvb_usb_af9005",
-       .probe = af9005_usb_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table = af9005_usb_table,
-};
-
-/* module stuff */
-static int __init af9005_usb_module_init(void)
-{
-       int result;
-       if ((result = usb_register(&af9005_usb_driver))) {
-               err("usb_register failed. (%d)", result);
-               return result;
-       }
-       rc_decode = symbol_request(af9005_rc_decode);
-       rc_keys = symbol_request(rc_map_af9005_table);
-       rc_keys_size = symbol_request(rc_map_af9005_table_size);
-       if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
-               err("af9005_rc_decode function not found, disabling remote");
-               af9005_properties.rc.legacy.rc_query = NULL;
-       } else {
-               af9005_properties.rc.legacy.rc_map_table = rc_keys;
-               af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
-       }
-
-       return 0;
-}
-
-static void __exit af9005_usb_module_exit(void)
-{
-       /* release rc decode symbols */
-       if (rc_decode != NULL)
-               symbol_put(af9005_rc_decode);
-       if (rc_keys != NULL)
-               symbol_put(rc_map_af9005_table);
-       if (rc_keys_size != NULL)
-               symbol_put(rc_map_af9005_table_size);
-       /* deregister this driver from the USB subsystem */
-       usb_deregister(&af9005_usb_driver);
-}
-
-module_init(af9005_usb_module_init);
-module_exit(af9005_usb_module_exit);
-
-MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
-MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
deleted file mode 100644 (file)
index 6a2bf3d..0000000
+++ /dev/null
@@ -1,3496 +0,0 @@
-/* Common header-file of the Linux driver for the Afatech 9005
- * USB1.1 DVB-T receiver.
- *
- * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
- *
- * Thanks to Afatech who kindly provided information.
- *
- * 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.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_AF9005_H_
-#define _DVB_USB_AF9005_H_
-
-#define DVB_USB_LOG_PREFIX "af9005"
-#include "dvb-usb.h"
-
-extern int dvb_usb_af9005_debug;
-#define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args)
-#define deb_rc(args...)   dprintk(dvb_usb_af9005_debug,0x04,args)
-#define deb_reg(args...)  dprintk(dvb_usb_af9005_debug,0x08,args)
-#define deb_i2c(args...)  dprintk(dvb_usb_af9005_debug,0x10,args)
-#define deb_fw(args...)   dprintk(dvb_usb_af9005_debug,0x20,args)
-
-extern bool dvb_usb_af9005_led;
-
-/* firmware */
-#define FW_BULKOUT_SIZE 250
-enum {
-       FW_CONFIG,
-       FW_CONFIRM,
-       FW_BOOT
-};
-
-/* af9005 commands */
-#define AF9005_OFDM_REG  0
-#define AF9005_TUNER_REG 1
-
-#define AF9005_REGISTER_RW     0x20
-#define AF9005_REGISTER_RW_ACK 0x21
-
-#define AF9005_CMD_OFDM_REG 0x00
-#define AF9005_CMD_TUNER    0x80
-#define AF9005_CMD_BURST    0x02
-#define AF9005_CMD_AUTOINC  0x04
-#define AF9005_CMD_READ     0x00
-#define AF9005_CMD_WRITE    0x01
-
-/* af9005 registers */
-#define APO_REG_RESET                                  0xAEFF
-
-#define APO_REG_I2C_RW_CAN_TUNER            0xF000
-#define APO_REG_I2C_RW_SILICON_TUNER        0xF001
-#define APO_REG_GPIO_RW_SILICON_TUNER       0xFFFE     /*  also for OFSM */
-#define APO_REG_TRIGGER_OFSM                0xFFFF     /*  also for OFSM */
-
-/***********************************************************************
- *  Apollo Registers from VLSI                                        *
- ***********************************************************************/
-#define xd_p_reg_aagc_inverted_agc     0xA000
-#define        reg_aagc_inverted_agc_pos 0
-#define        reg_aagc_inverted_agc_len 1
-#define        reg_aagc_inverted_agc_lsb 0
-#define xd_p_reg_aagc_sign_only        0xA000
-#define        reg_aagc_sign_only_pos 1
-#define        reg_aagc_sign_only_len 1
-#define        reg_aagc_sign_only_lsb 0
-#define xd_p_reg_aagc_slow_adc_en      0xA000
-#define        reg_aagc_slow_adc_en_pos 2
-#define        reg_aagc_slow_adc_en_len 1
-#define        reg_aagc_slow_adc_en_lsb 0
-#define xd_p_reg_aagc_slow_adc_scale   0xA000
-#define        reg_aagc_slow_adc_scale_pos 3
-#define        reg_aagc_slow_adc_scale_len 5
-#define        reg_aagc_slow_adc_scale_lsb 0
-#define xd_p_reg_aagc_check_slow_adc_lock      0xA001
-#define        reg_aagc_check_slow_adc_lock_pos 0
-#define        reg_aagc_check_slow_adc_lock_len 1
-#define        reg_aagc_check_slow_adc_lock_lsb 0
-#define xd_p_reg_aagc_init_control     0xA001
-#define        reg_aagc_init_control_pos 1
-#define        reg_aagc_init_control_len 1
-#define        reg_aagc_init_control_lsb 0
-#define xd_p_reg_aagc_total_gain_sel   0xA001
-#define        reg_aagc_total_gain_sel_pos 2
-#define        reg_aagc_total_gain_sel_len 2
-#define        reg_aagc_total_gain_sel_lsb 0
-#define xd_p_reg_aagc_out_inv  0xA001
-#define        reg_aagc_out_inv_pos 5
-#define        reg_aagc_out_inv_len 1
-#define        reg_aagc_out_inv_lsb 0
-#define xd_p_reg_aagc_int_en   0xA001
-#define        reg_aagc_int_en_pos 6
-#define        reg_aagc_int_en_len 1
-#define        reg_aagc_int_en_lsb 0
-#define xd_p_reg_aagc_lock_change_flag 0xA001
-#define        reg_aagc_lock_change_flag_pos 7
-#define        reg_aagc_lock_change_flag_len 1
-#define        reg_aagc_lock_change_flag_lsb 0
-#define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002
-#define        reg_aagc_rf_loop_bw_scale_acquire_pos 0
-#define        reg_aagc_rf_loop_bw_scale_acquire_len 5
-#define        reg_aagc_rf_loop_bw_scale_acquire_lsb 0
-#define xd_p_reg_aagc_rf_loop_bw_scale_track   0xA003
-#define        reg_aagc_rf_loop_bw_scale_track_pos 0
-#define        reg_aagc_rf_loop_bw_scale_track_len 5
-#define        reg_aagc_rf_loop_bw_scale_track_lsb 0
-#define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004
-#define        reg_aagc_if_loop_bw_scale_acquire_pos 0
-#define        reg_aagc_if_loop_bw_scale_acquire_len 5
-#define        reg_aagc_if_loop_bw_scale_acquire_lsb 0
-#define xd_p_reg_aagc_if_loop_bw_scale_track   0xA005
-#define        reg_aagc_if_loop_bw_scale_track_pos 0
-#define        reg_aagc_if_loop_bw_scale_track_len 5
-#define        reg_aagc_if_loop_bw_scale_track_lsb 0
-#define xd_p_reg_aagc_max_rf_agc_7_0   0xA006
-#define        reg_aagc_max_rf_agc_7_0_pos 0
-#define        reg_aagc_max_rf_agc_7_0_len 8
-#define        reg_aagc_max_rf_agc_7_0_lsb 0
-#define xd_p_reg_aagc_max_rf_agc_9_8   0xA007
-#define        reg_aagc_max_rf_agc_9_8_pos 0
-#define        reg_aagc_max_rf_agc_9_8_len 2
-#define        reg_aagc_max_rf_agc_9_8_lsb 8
-#define xd_p_reg_aagc_min_rf_agc_7_0   0xA008
-#define        reg_aagc_min_rf_agc_7_0_pos 0
-#define        reg_aagc_min_rf_agc_7_0_len 8
-#define        reg_aagc_min_rf_agc_7_0_lsb 0
-#define xd_p_reg_aagc_min_rf_agc_9_8   0xA009
-#define        reg_aagc_min_rf_agc_9_8_pos 0
-#define        reg_aagc_min_rf_agc_9_8_len 2
-#define        reg_aagc_min_rf_agc_9_8_lsb 8
-#define xd_p_reg_aagc_max_if_agc_7_0   0xA00A
-#define        reg_aagc_max_if_agc_7_0_pos 0
-#define        reg_aagc_max_if_agc_7_0_len 8
-#define        reg_aagc_max_if_agc_7_0_lsb 0
-#define xd_p_reg_aagc_max_if_agc_9_8   0xA00B
-#define        reg_aagc_max_if_agc_9_8_pos 0
-#define        reg_aagc_max_if_agc_9_8_len 2
-#define        reg_aagc_max_if_agc_9_8_lsb 8
-#define xd_p_reg_aagc_min_if_agc_7_0   0xA00C
-#define        reg_aagc_min_if_agc_7_0_pos 0
-#define        reg_aagc_min_if_agc_7_0_len 8
-#define        reg_aagc_min_if_agc_7_0_lsb 0
-#define xd_p_reg_aagc_min_if_agc_9_8   0xA00D
-#define        reg_aagc_min_if_agc_9_8_pos 0
-#define        reg_aagc_min_if_agc_9_8_len 2
-#define        reg_aagc_min_if_agc_9_8_lsb 8
-#define xd_p_reg_aagc_lock_sample_scale        0xA00E
-#define        reg_aagc_lock_sample_scale_pos 0
-#define        reg_aagc_lock_sample_scale_len 5
-#define        reg_aagc_lock_sample_scale_lsb 0
-#define xd_p_reg_aagc_rf_agc_lock_scale_acquire        0xA00F
-#define        reg_aagc_rf_agc_lock_scale_acquire_pos 0
-#define        reg_aagc_rf_agc_lock_scale_acquire_len 3
-#define        reg_aagc_rf_agc_lock_scale_acquire_lsb 0
-#define xd_p_reg_aagc_rf_agc_lock_scale_track  0xA00F
-#define        reg_aagc_rf_agc_lock_scale_track_pos 3
-#define        reg_aagc_rf_agc_lock_scale_track_len 3
-#define        reg_aagc_rf_agc_lock_scale_track_lsb 0
-#define xd_p_reg_aagc_if_agc_lock_scale_acquire        0xA010
-#define        reg_aagc_if_agc_lock_scale_acquire_pos 0
-#define        reg_aagc_if_agc_lock_scale_acquire_len 3
-#define        reg_aagc_if_agc_lock_scale_acquire_lsb 0
-#define xd_p_reg_aagc_if_agc_lock_scale_track  0xA010
-#define        reg_aagc_if_agc_lock_scale_track_pos 3
-#define        reg_aagc_if_agc_lock_scale_track_len 3
-#define        reg_aagc_if_agc_lock_scale_track_lsb 0
-#define xd_p_reg_aagc_rf_top_numerator_7_0     0xA011
-#define        reg_aagc_rf_top_numerator_7_0_pos 0
-#define        reg_aagc_rf_top_numerator_7_0_len 8
-#define        reg_aagc_rf_top_numerator_7_0_lsb 0
-#define xd_p_reg_aagc_rf_top_numerator_9_8     0xA012
-#define        reg_aagc_rf_top_numerator_9_8_pos 0
-#define        reg_aagc_rf_top_numerator_9_8_len 2
-#define        reg_aagc_rf_top_numerator_9_8_lsb 8
-#define xd_p_reg_aagc_if_top_numerator_7_0     0xA013
-#define        reg_aagc_if_top_numerator_7_0_pos 0
-#define        reg_aagc_if_top_numerator_7_0_len 8
-#define        reg_aagc_if_top_numerator_7_0_lsb 0
-#define xd_p_reg_aagc_if_top_numerator_9_8     0xA014
-#define        reg_aagc_if_top_numerator_9_8_pos 0
-#define        reg_aagc_if_top_numerator_9_8_len 2
-#define        reg_aagc_if_top_numerator_9_8_lsb 8
-#define xd_p_reg_aagc_adc_out_desired_7_0      0xA015
-#define        reg_aagc_adc_out_desired_7_0_pos 0
-#define        reg_aagc_adc_out_desired_7_0_len 8
-#define        reg_aagc_adc_out_desired_7_0_lsb 0
-#define xd_p_reg_aagc_adc_out_desired_8        0xA016
-#define        reg_aagc_adc_out_desired_8_pos 0
-#define        reg_aagc_adc_out_desired_8_len 1
-#define        reg_aagc_adc_out_desired_8_lsb 0
-#define xd_p_reg_aagc_fixed_gain       0xA016
-#define        reg_aagc_fixed_gain_pos 3
-#define        reg_aagc_fixed_gain_len 1
-#define        reg_aagc_fixed_gain_lsb 0
-#define xd_p_reg_aagc_lock_count_th    0xA016
-#define        reg_aagc_lock_count_th_pos 4
-#define        reg_aagc_lock_count_th_len 4
-#define        reg_aagc_lock_count_th_lsb 0
-#define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017
-#define        reg_aagc_fixed_rf_agc_control_7_0_pos 0
-#define        reg_aagc_fixed_rf_agc_control_7_0_len 8
-#define        reg_aagc_fixed_rf_agc_control_7_0_lsb 0
-#define xd_p_reg_aagc_fixed_rf_agc_control_15_8        0xA018
-#define        reg_aagc_fixed_rf_agc_control_15_8_pos 0
-#define        reg_aagc_fixed_rf_agc_control_15_8_len 8
-#define        reg_aagc_fixed_rf_agc_control_15_8_lsb 8
-#define xd_p_reg_aagc_fixed_rf_agc_control_23_16       0xA019
-#define        reg_aagc_fixed_rf_agc_control_23_16_pos 0
-#define        reg_aagc_fixed_rf_agc_control_23_16_len 8
-#define        reg_aagc_fixed_rf_agc_control_23_16_lsb 16
-#define xd_p_reg_aagc_fixed_rf_agc_control_30_24       0xA01A
-#define        reg_aagc_fixed_rf_agc_control_30_24_pos 0
-#define        reg_aagc_fixed_rf_agc_control_30_24_len 7
-#define        reg_aagc_fixed_rf_agc_control_30_24_lsb 24
-#define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B
-#define        reg_aagc_fixed_if_agc_control_7_0_pos 0
-#define        reg_aagc_fixed_if_agc_control_7_0_len 8
-#define        reg_aagc_fixed_if_agc_control_7_0_lsb 0
-#define xd_p_reg_aagc_fixed_if_agc_control_15_8        0xA01C
-#define        reg_aagc_fixed_if_agc_control_15_8_pos 0
-#define        reg_aagc_fixed_if_agc_control_15_8_len 8
-#define        reg_aagc_fixed_if_agc_control_15_8_lsb 8
-#define xd_p_reg_aagc_fixed_if_agc_control_23_16       0xA01D
-#define        reg_aagc_fixed_if_agc_control_23_16_pos 0
-#define        reg_aagc_fixed_if_agc_control_23_16_len 8
-#define        reg_aagc_fixed_if_agc_control_23_16_lsb 16
-#define xd_p_reg_aagc_fixed_if_agc_control_30_24       0xA01E
-#define        reg_aagc_fixed_if_agc_control_30_24_pos 0
-#define        reg_aagc_fixed_if_agc_control_30_24_len 7
-#define        reg_aagc_fixed_if_agc_control_30_24_lsb 24
-#define xd_p_reg_aagc_rf_agc_unlock_numerator  0xA01F
-#define        reg_aagc_rf_agc_unlock_numerator_pos 0
-#define        reg_aagc_rf_agc_unlock_numerator_len 6
-#define        reg_aagc_rf_agc_unlock_numerator_lsb 0
-#define xd_p_reg_aagc_if_agc_unlock_numerator  0xA020
-#define        reg_aagc_if_agc_unlock_numerator_pos 0
-#define        reg_aagc_if_agc_unlock_numerator_len 6
-#define        reg_aagc_if_agc_unlock_numerator_lsb 0
-#define xd_p_reg_unplug_th     0xA021
-#define        reg_unplug_th_pos 0
-#define        reg_unplug_th_len 8
-#define        reg_aagc_rf_x0_lsb 0
-#define xd_p_reg_weak_signal_rfagc_thr 0xA022
-#define        reg_weak_signal_rfagc_thr_pos 0
-#define        reg_weak_signal_rfagc_thr_len 8
-#define        reg_weak_signal_rfagc_thr_lsb 0
-#define xd_p_reg_unplug_rf_gain_th 0xA023
-#define        reg_unplug_rf_gain_th_pos 0
-#define        reg_unplug_rf_gain_th_len 8
-#define        reg_unplug_rf_gain_th_lsb 0
-#define xd_p_reg_unplug_dtop_rf_gain_th 0xA024
-#define        reg_unplug_dtop_rf_gain_th_pos 0
-#define        reg_unplug_dtop_rf_gain_th_len 8
-#define        reg_unplug_dtop_rf_gain_th_lsb 0
-#define xd_p_reg_unplug_dtop_if_gain_th 0xA025
-#define        reg_unplug_dtop_if_gain_th_pos 0
-#define        reg_unplug_dtop_if_gain_th_len 8
-#define        reg_unplug_dtop_if_gain_th_lsb 0
-#define xd_p_reg_top_recover_at_unplug_en 0xA026
-#define        reg_top_recover_at_unplug_en_pos 0
-#define        reg_top_recover_at_unplug_en_len 1
-#define        reg_top_recover_at_unplug_en_lsb 0
-#define xd_p_reg_aagc_rf_x6    0xA027
-#define        reg_aagc_rf_x6_pos 0
-#define        reg_aagc_rf_x6_len 8
-#define        reg_aagc_rf_x6_lsb 0
-#define xd_p_reg_aagc_rf_x7    0xA028
-#define        reg_aagc_rf_x7_pos 0
-#define        reg_aagc_rf_x7_len 8
-#define        reg_aagc_rf_x7_lsb 0
-#define xd_p_reg_aagc_rf_x8    0xA029
-#define        reg_aagc_rf_x8_pos 0
-#define        reg_aagc_rf_x8_len 8
-#define        reg_aagc_rf_x8_lsb 0
-#define xd_p_reg_aagc_rf_x9    0xA02A
-#define        reg_aagc_rf_x9_pos 0
-#define        reg_aagc_rf_x9_len 8
-#define        reg_aagc_rf_x9_lsb 0
-#define xd_p_reg_aagc_rf_x10   0xA02B
-#define        reg_aagc_rf_x10_pos 0
-#define        reg_aagc_rf_x10_len 8
-#define        reg_aagc_rf_x10_lsb 0
-#define xd_p_reg_aagc_rf_x11   0xA02C
-#define        reg_aagc_rf_x11_pos 0
-#define        reg_aagc_rf_x11_len 8
-#define        reg_aagc_rf_x11_lsb 0
-#define xd_p_reg_aagc_rf_x12   0xA02D
-#define        reg_aagc_rf_x12_pos 0
-#define        reg_aagc_rf_x12_len 8
-#define        reg_aagc_rf_x12_lsb 0
-#define xd_p_reg_aagc_rf_x13   0xA02E
-#define        reg_aagc_rf_x13_pos 0
-#define        reg_aagc_rf_x13_len 8
-#define        reg_aagc_rf_x13_lsb 0
-#define xd_p_reg_aagc_if_x0    0xA02F
-#define        reg_aagc_if_x0_pos 0
-#define        reg_aagc_if_x0_len 8
-#define        reg_aagc_if_x0_lsb 0
-#define xd_p_reg_aagc_if_x1    0xA030
-#define        reg_aagc_if_x1_pos 0
-#define        reg_aagc_if_x1_len 8
-#define        reg_aagc_if_x1_lsb 0
-#define xd_p_reg_aagc_if_x2    0xA031
-#define        reg_aagc_if_x2_pos 0
-#define        reg_aagc_if_x2_len 8
-#define        reg_aagc_if_x2_lsb 0
-#define xd_p_reg_aagc_if_x3    0xA032
-#define        reg_aagc_if_x3_pos 0
-#define        reg_aagc_if_x3_len 8
-#define        reg_aagc_if_x3_lsb 0
-#define xd_p_reg_aagc_if_x4    0xA033
-#define        reg_aagc_if_x4_pos 0
-#define        reg_aagc_if_x4_len 8
-#define        reg_aagc_if_x4_lsb 0
-#define xd_p_reg_aagc_if_x5    0xA034
-#define        reg_aagc_if_x5_pos 0
-#define        reg_aagc_if_x5_len 8
-#define        reg_aagc_if_x5_lsb 0
-#define xd_p_reg_aagc_if_x6    0xA035
-#define        reg_aagc_if_x6_pos 0
-#define        reg_aagc_if_x6_len 8
-#define        reg_aagc_if_x6_lsb 0
-#define xd_p_reg_aagc_if_x7    0xA036
-#define        reg_aagc_if_x7_pos 0
-#define        reg_aagc_if_x7_len 8
-#define        reg_aagc_if_x7_lsb 0
-#define xd_p_reg_aagc_if_x8    0xA037
-#define        reg_aagc_if_x8_pos 0
-#define        reg_aagc_if_x8_len 8
-#define        reg_aagc_if_x8_lsb 0
-#define xd_p_reg_aagc_if_x9    0xA038
-#define        reg_aagc_if_x9_pos 0
-#define        reg_aagc_if_x9_len 8
-#define        reg_aagc_if_x9_lsb 0
-#define xd_p_reg_aagc_if_x10   0xA039
-#define        reg_aagc_if_x10_pos 0
-#define        reg_aagc_if_x10_len 8
-#define        reg_aagc_if_x10_lsb 0
-#define xd_p_reg_aagc_if_x11   0xA03A
-#define        reg_aagc_if_x11_pos 0
-#define        reg_aagc_if_x11_len 8
-#define        reg_aagc_if_x11_lsb 0
-#define xd_p_reg_aagc_if_x12   0xA03B
-#define        reg_aagc_if_x12_pos 0
-#define        reg_aagc_if_x12_len 8
-#define        reg_aagc_if_x12_lsb 0
-#define xd_p_reg_aagc_if_x13   0xA03C
-#define        reg_aagc_if_x13_pos 0
-#define        reg_aagc_if_x13_len 8
-#define        reg_aagc_if_x13_lsb 0
-#define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca  0xA03D
-#define        reg_aagc_min_rf_ctl_8bit_for_dca_pos 0
-#define        reg_aagc_min_rf_ctl_8bit_for_dca_len 8
-#define        reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0
-#define xd_p_reg_aagc_min_if_ctl_8bit_for_dca  0xA03E
-#define        reg_aagc_min_if_ctl_8bit_for_dca_pos 0
-#define        reg_aagc_min_if_ctl_8bit_for_dca_len 8
-#define        reg_aagc_min_if_ctl_8bit_for_dca_lsb 0
-#define xd_r_reg_aagc_total_gain_7_0   0xA070
-#define        reg_aagc_total_gain_7_0_pos 0
-#define        reg_aagc_total_gain_7_0_len 8
-#define        reg_aagc_total_gain_7_0_lsb 0
-#define xd_r_reg_aagc_total_gain_15_8  0xA071
-#define        reg_aagc_total_gain_15_8_pos 0
-#define        reg_aagc_total_gain_15_8_len 8
-#define        reg_aagc_total_gain_15_8_lsb 8
-#define xd_p_reg_aagc_in_sat_cnt_7_0   0xA074
-#define        reg_aagc_in_sat_cnt_7_0_pos 0
-#define        reg_aagc_in_sat_cnt_7_0_len 8
-#define        reg_aagc_in_sat_cnt_7_0_lsb 0
-#define xd_p_reg_aagc_in_sat_cnt_15_8  0xA075
-#define        reg_aagc_in_sat_cnt_15_8_pos 0
-#define        reg_aagc_in_sat_cnt_15_8_len 8
-#define        reg_aagc_in_sat_cnt_15_8_lsb 8
-#define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076
-#define        reg_aagc_in_sat_cnt_23_16_pos 0
-#define        reg_aagc_in_sat_cnt_23_16_len 8
-#define        reg_aagc_in_sat_cnt_23_16_lsb 16
-#define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077
-#define        reg_aagc_in_sat_cnt_31_24_pos 0
-#define        reg_aagc_in_sat_cnt_31_24_len 8
-#define        reg_aagc_in_sat_cnt_31_24_lsb 24
-#define xd_r_reg_aagc_digital_rf_volt_7_0      0xA078
-#define        reg_aagc_digital_rf_volt_7_0_pos 0
-#define        reg_aagc_digital_rf_volt_7_0_len 8
-#define        reg_aagc_digital_rf_volt_7_0_lsb 0
-#define xd_r_reg_aagc_digital_rf_volt_9_8      0xA079
-#define        reg_aagc_digital_rf_volt_9_8_pos 0
-#define        reg_aagc_digital_rf_volt_9_8_len 2
-#define        reg_aagc_digital_rf_volt_9_8_lsb 8
-#define xd_r_reg_aagc_digital_if_volt_7_0      0xA07A
-#define        reg_aagc_digital_if_volt_7_0_pos 0
-#define        reg_aagc_digital_if_volt_7_0_len 8
-#define        reg_aagc_digital_if_volt_7_0_lsb 0
-#define xd_r_reg_aagc_digital_if_volt_9_8      0xA07B
-#define        reg_aagc_digital_if_volt_9_8_pos 0
-#define        reg_aagc_digital_if_volt_9_8_len 2
-#define        reg_aagc_digital_if_volt_9_8_lsb 8
-#define xd_r_reg_aagc_rf_gain  0xA07C
-#define        reg_aagc_rf_gain_pos 0
-#define        reg_aagc_rf_gain_len 8
-#define        reg_aagc_rf_gain_lsb 0
-#define xd_r_reg_aagc_if_gain  0xA07D
-#define        reg_aagc_if_gain_pos 0
-#define        reg_aagc_if_gain_len 8
-#define        reg_aagc_if_gain_lsb 0
-#define xd_p_tinr_imp_indicator        0xA080
-#define        tinr_imp_indicator_pos 0
-#define        tinr_imp_indicator_len 2
-#define        tinr_imp_indicator_lsb 0
-#define xd_p_reg_tinr_fifo_size        0xA080
-#define        reg_tinr_fifo_size_pos 2
-#define        reg_tinr_fifo_size_len 5
-#define        reg_tinr_fifo_size_lsb 0
-#define xd_p_reg_tinr_saturation_cnt_th        0xA081
-#define        reg_tinr_saturation_cnt_th_pos 0
-#define        reg_tinr_saturation_cnt_th_len 4
-#define        reg_tinr_saturation_cnt_th_lsb 0
-#define xd_p_reg_tinr_saturation_th_3_0        0xA081
-#define        reg_tinr_saturation_th_3_0_pos 4
-#define        reg_tinr_saturation_th_3_0_len 4
-#define        reg_tinr_saturation_th_3_0_lsb 0
-#define xd_p_reg_tinr_saturation_th_8_4        0xA082
-#define        reg_tinr_saturation_th_8_4_pos 0
-#define        reg_tinr_saturation_th_8_4_len 5
-#define        reg_tinr_saturation_th_8_4_lsb 4
-#define xd_p_reg_tinr_imp_duration_th_2k_7_0   0xA083
-#define        reg_tinr_imp_duration_th_2k_7_0_pos 0
-#define        reg_tinr_imp_duration_th_2k_7_0_len 8
-#define        reg_tinr_imp_duration_th_2k_7_0_lsb 0
-#define xd_p_reg_tinr_imp_duration_th_2k_8     0xA084
-#define        reg_tinr_imp_duration_th_2k_8_pos 0
-#define        reg_tinr_imp_duration_th_2k_8_len 1
-#define        reg_tinr_imp_duration_th_2k_8_lsb 0
-#define xd_p_reg_tinr_imp_duration_th_8k_7_0   0xA085
-#define        reg_tinr_imp_duration_th_8k_7_0_pos 0
-#define        reg_tinr_imp_duration_th_8k_7_0_len 8
-#define        reg_tinr_imp_duration_th_8k_7_0_lsb 0
-#define xd_p_reg_tinr_imp_duration_th_8k_10_8  0xA086
-#define        reg_tinr_imp_duration_th_8k_10_8_pos 0
-#define        reg_tinr_imp_duration_th_8k_10_8_len 3
-#define        reg_tinr_imp_duration_th_8k_10_8_lsb 8
-#define xd_p_reg_tinr_freq_ratio_6m_7_0        0xA087
-#define        reg_tinr_freq_ratio_6m_7_0_pos 0
-#define        reg_tinr_freq_ratio_6m_7_0_len 8
-#define        reg_tinr_freq_ratio_6m_7_0_lsb 0
-#define xd_p_reg_tinr_freq_ratio_6m_12_8       0xA088
-#define        reg_tinr_freq_ratio_6m_12_8_pos 0
-#define        reg_tinr_freq_ratio_6m_12_8_len 5
-#define        reg_tinr_freq_ratio_6m_12_8_lsb 8
-#define xd_p_reg_tinr_freq_ratio_7m_7_0        0xA089
-#define        reg_tinr_freq_ratio_7m_7_0_pos 0
-#define        reg_tinr_freq_ratio_7m_7_0_len 8
-#define        reg_tinr_freq_ratio_7m_7_0_lsb 0
-#define xd_p_reg_tinr_freq_ratio_7m_12_8       0xA08A
-#define        reg_tinr_freq_ratio_7m_12_8_pos 0
-#define        reg_tinr_freq_ratio_7m_12_8_len 5
-#define        reg_tinr_freq_ratio_7m_12_8_lsb 8
-#define xd_p_reg_tinr_freq_ratio_8m_7_0        0xA08B
-#define        reg_tinr_freq_ratio_8m_7_0_pos 0
-#define        reg_tinr_freq_ratio_8m_7_0_len 8
-#define        reg_tinr_freq_ratio_8m_7_0_lsb 0
-#define xd_p_reg_tinr_freq_ratio_8m_12_8       0xA08C
-#define        reg_tinr_freq_ratio_8m_12_8_pos 0
-#define        reg_tinr_freq_ratio_8m_12_8_len 5
-#define        reg_tinr_freq_ratio_8m_12_8_lsb 8
-#define xd_p_reg_tinr_imp_duration_th_low_2k   0xA08D
-#define        reg_tinr_imp_duration_th_low_2k_pos 0
-#define        reg_tinr_imp_duration_th_low_2k_len 8
-#define        reg_tinr_imp_duration_th_low_2k_lsb 0
-#define xd_p_reg_tinr_imp_duration_th_low_8k   0xA08E
-#define        reg_tinr_imp_duration_th_low_8k_pos 0
-#define        reg_tinr_imp_duration_th_low_8k_len 8
-#define        reg_tinr_imp_duration_th_low_8k_lsb 0
-#define xd_r_reg_tinr_counter_7_0      0xA090
-#define        reg_tinr_counter_7_0_pos 0
-#define        reg_tinr_counter_7_0_len 8
-#define        reg_tinr_counter_7_0_lsb 0
-#define xd_r_reg_tinr_counter_15_8     0xA091
-#define        reg_tinr_counter_15_8_pos 0
-#define        reg_tinr_counter_15_8_len 8
-#define        reg_tinr_counter_15_8_lsb 8
-#define xd_p_reg_tinr_adative_tinr_en  0xA093
-#define        reg_tinr_adative_tinr_en_pos 0
-#define        reg_tinr_adative_tinr_en_len 1
-#define        reg_tinr_adative_tinr_en_lsb 0
-#define xd_p_reg_tinr_peak_fifo_size   0xA093
-#define        reg_tinr_peak_fifo_size_pos 1
-#define        reg_tinr_peak_fifo_size_len 5
-#define        reg_tinr_peak_fifo_size_lsb 0
-#define xd_p_reg_tinr_counter_rst      0xA093
-#define        reg_tinr_counter_rst_pos 6
-#define        reg_tinr_counter_rst_len 1
-#define        reg_tinr_counter_rst_lsb 0
-#define xd_p_reg_tinr_search_period_7_0        0xA094
-#define        reg_tinr_search_period_7_0_pos 0
-#define        reg_tinr_search_period_7_0_len 8
-#define        reg_tinr_search_period_7_0_lsb 0
-#define xd_p_reg_tinr_search_period_15_8       0xA095
-#define        reg_tinr_search_period_15_8_pos 0
-#define        reg_tinr_search_period_15_8_len 8
-#define        reg_tinr_search_period_15_8_lsb 8
-#define xd_p_reg_ccifs_fcw_7_0 0xA0A0
-#define        reg_ccifs_fcw_7_0_pos 0
-#define        reg_ccifs_fcw_7_0_len 8
-#define        reg_ccifs_fcw_7_0_lsb 0
-#define xd_p_reg_ccifs_fcw_12_8        0xA0A1
-#define        reg_ccifs_fcw_12_8_pos 0
-#define        reg_ccifs_fcw_12_8_len 5
-#define        reg_ccifs_fcw_12_8_lsb 8
-#define xd_p_reg_ccifs_spec_inv        0xA0A1
-#define        reg_ccifs_spec_inv_pos 5
-#define        reg_ccifs_spec_inv_len 1
-#define        reg_ccifs_spec_inv_lsb 0
-#define xd_p_reg_gp_trigger    0xA0A2
-#define        reg_gp_trigger_pos 0
-#define        reg_gp_trigger_len 1
-#define        reg_gp_trigger_lsb 0
-#define xd_p_reg_trigger_sel   0xA0A2
-#define        reg_trigger_sel_pos 1
-#define        reg_trigger_sel_len 2
-#define        reg_trigger_sel_lsb 0
-#define xd_p_reg_debug_ofdm    0xA0A2
-#define        reg_debug_ofdm_pos 3
-#define        reg_debug_ofdm_len 2
-#define        reg_debug_ofdm_lsb 0
-#define xd_p_reg_trigger_module_sel    0xA0A3
-#define        reg_trigger_module_sel_pos 0
-#define        reg_trigger_module_sel_len 6
-#define        reg_trigger_module_sel_lsb 0
-#define xd_p_reg_trigger_set_sel       0xA0A4
-#define        reg_trigger_set_sel_pos 0
-#define        reg_trigger_set_sel_len 6
-#define        reg_trigger_set_sel_lsb 0
-#define xd_p_reg_fw_int_mask_n 0xA0A4
-#define        reg_fw_int_mask_n_pos 6
-#define        reg_fw_int_mask_n_len 1
-#define        reg_fw_int_mask_n_lsb 0
-#define xd_p_reg_debug_group   0xA0A5
-#define        reg_debug_group_pos 0
-#define        reg_debug_group_len 4
-#define        reg_debug_group_lsb 0
-#define xd_p_reg_odbg_clk_sel  0xA0A5
-#define        reg_odbg_clk_sel_pos 4
-#define        reg_odbg_clk_sel_len 2
-#define        reg_odbg_clk_sel_lsb 0
-#define xd_p_reg_ccif_sc       0xA0C0
-#define        reg_ccif_sc_pos 0
-#define        reg_ccif_sc_len 4
-#define        reg_ccif_sc_lsb 0
-#define xd_r_reg_ccif_saturate 0xA0C1
-#define        reg_ccif_saturate_pos 0
-#define        reg_ccif_saturate_len 2
-#define        reg_ccif_saturate_lsb 0
-#define xd_r_reg_antif_saturate        0xA0C1
-#define        reg_antif_saturate_pos 2
-#define        reg_antif_saturate_len 4
-#define        reg_antif_saturate_lsb 0
-#define xd_r_reg_acif_saturate 0xA0C2
-#define        reg_acif_saturate_pos 0
-#define        reg_acif_saturate_len 8
-#define        reg_acif_saturate_lsb 0
-#define xd_p_reg_tmr_timer0_threshold_7_0      0xA0C8
-#define        reg_tmr_timer0_threshold_7_0_pos 0
-#define        reg_tmr_timer0_threshold_7_0_len 8
-#define        reg_tmr_timer0_threshold_7_0_lsb 0
-#define xd_p_reg_tmr_timer0_threshold_15_8     0xA0C9
-#define        reg_tmr_timer0_threshold_15_8_pos 0
-#define        reg_tmr_timer0_threshold_15_8_len 8
-#define        reg_tmr_timer0_threshold_15_8_lsb 8
-#define xd_p_reg_tmr_timer0_enable     0xA0CA
-#define        reg_tmr_timer0_enable_pos 0
-#define        reg_tmr_timer0_enable_len 1
-#define        reg_tmr_timer0_enable_lsb 0
-#define xd_p_reg_tmr_timer0_clk_sel    0xA0CA
-#define        reg_tmr_timer0_clk_sel_pos 1
-#define        reg_tmr_timer0_clk_sel_len 1
-#define        reg_tmr_timer0_clk_sel_lsb 0
-#define xd_p_reg_tmr_timer0_int        0xA0CA
-#define        reg_tmr_timer0_int_pos 2
-#define        reg_tmr_timer0_int_len 1
-#define        reg_tmr_timer0_int_lsb 0
-#define xd_p_reg_tmr_timer0_rst        0xA0CA
-#define        reg_tmr_timer0_rst_pos 3
-#define        reg_tmr_timer0_rst_len 1
-#define        reg_tmr_timer0_rst_lsb 0
-#define xd_r_reg_tmr_timer0_count_7_0  0xA0CB
-#define        reg_tmr_timer0_count_7_0_pos 0
-#define        reg_tmr_timer0_count_7_0_len 8
-#define        reg_tmr_timer0_count_7_0_lsb 0
-#define xd_r_reg_tmr_timer0_count_15_8 0xA0CC
-#define        reg_tmr_timer0_count_15_8_pos 0
-#define        reg_tmr_timer0_count_15_8_len 8
-#define        reg_tmr_timer0_count_15_8_lsb 8
-#define xd_p_reg_suspend       0xA0CD
-#define        reg_suspend_pos 0
-#define        reg_suspend_len 1
-#define        reg_suspend_lsb 0
-#define xd_p_reg_suspend_rdy   0xA0CD
-#define        reg_suspend_rdy_pos 1
-#define        reg_suspend_rdy_len 1
-#define        reg_suspend_rdy_lsb 0
-#define xd_p_reg_resume        0xA0CD
-#define        reg_resume_pos 2
-#define        reg_resume_len 1
-#define        reg_resume_lsb 0
-#define xd_p_reg_resume_rdy    0xA0CD
-#define        reg_resume_rdy_pos 3
-#define        reg_resume_rdy_len 1
-#define        reg_resume_rdy_lsb 0
-#define xd_p_reg_fmf   0xA0CE
-#define        reg_fmf_pos 0
-#define        reg_fmf_len 8
-#define        reg_fmf_lsb 0
-#define xd_p_ccid_accumulate_num_2k_7_0        0xA100
-#define        ccid_accumulate_num_2k_7_0_pos 0
-#define        ccid_accumulate_num_2k_7_0_len 8
-#define        ccid_accumulate_num_2k_7_0_lsb 0
-#define xd_p_ccid_accumulate_num_2k_12_8       0xA101
-#define        ccid_accumulate_num_2k_12_8_pos 0
-#define        ccid_accumulate_num_2k_12_8_len 5
-#define        ccid_accumulate_num_2k_12_8_lsb 8
-#define xd_p_ccid_accumulate_num_8k_7_0        0xA102
-#define        ccid_accumulate_num_8k_7_0_pos 0
-#define        ccid_accumulate_num_8k_7_0_len 8
-#define        ccid_accumulate_num_8k_7_0_lsb 0
-#define xd_p_ccid_accumulate_num_8k_14_8       0xA103
-#define        ccid_accumulate_num_8k_14_8_pos 0
-#define        ccid_accumulate_num_8k_14_8_len 7
-#define        ccid_accumulate_num_8k_14_8_lsb 8
-#define xd_p_ccid_desired_level_0      0xA103
-#define        ccid_desired_level_0_pos 7
-#define        ccid_desired_level_0_len 1
-#define        ccid_desired_level_0_lsb 0
-#define xd_p_ccid_desired_level_8_1    0xA104
-#define        ccid_desired_level_8_1_pos 0
-#define        ccid_desired_level_8_1_len 8
-#define        ccid_desired_level_8_1_lsb 1
-#define xd_p_ccid_apply_delay  0xA105
-#define        ccid_apply_delay_pos 0
-#define        ccid_apply_delay_len 7
-#define        ccid_apply_delay_lsb 0
-#define xd_p_ccid_CCID_Threshold1      0xA106
-#define        ccid_CCID_Threshold1_pos 0
-#define        ccid_CCID_Threshold1_len 8
-#define        ccid_CCID_Threshold1_lsb 0
-#define xd_p_ccid_CCID_Threshold2      0xA107
-#define        ccid_CCID_Threshold2_pos 0
-#define        ccid_CCID_Threshold2_len 8
-#define        ccid_CCID_Threshold2_lsb 0
-#define xd_p_reg_ccid_gain_scale       0xA108
-#define        reg_ccid_gain_scale_pos 0
-#define        reg_ccid_gain_scale_len 4
-#define        reg_ccid_gain_scale_lsb 0
-#define xd_p_reg_ccid2_passband_gain_set       0xA108
-#define        reg_ccid2_passband_gain_set_pos 4
-#define        reg_ccid2_passband_gain_set_len 4
-#define        reg_ccid2_passband_gain_set_lsb 0
-#define xd_r_ccid_multiplier_7_0       0xA109
-#define        ccid_multiplier_7_0_pos 0
-#define        ccid_multiplier_7_0_len 8
-#define        ccid_multiplier_7_0_lsb 0
-#define xd_r_ccid_multiplier_15_8      0xA10A
-#define        ccid_multiplier_15_8_pos 0
-#define        ccid_multiplier_15_8_len 8
-#define        ccid_multiplier_15_8_lsb 8
-#define xd_r_ccid_right_shift_bits     0xA10B
-#define        ccid_right_shift_bits_pos 0
-#define        ccid_right_shift_bits_len 4
-#define        ccid_right_shift_bits_lsb 0
-#define xd_r_reg_ccid_sx_7_0   0xA10C
-#define        reg_ccid_sx_7_0_pos 0
-#define        reg_ccid_sx_7_0_len 8
-#define        reg_ccid_sx_7_0_lsb 0
-#define xd_r_reg_ccid_sx_15_8  0xA10D
-#define        reg_ccid_sx_15_8_pos 0
-#define        reg_ccid_sx_15_8_len 8
-#define        reg_ccid_sx_15_8_lsb 8
-#define xd_r_reg_ccid_sx_21_16 0xA10E
-#define        reg_ccid_sx_21_16_pos 0
-#define        reg_ccid_sx_21_16_len 6
-#define        reg_ccid_sx_21_16_lsb 16
-#define xd_r_reg_ccid_sy_7_0   0xA110
-#define        reg_ccid_sy_7_0_pos 0
-#define        reg_ccid_sy_7_0_len 8
-#define        reg_ccid_sy_7_0_lsb 0
-#define xd_r_reg_ccid_sy_15_8  0xA111
-#define        reg_ccid_sy_15_8_pos 0
-#define        reg_ccid_sy_15_8_len 8
-#define        reg_ccid_sy_15_8_lsb 8
-#define xd_r_reg_ccid_sy_23_16 0xA112
-#define        reg_ccid_sy_23_16_pos 0
-#define        reg_ccid_sy_23_16_len 8
-#define        reg_ccid_sy_23_16_lsb 16
-#define xd_r_reg_ccid2_sz_7_0  0xA114
-#define        reg_ccid2_sz_7_0_pos 0
-#define        reg_ccid2_sz_7_0_len 8
-#define        reg_ccid2_sz_7_0_lsb 0
-#define xd_r_reg_ccid2_sz_15_8 0xA115
-#define        reg_ccid2_sz_15_8_pos 0
-#define        reg_ccid2_sz_15_8_len 8
-#define        reg_ccid2_sz_15_8_lsb 8
-#define xd_r_reg_ccid2_sz_23_16        0xA116
-#define        reg_ccid2_sz_23_16_pos 0
-#define        reg_ccid2_sz_23_16_len 8
-#define        reg_ccid2_sz_23_16_lsb 16
-#define xd_r_reg_ccid2_sz_25_24        0xA117
-#define        reg_ccid2_sz_25_24_pos 0
-#define        reg_ccid2_sz_25_24_len 2
-#define        reg_ccid2_sz_25_24_lsb 24
-#define xd_r_reg_ccid2_sy_7_0  0xA118
-#define        reg_ccid2_sy_7_0_pos 0
-#define        reg_ccid2_sy_7_0_len 8
-#define        reg_ccid2_sy_7_0_lsb 0
-#define xd_r_reg_ccid2_sy_15_8 0xA119
-#define        reg_ccid2_sy_15_8_pos 0
-#define        reg_ccid2_sy_15_8_len 8
-#define        reg_ccid2_sy_15_8_lsb 8
-#define xd_r_reg_ccid2_sy_23_16        0xA11A
-#define        reg_ccid2_sy_23_16_pos 0
-#define        reg_ccid2_sy_23_16_len 8
-#define        reg_ccid2_sy_23_16_lsb 16
-#define xd_r_reg_ccid2_sy_25_24        0xA11B
-#define        reg_ccid2_sy_25_24_pos 0
-#define        reg_ccid2_sy_25_24_len 2
-#define        reg_ccid2_sy_25_24_lsb 24
-#define xd_p_dagc1_accumulate_num_2k_7_0       0xA120
-#define        dagc1_accumulate_num_2k_7_0_pos 0
-#define        dagc1_accumulate_num_2k_7_0_len 8
-#define        dagc1_accumulate_num_2k_7_0_lsb 0
-#define xd_p_dagc1_accumulate_num_2k_12_8      0xA121
-#define        dagc1_accumulate_num_2k_12_8_pos 0
-#define        dagc1_accumulate_num_2k_12_8_len 5
-#define        dagc1_accumulate_num_2k_12_8_lsb 8
-#define xd_p_dagc1_accumulate_num_8k_7_0       0xA122
-#define        dagc1_accumulate_num_8k_7_0_pos 0
-#define        dagc1_accumulate_num_8k_7_0_len 8
-#define        dagc1_accumulate_num_8k_7_0_lsb 0
-#define xd_p_dagc1_accumulate_num_8k_14_8      0xA123
-#define        dagc1_accumulate_num_8k_14_8_pos 0
-#define        dagc1_accumulate_num_8k_14_8_len 7
-#define        dagc1_accumulate_num_8k_14_8_lsb 8
-#define xd_p_dagc1_desired_level_0     0xA123
-#define        dagc1_desired_level_0_pos 7
-#define        dagc1_desired_level_0_len 1
-#define        dagc1_desired_level_0_lsb 0
-#define xd_p_dagc1_desired_level_8_1   0xA124
-#define        dagc1_desired_level_8_1_pos 0
-#define        dagc1_desired_level_8_1_len 8
-#define        dagc1_desired_level_8_1_lsb 1
-#define xd_p_dagc1_apply_delay 0xA125
-#define        dagc1_apply_delay_pos 0
-#define        dagc1_apply_delay_len 7
-#define        dagc1_apply_delay_lsb 0
-#define xd_p_dagc1_bypass_scale_ctl    0xA126
-#define        dagc1_bypass_scale_ctl_pos 0
-#define        dagc1_bypass_scale_ctl_len 2
-#define        dagc1_bypass_scale_ctl_lsb 0
-#define xd_p_reg_dagc1_in_sat_cnt_7_0  0xA127
-#define        reg_dagc1_in_sat_cnt_7_0_pos 0
-#define        reg_dagc1_in_sat_cnt_7_0_len 8
-#define        reg_dagc1_in_sat_cnt_7_0_lsb 0
-#define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128
-#define        reg_dagc1_in_sat_cnt_15_8_pos 0
-#define        reg_dagc1_in_sat_cnt_15_8_len 8
-#define        reg_dagc1_in_sat_cnt_15_8_lsb 8
-#define xd_p_reg_dagc1_in_sat_cnt_23_16        0xA129
-#define        reg_dagc1_in_sat_cnt_23_16_pos 0
-#define        reg_dagc1_in_sat_cnt_23_16_len 8
-#define        reg_dagc1_in_sat_cnt_23_16_lsb 16
-#define xd_p_reg_dagc1_in_sat_cnt_31_24        0xA12A
-#define        reg_dagc1_in_sat_cnt_31_24_pos 0
-#define        reg_dagc1_in_sat_cnt_31_24_len 8
-#define        reg_dagc1_in_sat_cnt_31_24_lsb 24
-#define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B
-#define        reg_dagc1_out_sat_cnt_7_0_pos 0
-#define        reg_dagc1_out_sat_cnt_7_0_len 8
-#define        reg_dagc1_out_sat_cnt_7_0_lsb 0
-#define xd_p_reg_dagc1_out_sat_cnt_15_8        0xA12C
-#define        reg_dagc1_out_sat_cnt_15_8_pos 0
-#define        reg_dagc1_out_sat_cnt_15_8_len 8
-#define        reg_dagc1_out_sat_cnt_15_8_lsb 8
-#define xd_p_reg_dagc1_out_sat_cnt_23_16       0xA12D
-#define        reg_dagc1_out_sat_cnt_23_16_pos 0
-#define        reg_dagc1_out_sat_cnt_23_16_len 8
-#define        reg_dagc1_out_sat_cnt_23_16_lsb 16
-#define xd_p_reg_dagc1_out_sat_cnt_31_24       0xA12E
-#define        reg_dagc1_out_sat_cnt_31_24_pos 0
-#define        reg_dagc1_out_sat_cnt_31_24_len 8
-#define        reg_dagc1_out_sat_cnt_31_24_lsb 24
-#define xd_r_dagc1_multiplier_7_0      0xA136
-#define        dagc1_multiplier_7_0_pos 0
-#define        dagc1_multiplier_7_0_len 8
-#define        dagc1_multiplier_7_0_lsb 0
-#define xd_r_dagc1_multiplier_15_8     0xA137
-#define        dagc1_multiplier_15_8_pos 0
-#define        dagc1_multiplier_15_8_len 8
-#define        dagc1_multiplier_15_8_lsb 8
-#define xd_r_dagc1_right_shift_bits    0xA138
-#define        dagc1_right_shift_bits_pos 0
-#define        dagc1_right_shift_bits_len 4
-#define        dagc1_right_shift_bits_lsb 0
-#define xd_p_reg_bfs_fcw_7_0   0xA140
-#define        reg_bfs_fcw_7_0_pos 0
-#define        reg_bfs_fcw_7_0_len 8
-#define        reg_bfs_fcw_7_0_lsb 0
-#define xd_p_reg_bfs_fcw_15_8  0xA141
-#define        reg_bfs_fcw_15_8_pos 0
-#define        reg_bfs_fcw_15_8_len 8
-#define        reg_bfs_fcw_15_8_lsb 8
-#define xd_p_reg_bfs_fcw_22_16 0xA142
-#define        reg_bfs_fcw_22_16_pos 0
-#define        reg_bfs_fcw_22_16_len 7
-#define        reg_bfs_fcw_22_16_lsb 16
-#define xd_p_reg_antif_sf_7_0  0xA144
-#define        reg_antif_sf_7_0_pos 0
-#define        reg_antif_sf_7_0_len 8
-#define        reg_antif_sf_7_0_lsb 0
-#define xd_p_reg_antif_sf_11_8 0xA145
-#define        reg_antif_sf_11_8_pos 0
-#define        reg_antif_sf_11_8_len 4
-#define        reg_antif_sf_11_8_lsb 8
-#define xd_r_bfs_fcw_q_7_0     0xA150
-#define        bfs_fcw_q_7_0_pos 0
-#define        bfs_fcw_q_7_0_len 8
-#define        bfs_fcw_q_7_0_lsb 0
-#define xd_r_bfs_fcw_q_15_8    0xA151
-#define        bfs_fcw_q_15_8_pos 0
-#define        bfs_fcw_q_15_8_len 8
-#define        bfs_fcw_q_15_8_lsb 8
-#define xd_r_bfs_fcw_q_22_16   0xA152
-#define        bfs_fcw_q_22_16_pos 0
-#define        bfs_fcw_q_22_16_len 7
-#define        bfs_fcw_q_22_16_lsb 16
-#define xd_p_reg_dca_enu       0xA160
-#define        reg_dca_enu_pos 0
-#define        reg_dca_enu_len 1
-#define        reg_dca_enu_lsb 0
-#define xd_p_reg_dca_enl       0xA160
-#define        reg_dca_enl_pos 1
-#define        reg_dca_enl_len 1
-#define        reg_dca_enl_lsb 0
-#define xd_p_reg_dca_lower_chip        0xA160
-#define        reg_dca_lower_chip_pos 2
-#define        reg_dca_lower_chip_len 1
-#define        reg_dca_lower_chip_lsb 0
-#define xd_p_reg_dca_upper_chip        0xA160
-#define        reg_dca_upper_chip_pos 3
-#define        reg_dca_upper_chip_len 1
-#define        reg_dca_upper_chip_lsb 0
-#define xd_p_reg_dca_platch    0xA160
-#define        reg_dca_platch_pos 4
-#define        reg_dca_platch_len 1
-#define        reg_dca_platch_lsb 0
-#define xd_p_reg_dca_th        0xA161
-#define        reg_dca_th_pos 0
-#define        reg_dca_th_len 5
-#define        reg_dca_th_lsb 0
-#define xd_p_reg_dca_scale     0xA162
-#define        reg_dca_scale_pos 0
-#define        reg_dca_scale_len 4
-#define        reg_dca_scale_lsb 0
-#define xd_p_reg_dca_tone_7_0  0xA163
-#define        reg_dca_tone_7_0_pos 0
-#define        reg_dca_tone_7_0_len 8
-#define        reg_dca_tone_7_0_lsb 0
-#define xd_p_reg_dca_tone_12_8 0xA164
-#define        reg_dca_tone_12_8_pos 0
-#define        reg_dca_tone_12_8_len 5
-#define        reg_dca_tone_12_8_lsb 8
-#define xd_p_reg_dca_time_7_0  0xA165
-#define        reg_dca_time_7_0_pos 0
-#define        reg_dca_time_7_0_len 8
-#define        reg_dca_time_7_0_lsb 0
-#define xd_p_reg_dca_time_15_8 0xA166
-#define        reg_dca_time_15_8_pos 0
-#define        reg_dca_time_15_8_len 8
-#define        reg_dca_time_15_8_lsb 8
-#define xd_r_dcasm     0xA167
-#define        dcasm_pos 0
-#define        dcasm_len 3
-#define        dcasm_lsb 0
-#define xd_p_reg_qnt_valuew_7_0        0xA168
-#define        reg_qnt_valuew_7_0_pos 0
-#define        reg_qnt_valuew_7_0_len 8
-#define        reg_qnt_valuew_7_0_lsb 0
-#define xd_p_reg_qnt_valuew_10_8       0xA169
-#define        reg_qnt_valuew_10_8_pos 0
-#define        reg_qnt_valuew_10_8_len 3
-#define        reg_qnt_valuew_10_8_lsb 8
-#define xd_p_dca_sbx_gain_diff_7_0     0xA16A
-#define        dca_sbx_gain_diff_7_0_pos 0
-#define        dca_sbx_gain_diff_7_0_len 8
-#define        dca_sbx_gain_diff_7_0_lsb 0
-#define xd_p_dca_sbx_gain_diff_9_8     0xA16B
-#define        dca_sbx_gain_diff_9_8_pos 0
-#define        dca_sbx_gain_diff_9_8_len 2
-#define        dca_sbx_gain_diff_9_8_lsb 8
-#define xd_p_reg_dca_stand_alone       0xA16C
-#define        reg_dca_stand_alone_pos 0
-#define        reg_dca_stand_alone_len 1
-#define        reg_dca_stand_alone_lsb 0
-#define xd_p_reg_dca_upper_out_en      0xA16C
-#define        reg_dca_upper_out_en_pos 1
-#define        reg_dca_upper_out_en_len 1
-#define        reg_dca_upper_out_en_lsb 0
-#define xd_p_reg_dca_rc_en     0xA16C
-#define        reg_dca_rc_en_pos 2
-#define        reg_dca_rc_en_len 1
-#define        reg_dca_rc_en_lsb 0
-#define xd_p_reg_dca_retrain_send      0xA16C
-#define        reg_dca_retrain_send_pos 3
-#define        reg_dca_retrain_send_len 1
-#define        reg_dca_retrain_send_lsb 0
-#define xd_p_reg_dca_retrain_rec       0xA16C
-#define        reg_dca_retrain_rec_pos 4
-#define        reg_dca_retrain_rec_len 1
-#define        reg_dca_retrain_rec_lsb 0
-#define xd_p_reg_dca_api_tpsrdy        0xA16C
-#define        reg_dca_api_tpsrdy_pos 5
-#define        reg_dca_api_tpsrdy_len 1
-#define        reg_dca_api_tpsrdy_lsb 0
-#define xd_p_reg_dca_symbol_gap        0xA16D
-#define        reg_dca_symbol_gap_pos 0
-#define        reg_dca_symbol_gap_len 4
-#define        reg_dca_symbol_gap_lsb 0
-#define xd_p_reg_qnt_nfvaluew_7_0      0xA16E
-#define        reg_qnt_nfvaluew_7_0_pos 0
-#define        reg_qnt_nfvaluew_7_0_len 8
-#define        reg_qnt_nfvaluew_7_0_lsb 0
-#define xd_p_reg_qnt_nfvaluew_10_8     0xA16F
-#define        reg_qnt_nfvaluew_10_8_pos 0
-#define        reg_qnt_nfvaluew_10_8_len 3
-#define        reg_qnt_nfvaluew_10_8_lsb 8
-#define xd_p_reg_qnt_flatness_thr_7_0  0xA170
-#define        reg_qnt_flatness_thr_7_0_pos 0
-#define        reg_qnt_flatness_thr_7_0_len 8
-#define        reg_qnt_flatness_thr_7_0_lsb 0
-#define xd_p_reg_qnt_flatness_thr_9_8  0xA171
-#define        reg_qnt_flatness_thr_9_8_pos 0
-#define        reg_qnt_flatness_thr_9_8_len 2
-#define        reg_qnt_flatness_thr_9_8_lsb 8
-#define xd_p_reg_dca_tone_idx_5_0      0xA171
-#define        reg_dca_tone_idx_5_0_pos 2
-#define        reg_dca_tone_idx_5_0_len 6
-#define        reg_dca_tone_idx_5_0_lsb 0
-#define xd_p_reg_dca_tone_idx_12_6     0xA172
-#define        reg_dca_tone_idx_12_6_pos 0
-#define        reg_dca_tone_idx_12_6_len 7
-#define        reg_dca_tone_idx_12_6_lsb 6
-#define xd_p_reg_dca_data_vld  0xA173
-#define        reg_dca_data_vld_pos 0
-#define        reg_dca_data_vld_len 1
-#define        reg_dca_data_vld_lsb 0
-#define xd_p_reg_dca_read_update       0xA173
-#define        reg_dca_read_update_pos 1
-#define        reg_dca_read_update_len 1
-#define        reg_dca_read_update_lsb 0
-#define xd_r_reg_dca_data_re_5_0       0xA173
-#define        reg_dca_data_re_5_0_pos 2
-#define        reg_dca_data_re_5_0_len 6
-#define        reg_dca_data_re_5_0_lsb 0
-#define xd_r_reg_dca_data_re_10_6      0xA174
-#define        reg_dca_data_re_10_6_pos 0
-#define        reg_dca_data_re_10_6_len 5
-#define        reg_dca_data_re_10_6_lsb 6
-#define xd_r_reg_dca_data_im_7_0       0xA175
-#define        reg_dca_data_im_7_0_pos 0
-#define        reg_dca_data_im_7_0_len 8
-#define        reg_dca_data_im_7_0_lsb 0
-#define xd_r_reg_dca_data_im_10_8      0xA176
-#define        reg_dca_data_im_10_8_pos 0
-#define        reg_dca_data_im_10_8_len 3
-#define        reg_dca_data_im_10_8_lsb 8
-#define xd_r_reg_dca_data_h2_7_0       0xA178
-#define        reg_dca_data_h2_7_0_pos 0
-#define        reg_dca_data_h2_7_0_len 8
-#define        reg_dca_data_h2_7_0_lsb 0
-#define xd_r_reg_dca_data_h2_9_8       0xA179
-#define        reg_dca_data_h2_9_8_pos 0
-#define        reg_dca_data_h2_9_8_len 2
-#define        reg_dca_data_h2_9_8_lsb 8
-#define xd_p_reg_f_adc_7_0     0xA180
-#define        reg_f_adc_7_0_pos 0
-#define        reg_f_adc_7_0_len 8
-#define        reg_f_adc_7_0_lsb 0
-#define xd_p_reg_f_adc_15_8    0xA181
-#define        reg_f_adc_15_8_pos 0
-#define        reg_f_adc_15_8_len 8
-#define        reg_f_adc_15_8_lsb 8
-#define xd_p_reg_f_adc_23_16   0xA182
-#define        reg_f_adc_23_16_pos 0
-#define        reg_f_adc_23_16_len 8
-#define        reg_f_adc_23_16_lsb 16
-#define xd_r_intp_mu_7_0       0xA190
-#define        intp_mu_7_0_pos 0
-#define        intp_mu_7_0_len 8
-#define        intp_mu_7_0_lsb 0
-#define xd_r_intp_mu_15_8      0xA191
-#define        intp_mu_15_8_pos 0
-#define        intp_mu_15_8_len 8
-#define        intp_mu_15_8_lsb 8
-#define xd_r_intp_mu_19_16     0xA192
-#define        intp_mu_19_16_pos 0
-#define        intp_mu_19_16_len 4
-#define        intp_mu_19_16_lsb 16
-#define xd_p_reg_agc_rst       0xA1A0
-#define        reg_agc_rst_pos 0
-#define        reg_agc_rst_len 1
-#define        reg_agc_rst_lsb 0
-#define xd_p_rf_agc_en 0xA1A0
-#define        rf_agc_en_pos 1
-#define        rf_agc_en_len 1
-#define        rf_agc_en_lsb 0
-#define xd_p_rf_agc_dis        0xA1A0
-#define        rf_agc_dis_pos 2
-#define        rf_agc_dis_len 1
-#define        rf_agc_dis_lsb 0
-#define xd_p_if_agc_rst        0xA1A0
-#define        if_agc_rst_pos 3
-#define        if_agc_rst_len 1
-#define        if_agc_rst_lsb 0
-#define xd_p_if_agc_en 0xA1A0
-#define        if_agc_en_pos 4
-#define        if_agc_en_len 1
-#define        if_agc_en_lsb 0
-#define xd_p_if_agc_dis        0xA1A0
-#define        if_agc_dis_pos 5
-#define        if_agc_dis_len 1
-#define        if_agc_dis_lsb 0
-#define xd_p_agc_lock  0xA1A0
-#define        agc_lock_pos 6
-#define        agc_lock_len 1
-#define        agc_lock_lsb 0
-#define xd_p_reg_tinr_rst      0xA1A1
-#define        reg_tinr_rst_pos 0
-#define        reg_tinr_rst_len 1
-#define        reg_tinr_rst_lsb 0
-#define xd_p_reg_tinr_en       0xA1A1
-#define        reg_tinr_en_pos 1
-#define        reg_tinr_en_len 1
-#define        reg_tinr_en_lsb 0
-#define xd_p_reg_ccifs_en      0xA1A2
-#define        reg_ccifs_en_pos 0
-#define        reg_ccifs_en_len 1
-#define        reg_ccifs_en_lsb 0
-#define xd_p_reg_ccifs_dis     0xA1A2
-#define        reg_ccifs_dis_pos 1
-#define        reg_ccifs_dis_len 1
-#define        reg_ccifs_dis_lsb 0
-#define xd_p_reg_ccifs_rst     0xA1A2
-#define        reg_ccifs_rst_pos 2
-#define        reg_ccifs_rst_len 1
-#define        reg_ccifs_rst_lsb 0
-#define xd_p_reg_ccifs_byp     0xA1A2
-#define        reg_ccifs_byp_pos 3
-#define        reg_ccifs_byp_len 1
-#define        reg_ccifs_byp_lsb 0
-#define xd_p_reg_ccif_en       0xA1A3
-#define        reg_ccif_en_pos 0
-#define        reg_ccif_en_len 1
-#define        reg_ccif_en_lsb 0
-#define xd_p_reg_ccif_dis      0xA1A3
-#define        reg_ccif_dis_pos 1
-#define        reg_ccif_dis_len 1
-#define        reg_ccif_dis_lsb 0
-#define xd_p_reg_ccif_rst      0xA1A3
-#define        reg_ccif_rst_pos 2
-#define        reg_ccif_rst_len 1
-#define        reg_ccif_rst_lsb 0
-#define xd_p_reg_ccif_byp      0xA1A3
-#define        reg_ccif_byp_pos 3
-#define        reg_ccif_byp_len 1
-#define        reg_ccif_byp_lsb 0
-#define xd_p_dagc1_rst 0xA1A4
-#define        dagc1_rst_pos 0
-#define        dagc1_rst_len 1
-#define        dagc1_rst_lsb 0
-#define xd_p_dagc1_en  0xA1A4
-#define        dagc1_en_pos 1
-#define        dagc1_en_len 1
-#define        dagc1_en_lsb 0
-#define xd_p_dagc1_mode        0xA1A4
-#define        dagc1_mode_pos 2
-#define        dagc1_mode_len 2
-#define        dagc1_mode_lsb 0
-#define xd_p_dagc1_done        0xA1A4
-#define        dagc1_done_pos 4
-#define        dagc1_done_len 1
-#define        dagc1_done_lsb 0
-#define xd_p_ccid_rst  0xA1A5
-#define        ccid_rst_pos 0
-#define        ccid_rst_len 1
-#define        ccid_rst_lsb 0
-#define xd_p_ccid_en   0xA1A5
-#define        ccid_en_pos 1
-#define        ccid_en_len 1
-#define        ccid_en_lsb 0
-#define xd_p_ccid_mode 0xA1A5
-#define        ccid_mode_pos 2
-#define        ccid_mode_len 2
-#define        ccid_mode_lsb 0
-#define xd_p_ccid_done 0xA1A5
-#define        ccid_done_pos 4
-#define        ccid_done_len 1
-#define        ccid_done_lsb 0
-#define xd_r_ccid_deted        0xA1A5
-#define        ccid_deted_pos 5
-#define        ccid_deted_len 1
-#define        ccid_deted_lsb 0
-#define xd_p_ccid2_en  0xA1A5
-#define        ccid2_en_pos 6
-#define        ccid2_en_len 1
-#define        ccid2_en_lsb 0
-#define xd_p_ccid2_done        0xA1A5
-#define        ccid2_done_pos 7
-#define        ccid2_done_len 1
-#define        ccid2_done_lsb 0
-#define xd_p_reg_bfs_en        0xA1A6
-#define        reg_bfs_en_pos 0
-#define        reg_bfs_en_len 1
-#define        reg_bfs_en_lsb 0
-#define xd_p_reg_bfs_dis       0xA1A6
-#define        reg_bfs_dis_pos 1
-#define        reg_bfs_dis_len 1
-#define        reg_bfs_dis_lsb 0
-#define xd_p_reg_bfs_rst       0xA1A6
-#define        reg_bfs_rst_pos 2
-#define        reg_bfs_rst_len 1
-#define        reg_bfs_rst_lsb 0
-#define xd_p_reg_bfs_byp       0xA1A6
-#define        reg_bfs_byp_pos 3
-#define        reg_bfs_byp_len 1
-#define        reg_bfs_byp_lsb 0
-#define xd_p_reg_antif_en      0xA1A7
-#define        reg_antif_en_pos 0
-#define        reg_antif_en_len 1
-#define        reg_antif_en_lsb 0
-#define xd_p_reg_antif_dis     0xA1A7
-#define        reg_antif_dis_pos 1
-#define        reg_antif_dis_len 1
-#define        reg_antif_dis_lsb 0
-#define xd_p_reg_antif_rst     0xA1A7
-#define        reg_antif_rst_pos 2
-#define        reg_antif_rst_len 1
-#define        reg_antif_rst_lsb 0
-#define xd_p_reg_antif_byp     0xA1A7
-#define        reg_antif_byp_pos 3
-#define        reg_antif_byp_len 1
-#define        reg_antif_byp_lsb 0
-#define xd_p_intp_en   0xA1A8
-#define        intp_en_pos 0
-#define        intp_en_len 1
-#define        intp_en_lsb 0
-#define xd_p_intp_dis  0xA1A8
-#define        intp_dis_pos 1
-#define        intp_dis_len 1
-#define        intp_dis_lsb 0
-#define xd_p_intp_rst  0xA1A8
-#define        intp_rst_pos 2
-#define        intp_rst_len 1
-#define        intp_rst_lsb 0
-#define xd_p_intp_byp  0xA1A8
-#define        intp_byp_pos 3
-#define        intp_byp_len 1
-#define        intp_byp_lsb 0
-#define xd_p_reg_acif_en       0xA1A9
-#define        reg_acif_en_pos 0
-#define        reg_acif_en_len 1
-#define        reg_acif_en_lsb 0
-#define xd_p_reg_acif_dis      0xA1A9
-#define        reg_acif_dis_pos 1
-#define        reg_acif_dis_len 1
-#define        reg_acif_dis_lsb 0
-#define xd_p_reg_acif_rst      0xA1A9
-#define        reg_acif_rst_pos 2
-#define        reg_acif_rst_len 1
-#define        reg_acif_rst_lsb 0
-#define xd_p_reg_acif_byp      0xA1A9
-#define        reg_acif_byp_pos 3
-#define        reg_acif_byp_len 1
-#define        reg_acif_byp_lsb 0
-#define xd_p_reg_acif_sync_mode        0xA1A9
-#define        reg_acif_sync_mode_pos 4
-#define        reg_acif_sync_mode_len 1
-#define        reg_acif_sync_mode_lsb 0
-#define xd_p_dagc2_rst 0xA1AA
-#define        dagc2_rst_pos 0
-#define        dagc2_rst_len 1
-#define        dagc2_rst_lsb 0
-#define xd_p_dagc2_en  0xA1AA
-#define        dagc2_en_pos 1
-#define        dagc2_en_len 1
-#define        dagc2_en_lsb 0
-#define xd_p_dagc2_mode        0xA1AA
-#define        dagc2_mode_pos 2
-#define        dagc2_mode_len 2
-#define        dagc2_mode_lsb 0
-#define xd_p_dagc2_done        0xA1AA
-#define        dagc2_done_pos 4
-#define        dagc2_done_len 1
-#define        dagc2_done_lsb 0
-#define xd_p_reg_dca_en        0xA1AB
-#define        reg_dca_en_pos 0
-#define        reg_dca_en_len 1
-#define        reg_dca_en_lsb 0
-#define xd_p_dagc2_accumulate_num_2k_7_0       0xA1C0
-#define        dagc2_accumulate_num_2k_7_0_pos 0
-#define        dagc2_accumulate_num_2k_7_0_len 8
-#define        dagc2_accumulate_num_2k_7_0_lsb 0
-#define xd_p_dagc2_accumulate_num_2k_12_8      0xA1C1
-#define        dagc2_accumulate_num_2k_12_8_pos 0
-#define        dagc2_accumulate_num_2k_12_8_len 5
-#define        dagc2_accumulate_num_2k_12_8_lsb 8
-#define xd_p_dagc2_accumulate_num_8k_7_0       0xA1C2
-#define        dagc2_accumulate_num_8k_7_0_pos 0
-#define        dagc2_accumulate_num_8k_7_0_len 8
-#define        dagc2_accumulate_num_8k_7_0_lsb 0
-#define xd_p_dagc2_accumulate_num_8k_12_8      0xA1C3
-#define        dagc2_accumulate_num_8k_12_8_pos 0
-#define        dagc2_accumulate_num_8k_12_8_len 5
-#define        dagc2_accumulate_num_8k_12_8_lsb 8
-#define xd_p_dagc2_desired_level_2_0   0xA1C3
-#define        dagc2_desired_level_2_0_pos 5
-#define        dagc2_desired_level_2_0_len 3
-#define        dagc2_desired_level_2_0_lsb 0
-#define xd_p_dagc2_desired_level_8_3   0xA1C4
-#define        dagc2_desired_level_8_3_pos 0
-#define        dagc2_desired_level_8_3_len 6
-#define        dagc2_desired_level_8_3_lsb 3
-#define xd_p_dagc2_apply_delay 0xA1C5
-#define        dagc2_apply_delay_pos 0
-#define        dagc2_apply_delay_len 7
-#define        dagc2_apply_delay_lsb 0
-#define xd_p_dagc2_bypass_scale_ctl    0xA1C6
-#define        dagc2_bypass_scale_ctl_pos 0
-#define        dagc2_bypass_scale_ctl_len 3
-#define        dagc2_bypass_scale_ctl_lsb 0
-#define xd_p_dagc2_programmable_shift1 0xA1C7
-#define        dagc2_programmable_shift1_pos 0
-#define        dagc2_programmable_shift1_len 8
-#define        dagc2_programmable_shift1_lsb 0
-#define xd_p_dagc2_programmable_shift2 0xA1C8
-#define        dagc2_programmable_shift2_pos 0
-#define        dagc2_programmable_shift2_len 8
-#define        dagc2_programmable_shift2_lsb 0
-#define xd_p_reg_dagc2_in_sat_cnt_7_0  0xA1C9
-#define        reg_dagc2_in_sat_cnt_7_0_pos 0
-#define        reg_dagc2_in_sat_cnt_7_0_len 8
-#define        reg_dagc2_in_sat_cnt_7_0_lsb 0
-#define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA
-#define        reg_dagc2_in_sat_cnt_15_8_pos 0
-#define        reg_dagc2_in_sat_cnt_15_8_len 8
-#define        reg_dagc2_in_sat_cnt_15_8_lsb 8
-#define xd_p_reg_dagc2_in_sat_cnt_23_16        0xA1CB
-#define        reg_dagc2_in_sat_cnt_23_16_pos 0
-#define        reg_dagc2_in_sat_cnt_23_16_len 8
-#define        reg_dagc2_in_sat_cnt_23_16_lsb 16
-#define xd_p_reg_dagc2_in_sat_cnt_31_24        0xA1CC
-#define        reg_dagc2_in_sat_cnt_31_24_pos 0
-#define        reg_dagc2_in_sat_cnt_31_24_len 8
-#define        reg_dagc2_in_sat_cnt_31_24_lsb 24
-#define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD
-#define        reg_dagc2_out_sat_cnt_7_0_pos 0
-#define        reg_dagc2_out_sat_cnt_7_0_len 8
-#define        reg_dagc2_out_sat_cnt_7_0_lsb 0
-#define xd_p_reg_dagc2_out_sat_cnt_15_8        0xA1CE
-#define        reg_dagc2_out_sat_cnt_15_8_pos 0
-#define        reg_dagc2_out_sat_cnt_15_8_len 8
-#define        reg_dagc2_out_sat_cnt_15_8_lsb 8
-#define xd_p_reg_dagc2_out_sat_cnt_23_16       0xA1CF
-#define        reg_dagc2_out_sat_cnt_23_16_pos 0
-#define        reg_dagc2_out_sat_cnt_23_16_len 8
-#define        reg_dagc2_out_sat_cnt_23_16_lsb 16
-#define xd_p_reg_dagc2_out_sat_cnt_31_24       0xA1D0
-#define        reg_dagc2_out_sat_cnt_31_24_pos 0
-#define        reg_dagc2_out_sat_cnt_31_24_len 8
-#define        reg_dagc2_out_sat_cnt_31_24_lsb 24
-#define xd_r_dagc2_multiplier_7_0      0xA1D6
-#define        dagc2_multiplier_7_0_pos 0
-#define        dagc2_multiplier_7_0_len 8
-#define        dagc2_multiplier_7_0_lsb 0
-#define xd_r_dagc2_multiplier_15_8     0xA1D7
-#define        dagc2_multiplier_15_8_pos 0
-#define        dagc2_multiplier_15_8_len 8
-#define        dagc2_multiplier_15_8_lsb 8
-#define xd_r_dagc2_right_shift_bits    0xA1D8
-#define        dagc2_right_shift_bits_pos 0
-#define        dagc2_right_shift_bits_len 4
-#define        dagc2_right_shift_bits_lsb 0
-#define xd_p_cfoe_NS_coeff1_7_0        0xA200
-#define        cfoe_NS_coeff1_7_0_pos 0
-#define        cfoe_NS_coeff1_7_0_len 8
-#define        cfoe_NS_coeff1_7_0_lsb 0
-#define xd_p_cfoe_NS_coeff1_15_8       0xA201
-#define        cfoe_NS_coeff1_15_8_pos 0
-#define        cfoe_NS_coeff1_15_8_len 8
-#define        cfoe_NS_coeff1_15_8_lsb 8
-#define xd_p_cfoe_NS_coeff1_23_16      0xA202
-#define        cfoe_NS_coeff1_23_16_pos 0
-#define        cfoe_NS_coeff1_23_16_len 8
-#define        cfoe_NS_coeff1_23_16_lsb 16
-#define xd_p_cfoe_NS_coeff1_25_24      0xA203
-#define        cfoe_NS_coeff1_25_24_pos 0
-#define        cfoe_NS_coeff1_25_24_len 2
-#define        cfoe_NS_coeff1_25_24_lsb 24
-#define xd_p_cfoe_NS_coeff2_5_0        0xA203
-#define        cfoe_NS_coeff2_5_0_pos 2
-#define        cfoe_NS_coeff2_5_0_len 6
-#define        cfoe_NS_coeff2_5_0_lsb 0
-#define xd_p_cfoe_NS_coeff2_13_6       0xA204
-#define        cfoe_NS_coeff2_13_6_pos 0
-#define        cfoe_NS_coeff2_13_6_len 8
-#define        cfoe_NS_coeff2_13_6_lsb 6
-#define xd_p_cfoe_NS_coeff2_21_14      0xA205
-#define        cfoe_NS_coeff2_21_14_pos 0
-#define        cfoe_NS_coeff2_21_14_len 8
-#define        cfoe_NS_coeff2_21_14_lsb 14
-#define xd_p_cfoe_NS_coeff2_24_22      0xA206
-#define        cfoe_NS_coeff2_24_22_pos 0
-#define        cfoe_NS_coeff2_24_22_len 3
-#define        cfoe_NS_coeff2_24_22_lsb 22
-#define xd_p_cfoe_lf_c1_4_0    0xA206
-#define        cfoe_lf_c1_4_0_pos 3
-#define        cfoe_lf_c1_4_0_len 5
-#define        cfoe_lf_c1_4_0_lsb 0
-#define xd_p_cfoe_lf_c1_12_5   0xA207
-#define        cfoe_lf_c1_12_5_pos 0
-#define        cfoe_lf_c1_12_5_len 8
-#define        cfoe_lf_c1_12_5_lsb 5
-#define xd_p_cfoe_lf_c1_20_13  0xA208
-#define        cfoe_lf_c1_20_13_pos 0
-#define        cfoe_lf_c1_20_13_len 8
-#define        cfoe_lf_c1_20_13_lsb 13
-#define xd_p_cfoe_lf_c1_25_21  0xA209
-#define        cfoe_lf_c1_25_21_pos 0
-#define        cfoe_lf_c1_25_21_len 5
-#define        cfoe_lf_c1_25_21_lsb 21
-#define xd_p_cfoe_lf_c2_2_0    0xA209
-#define        cfoe_lf_c2_2_0_pos 5
-#define        cfoe_lf_c2_2_0_len 3
-#define        cfoe_lf_c2_2_0_lsb 0
-#define xd_p_cfoe_lf_c2_10_3   0xA20A
-#define        cfoe_lf_c2_10_3_pos 0
-#define        cfoe_lf_c2_10_3_len 8
-#define        cfoe_lf_c2_10_3_lsb 3
-#define xd_p_cfoe_lf_c2_18_11  0xA20B
-#define        cfoe_lf_c2_18_11_pos 0
-#define        cfoe_lf_c2_18_11_len 8
-#define        cfoe_lf_c2_18_11_lsb 11
-#define xd_p_cfoe_lf_c2_25_19  0xA20C
-#define        cfoe_lf_c2_25_19_pos 0
-#define        cfoe_lf_c2_25_19_len 7
-#define        cfoe_lf_c2_25_19_lsb 19
-#define xd_p_cfoe_ifod_7_0     0xA20D
-#define        cfoe_ifod_7_0_pos 0
-#define        cfoe_ifod_7_0_len 8
-#define        cfoe_ifod_7_0_lsb 0
-#define xd_p_cfoe_ifod_10_8    0xA20E
-#define        cfoe_ifod_10_8_pos 0
-#define        cfoe_ifod_10_8_len 3
-#define        cfoe_ifod_10_8_lsb 8
-#define xd_p_cfoe_Divg_ctr_th  0xA20E
-#define        cfoe_Divg_ctr_th_pos 4
-#define        cfoe_Divg_ctr_th_len 4
-#define        cfoe_Divg_ctr_th_lsb 0
-#define xd_p_cfoe_FOT_divg_th  0xA20F
-#define        cfoe_FOT_divg_th_pos 0
-#define        cfoe_FOT_divg_th_len 8
-#define        cfoe_FOT_divg_th_lsb 0
-#define xd_p_cfoe_FOT_cnvg_th  0xA210
-#define        cfoe_FOT_cnvg_th_pos 0
-#define        cfoe_FOT_cnvg_th_len 8
-#define        cfoe_FOT_cnvg_th_lsb 0
-#define xd_p_reg_cfoe_offset_7_0       0xA211
-#define        reg_cfoe_offset_7_0_pos 0
-#define        reg_cfoe_offset_7_0_len 8
-#define        reg_cfoe_offset_7_0_lsb 0
-#define xd_p_reg_cfoe_offset_9_8       0xA212
-#define        reg_cfoe_offset_9_8_pos 0
-#define        reg_cfoe_offset_9_8_len 2
-#define        reg_cfoe_offset_9_8_lsb 8
-#define xd_p_reg_cfoe_ifoe_sign_corr   0xA212
-#define        reg_cfoe_ifoe_sign_corr_pos 2
-#define        reg_cfoe_ifoe_sign_corr_len 1
-#define        reg_cfoe_ifoe_sign_corr_lsb 0
-#define xd_r_cfoe_fot_LF_output_7_0    0xA218
-#define        cfoe_fot_LF_output_7_0_pos 0
-#define        cfoe_fot_LF_output_7_0_len 8
-#define        cfoe_fot_LF_output_7_0_lsb 0
-#define xd_r_cfoe_fot_LF_output_15_8   0xA219
-#define        cfoe_fot_LF_output_15_8_pos 0
-#define        cfoe_fot_LF_output_15_8_len 8
-#define        cfoe_fot_LF_output_15_8_lsb 8
-#define xd_r_cfoe_ifo_metric_7_0       0xA21A
-#define        cfoe_ifo_metric_7_0_pos 0
-#define        cfoe_ifo_metric_7_0_len 8
-#define        cfoe_ifo_metric_7_0_lsb 0
-#define xd_r_cfoe_ifo_metric_15_8      0xA21B
-#define        cfoe_ifo_metric_15_8_pos 0
-#define        cfoe_ifo_metric_15_8_len 8
-#define        cfoe_ifo_metric_15_8_lsb 8
-#define xd_r_cfoe_ifo_metric_23_16     0xA21C
-#define        cfoe_ifo_metric_23_16_pos 0
-#define        cfoe_ifo_metric_23_16_len 8
-#define        cfoe_ifo_metric_23_16_lsb 16
-#define xd_p_ste_Nu    0xA220
-#define        ste_Nu_pos 0
-#define        ste_Nu_len 2
-#define        ste_Nu_lsb 0
-#define xd_p_ste_GI    0xA220
-#define        ste_GI_pos 2
-#define        ste_GI_len 3
-#define        ste_GI_lsb 0
-#define xd_p_ste_symbol_num    0xA221
-#define        ste_symbol_num_pos 0
-#define        ste_symbol_num_len 2
-#define        ste_symbol_num_lsb 0
-#define xd_p_ste_sample_num    0xA221
-#define        ste_sample_num_pos 2
-#define        ste_sample_num_len 2
-#define        ste_sample_num_lsb 0
-#define xd_p_reg_ste_buf_en    0xA221
-#define        reg_ste_buf_en_pos 7
-#define        reg_ste_buf_en_len 1
-#define        reg_ste_buf_en_lsb 0
-#define xd_p_ste_FFT_offset_7_0        0xA222
-#define        ste_FFT_offset_7_0_pos 0
-#define        ste_FFT_offset_7_0_len 8
-#define        ste_FFT_offset_7_0_lsb 0
-#define xd_p_ste_FFT_offset_11_8       0xA223
-#define        ste_FFT_offset_11_8_pos 0
-#define        ste_FFT_offset_11_8_len 4
-#define        ste_FFT_offset_11_8_lsb 8
-#define xd_p_reg_ste_tstmod    0xA223
-#define        reg_ste_tstmod_pos 5
-#define        reg_ste_tstmod_len 1
-#define        reg_ste_tstmod_lsb 0
-#define xd_p_ste_adv_start_7_0 0xA224
-#define        ste_adv_start_7_0_pos 0
-#define        ste_adv_start_7_0_len 8
-#define        ste_adv_start_7_0_lsb 0
-#define xd_p_ste_adv_start_10_8        0xA225
-#define        ste_adv_start_10_8_pos 0
-#define        ste_adv_start_10_8_len 3
-#define        ste_adv_start_10_8_lsb 8
-#define xd_p_ste_adv_stop      0xA226
-#define        ste_adv_stop_pos 0
-#define        ste_adv_stop_len 8
-#define        ste_adv_stop_lsb 0
-#define xd_r_ste_P_value_7_0   0xA228
-#define        ste_P_value_7_0_pos 0
-#define        ste_P_value_7_0_len 8
-#define        ste_P_value_7_0_lsb 0
-#define xd_r_ste_P_value_10_8  0xA229
-#define        ste_P_value_10_8_pos 0
-#define        ste_P_value_10_8_len 3
-#define        ste_P_value_10_8_lsb 8
-#define xd_r_ste_M_value_7_0   0xA22A
-#define        ste_M_value_7_0_pos 0
-#define        ste_M_value_7_0_len 8
-#define        ste_M_value_7_0_lsb 0
-#define xd_r_ste_M_value_10_8  0xA22B
-#define        ste_M_value_10_8_pos 0
-#define        ste_M_value_10_8_len 3
-#define        ste_M_value_10_8_lsb 8
-#define xd_r_ste_H1    0xA22C
-#define        ste_H1_pos 0
-#define        ste_H1_len 7
-#define        ste_H1_lsb 0
-#define xd_r_ste_H2    0xA22D
-#define        ste_H2_pos 0
-#define        ste_H2_len 7
-#define        ste_H2_lsb 0
-#define xd_r_ste_H3    0xA22E
-#define        ste_H3_pos 0
-#define        ste_H3_len 7
-#define        ste_H3_lsb 0
-#define xd_r_ste_H4    0xA22F
-#define        ste_H4_pos 0
-#define        ste_H4_len 7
-#define        ste_H4_lsb 0
-#define xd_r_ste_Corr_value_I_7_0      0xA230
-#define        ste_Corr_value_I_7_0_pos 0
-#define        ste_Corr_value_I_7_0_len 8
-#define        ste_Corr_value_I_7_0_lsb 0
-#define xd_r_ste_Corr_value_I_15_8     0xA231
-#define        ste_Corr_value_I_15_8_pos 0
-#define        ste_Corr_value_I_15_8_len 8
-#define        ste_Corr_value_I_15_8_lsb 8
-#define xd_r_ste_Corr_value_I_23_16    0xA232
-#define        ste_Corr_value_I_23_16_pos 0
-#define        ste_Corr_value_I_23_16_len 8
-#define        ste_Corr_value_I_23_16_lsb 16
-#define xd_r_ste_Corr_value_I_27_24    0xA233
-#define        ste_Corr_value_I_27_24_pos 0
-#define        ste_Corr_value_I_27_24_len 4
-#define        ste_Corr_value_I_27_24_lsb 24
-#define xd_r_ste_Corr_value_Q_7_0      0xA234
-#define        ste_Corr_value_Q_7_0_pos 0
-#define        ste_Corr_value_Q_7_0_len 8
-#define        ste_Corr_value_Q_7_0_lsb 0
-#define xd_r_ste_Corr_value_Q_15_8     0xA235
-#define        ste_Corr_value_Q_15_8_pos 0
-#define        ste_Corr_value_Q_15_8_len 8
-#define        ste_Corr_value_Q_15_8_lsb 8
-#define xd_r_ste_Corr_value_Q_23_16    0xA236
-#define        ste_Corr_value_Q_23_16_pos 0
-#define        ste_Corr_value_Q_23_16_len 8
-#define        ste_Corr_value_Q_23_16_lsb 16
-#define xd_r_ste_Corr_value_Q_27_24    0xA237
-#define        ste_Corr_value_Q_27_24_pos 0
-#define        ste_Corr_value_Q_27_24_len 4
-#define        ste_Corr_value_Q_27_24_lsb 24
-#define xd_r_ste_J_num_7_0     0xA238
-#define        ste_J_num_7_0_pos 0
-#define        ste_J_num_7_0_len 8
-#define        ste_J_num_7_0_lsb 0
-#define xd_r_ste_J_num_15_8    0xA239
-#define        ste_J_num_15_8_pos 0
-#define        ste_J_num_15_8_len 8
-#define        ste_J_num_15_8_lsb 8
-#define xd_r_ste_J_num_23_16   0xA23A
-#define        ste_J_num_23_16_pos 0
-#define        ste_J_num_23_16_len 8
-#define        ste_J_num_23_16_lsb 16
-#define xd_r_ste_J_num_31_24   0xA23B
-#define        ste_J_num_31_24_pos 0
-#define        ste_J_num_31_24_len 8
-#define        ste_J_num_31_24_lsb 24
-#define xd_r_ste_J_den_7_0     0xA23C
-#define        ste_J_den_7_0_pos 0
-#define        ste_J_den_7_0_len 8
-#define        ste_J_den_7_0_lsb 0
-#define xd_r_ste_J_den_15_8    0xA23D
-#define        ste_J_den_15_8_pos 0
-#define        ste_J_den_15_8_len 8
-#define        ste_J_den_15_8_lsb 8
-#define xd_r_ste_J_den_18_16   0xA23E
-#define        ste_J_den_18_16_pos 0
-#define        ste_J_den_18_16_len 3
-#define        ste_J_den_18_16_lsb 16
-#define xd_r_ste_Beacon_Indicator      0xA23E
-#define        ste_Beacon_Indicator_pos 4
-#define        ste_Beacon_Indicator_len 1
-#define        ste_Beacon_Indicator_lsb 0
-#define xd_r_tpsd_Frame_Num    0xA250
-#define        tpsd_Frame_Num_pos 0
-#define        tpsd_Frame_Num_len 2
-#define        tpsd_Frame_Num_lsb 0
-#define xd_r_tpsd_Constel      0xA250
-#define        tpsd_Constel_pos 2
-#define        tpsd_Constel_len 2
-#define        tpsd_Constel_lsb 0
-#define xd_r_tpsd_GI   0xA250
-#define        tpsd_GI_pos 4
-#define        tpsd_GI_len 2
-#define        tpsd_GI_lsb 0
-#define xd_r_tpsd_Mode 0xA250
-#define        tpsd_Mode_pos 6
-#define        tpsd_Mode_len 2
-#define        tpsd_Mode_lsb 0
-#define xd_r_tpsd_CR_HP        0xA251
-#define        tpsd_CR_HP_pos 0
-#define        tpsd_CR_HP_len 3
-#define        tpsd_CR_HP_lsb 0
-#define xd_r_tpsd_CR_LP        0xA251
-#define        tpsd_CR_LP_pos 3
-#define        tpsd_CR_LP_len 3
-#define        tpsd_CR_LP_lsb 0
-#define xd_r_tpsd_Hie  0xA252
-#define        tpsd_Hie_pos 0
-#define        tpsd_Hie_len 3
-#define        tpsd_Hie_lsb 0
-#define xd_r_tpsd_Res_Bits     0xA252
-#define        tpsd_Res_Bits_pos 3
-#define        tpsd_Res_Bits_len 5
-#define        tpsd_Res_Bits_lsb 0
-#define xd_r_tpsd_Res_Bits_0   0xA253
-#define        tpsd_Res_Bits_0_pos 0
-#define        tpsd_Res_Bits_0_len 1
-#define        tpsd_Res_Bits_0_lsb 0
-#define xd_r_tpsd_LengthInd    0xA253
-#define        tpsd_LengthInd_pos 1
-#define        tpsd_LengthInd_len 6
-#define        tpsd_LengthInd_lsb 0
-#define xd_r_tpsd_Cell_Id_7_0  0xA254
-#define        tpsd_Cell_Id_7_0_pos 0
-#define        tpsd_Cell_Id_7_0_len 8
-#define        tpsd_Cell_Id_7_0_lsb 0
-#define xd_r_tpsd_Cell_Id_15_8 0xA255
-#define        tpsd_Cell_Id_15_8_pos 0
-#define        tpsd_Cell_Id_15_8_len 8
-#define        tpsd_Cell_Id_15_8_lsb 0
-#define xd_p_reg_fft_mask_tone0_7_0    0xA260
-#define        reg_fft_mask_tone0_7_0_pos 0
-#define        reg_fft_mask_tone0_7_0_len 8
-#define        reg_fft_mask_tone0_7_0_lsb 0
-#define xd_p_reg_fft_mask_tone0_12_8   0xA261
-#define        reg_fft_mask_tone0_12_8_pos 0
-#define        reg_fft_mask_tone0_12_8_len 5
-#define        reg_fft_mask_tone0_12_8_lsb 8
-#define xd_p_reg_fft_mask_tone1_7_0    0xA262
-#define        reg_fft_mask_tone1_7_0_pos 0
-#define        reg_fft_mask_tone1_7_0_len 8
-#define        reg_fft_mask_tone1_7_0_lsb 0
-#define xd_p_reg_fft_mask_tone1_12_8   0xA263
-#define        reg_fft_mask_tone1_12_8_pos 0
-#define        reg_fft_mask_tone1_12_8_len 5
-#define        reg_fft_mask_tone1_12_8_lsb 8
-#define xd_p_reg_fft_mask_tone2_7_0    0xA264
-#define        reg_fft_mask_tone2_7_0_pos 0
-#define        reg_fft_mask_tone2_7_0_len 8
-#define        reg_fft_mask_tone2_7_0_lsb 0
-#define xd_p_reg_fft_mask_tone2_12_8   0xA265
-#define        reg_fft_mask_tone2_12_8_pos 0
-#define        reg_fft_mask_tone2_12_8_len 5
-#define        reg_fft_mask_tone2_12_8_lsb 8
-#define xd_p_reg_fft_mask_tone3_7_0    0xA266
-#define        reg_fft_mask_tone3_7_0_pos 0
-#define        reg_fft_mask_tone3_7_0_len 8
-#define        reg_fft_mask_tone3_7_0_lsb 0
-#define xd_p_reg_fft_mask_tone3_12_8   0xA267
-#define        reg_fft_mask_tone3_12_8_pos 0
-#define        reg_fft_mask_tone3_12_8_len 5
-#define        reg_fft_mask_tone3_12_8_lsb 8
-#define xd_p_reg_fft_mask_from0_7_0    0xA268
-#define        reg_fft_mask_from0_7_0_pos 0
-#define        reg_fft_mask_from0_7_0_len 8
-#define        reg_fft_mask_from0_7_0_lsb 0
-#define xd_p_reg_fft_mask_from0_12_8   0xA269
-#define        reg_fft_mask_from0_12_8_pos 0
-#define        reg_fft_mask_from0_12_8_len 5
-#define        reg_fft_mask_from0_12_8_lsb 8
-#define xd_p_reg_fft_mask_to0_7_0      0xA26A
-#define        reg_fft_mask_to0_7_0_pos 0
-#define        reg_fft_mask_to0_7_0_len 8
-#define        reg_fft_mask_to0_7_0_lsb 0
-#define xd_p_reg_fft_mask_to0_12_8     0xA26B
-#define        reg_fft_mask_to0_12_8_pos 0
-#define        reg_fft_mask_to0_12_8_len 5
-#define        reg_fft_mask_to0_12_8_lsb 8
-#define xd_p_reg_fft_mask_from1_7_0    0xA26C
-#define        reg_fft_mask_from1_7_0_pos 0
-#define        reg_fft_mask_from1_7_0_len 8
-#define        reg_fft_mask_from1_7_0_lsb 0
-#define xd_p_reg_fft_mask_from1_12_8   0xA26D
-#define        reg_fft_mask_from1_12_8_pos 0
-#define        reg_fft_mask_from1_12_8_len 5
-#define        reg_fft_mask_from1_12_8_lsb 8
-#define xd_p_reg_fft_mask_to1_7_0      0xA26E
-#define        reg_fft_mask_to1_7_0_pos 0
-#define        reg_fft_mask_to1_7_0_len 8
-#define        reg_fft_mask_to1_7_0_lsb 0
-#define xd_p_reg_fft_mask_to1_12_8     0xA26F
-#define        reg_fft_mask_to1_12_8_pos 0
-#define        reg_fft_mask_to1_12_8_len 5
-#define        reg_fft_mask_to1_12_8_lsb 8
-#define xd_p_reg_cge_idx0_7_0  0xA280
-#define        reg_cge_idx0_7_0_pos 0
-#define        reg_cge_idx0_7_0_len 8
-#define        reg_cge_idx0_7_0_lsb 0
-#define xd_p_reg_cge_idx0_12_8 0xA281
-#define        reg_cge_idx0_12_8_pos 0
-#define        reg_cge_idx0_12_8_len 5
-#define        reg_cge_idx0_12_8_lsb 8
-#define xd_p_reg_cge_idx1_7_0  0xA282
-#define        reg_cge_idx1_7_0_pos 0
-#define        reg_cge_idx1_7_0_len 8
-#define        reg_cge_idx1_7_0_lsb 0
-#define xd_p_reg_cge_idx1_12_8 0xA283
-#define        reg_cge_idx1_12_8_pos 0
-#define        reg_cge_idx1_12_8_len 5
-#define        reg_cge_idx1_12_8_lsb 8
-#define xd_p_reg_cge_idx2_7_0  0xA284
-#define        reg_cge_idx2_7_0_pos 0
-#define        reg_cge_idx2_7_0_len 8
-#define        reg_cge_idx2_7_0_lsb 0
-#define xd_p_reg_cge_idx2_12_8 0xA285
-#define        reg_cge_idx2_12_8_pos 0
-#define        reg_cge_idx2_12_8_len 5
-#define        reg_cge_idx2_12_8_lsb 8
-#define xd_p_reg_cge_idx3_7_0  0xA286
-#define        reg_cge_idx3_7_0_pos 0
-#define        reg_cge_idx3_7_0_len 8
-#define        reg_cge_idx3_7_0_lsb 0
-#define xd_p_reg_cge_idx3_12_8 0xA287
-#define        reg_cge_idx3_12_8_pos 0
-#define        reg_cge_idx3_12_8_len 5
-#define        reg_cge_idx3_12_8_lsb 8
-#define xd_p_reg_cge_idx4_7_0  0xA288
-#define        reg_cge_idx4_7_0_pos 0
-#define        reg_cge_idx4_7_0_len 8
-#define        reg_cge_idx4_7_0_lsb 0
-#define xd_p_reg_cge_idx4_12_8 0xA289
-#define        reg_cge_idx4_12_8_pos 0
-#define        reg_cge_idx4_12_8_len 5
-#define        reg_cge_idx4_12_8_lsb 8
-#define xd_p_reg_cge_idx5_7_0  0xA28A
-#define        reg_cge_idx5_7_0_pos 0
-#define        reg_cge_idx5_7_0_len 8
-#define        reg_cge_idx5_7_0_lsb 0
-#define xd_p_reg_cge_idx5_12_8 0xA28B
-#define        reg_cge_idx5_12_8_pos 0
-#define        reg_cge_idx5_12_8_len 5
-#define        reg_cge_idx5_12_8_lsb 8
-#define xd_p_reg_cge_idx6_7_0  0xA28C
-#define        reg_cge_idx6_7_0_pos 0
-#define        reg_cge_idx6_7_0_len 8
-#define        reg_cge_idx6_7_0_lsb 0
-#define xd_p_reg_cge_idx6_12_8 0xA28D
-#define        reg_cge_idx6_12_8_pos 0
-#define        reg_cge_idx6_12_8_len 5
-#define        reg_cge_idx6_12_8_lsb 8
-#define xd_p_reg_cge_idx7_7_0  0xA28E
-#define        reg_cge_idx7_7_0_pos 0
-#define        reg_cge_idx7_7_0_len 8
-#define        reg_cge_idx7_7_0_lsb 0
-#define xd_p_reg_cge_idx7_12_8 0xA28F
-#define        reg_cge_idx7_12_8_pos 0
-#define        reg_cge_idx7_12_8_len 5
-#define        reg_cge_idx7_12_8_lsb 8
-#define xd_p_reg_cge_idx8_7_0  0xA290
-#define        reg_cge_idx8_7_0_pos 0
-#define        reg_cge_idx8_7_0_len 8
-#define        reg_cge_idx8_7_0_lsb 0
-#define xd_p_reg_cge_idx8_12_8 0xA291
-#define        reg_cge_idx8_12_8_pos 0
-#define        reg_cge_idx8_12_8_len 5
-#define        reg_cge_idx8_12_8_lsb 8
-#define xd_p_reg_cge_idx9_7_0  0xA292
-#define        reg_cge_idx9_7_0_pos 0
-#define        reg_cge_idx9_7_0_len 8
-#define        reg_cge_idx9_7_0_lsb 0
-#define xd_p_reg_cge_idx9_12_8 0xA293
-#define        reg_cge_idx9_12_8_pos 0
-#define        reg_cge_idx9_12_8_len 5
-#define        reg_cge_idx9_12_8_lsb 8
-#define xd_p_reg_cge_idx10_7_0 0xA294
-#define        reg_cge_idx10_7_0_pos 0
-#define        reg_cge_idx10_7_0_len 8
-#define        reg_cge_idx10_7_0_lsb 0
-#define xd_p_reg_cge_idx10_12_8        0xA295
-#define        reg_cge_idx10_12_8_pos 0
-#define        reg_cge_idx10_12_8_len 5
-#define        reg_cge_idx10_12_8_lsb 8
-#define xd_p_reg_cge_idx11_7_0 0xA296
-#define        reg_cge_idx11_7_0_pos 0
-#define        reg_cge_idx11_7_0_len 8
-#define        reg_cge_idx11_7_0_lsb 0
-#define xd_p_reg_cge_idx11_12_8        0xA297
-#define        reg_cge_idx11_12_8_pos 0
-#define        reg_cge_idx11_12_8_len 5
-#define        reg_cge_idx11_12_8_lsb 8
-#define xd_p_reg_cge_idx12_7_0 0xA298
-#define        reg_cge_idx12_7_0_pos 0
-#define        reg_cge_idx12_7_0_len 8
-#define        reg_cge_idx12_7_0_lsb 0
-#define xd_p_reg_cge_idx12_12_8        0xA299
-#define        reg_cge_idx12_12_8_pos 0
-#define        reg_cge_idx12_12_8_len 5
-#define        reg_cge_idx12_12_8_lsb 8
-#define xd_p_reg_cge_idx13_7_0 0xA29A
-#define        reg_cge_idx13_7_0_pos 0
-#define        reg_cge_idx13_7_0_len 8
-#define        reg_cge_idx13_7_0_lsb 0
-#define xd_p_reg_cge_idx13_12_8        0xA29B
-#define        reg_cge_idx13_12_8_pos 0
-#define        reg_cge_idx13_12_8_len 5
-#define        reg_cge_idx13_12_8_lsb 8
-#define xd_p_reg_cge_idx14_7_0 0xA29C
-#define        reg_cge_idx14_7_0_pos 0
-#define        reg_cge_idx14_7_0_len 8
-#define        reg_cge_idx14_7_0_lsb 0
-#define xd_p_reg_cge_idx14_12_8        0xA29D
-#define        reg_cge_idx14_12_8_pos 0
-#define        reg_cge_idx14_12_8_len 5
-#define        reg_cge_idx14_12_8_lsb 8
-#define xd_p_reg_cge_idx15_7_0 0xA29E
-#define        reg_cge_idx15_7_0_pos 0
-#define        reg_cge_idx15_7_0_len 8
-#define        reg_cge_idx15_7_0_lsb 0
-#define xd_p_reg_cge_idx15_12_8        0xA29F
-#define        reg_cge_idx15_12_8_pos 0
-#define        reg_cge_idx15_12_8_len 5
-#define        reg_cge_idx15_12_8_lsb 8
-#define xd_r_reg_fft_crc       0xA2A8
-#define        reg_fft_crc_pos 0
-#define        reg_fft_crc_len 8
-#define        reg_fft_crc_lsb 0
-#define xd_p_fd_fft_shift_max  0xA2A9
-#define        fd_fft_shift_max_pos 0
-#define        fd_fft_shift_max_len 4
-#define        fd_fft_shift_max_lsb 0
-#define xd_r_fd_fft_shift      0xA2A9
-#define        fd_fft_shift_pos 4
-#define        fd_fft_shift_len 4
-#define        fd_fft_shift_lsb 0
-#define xd_r_fd_fft_frame_num  0xA2AA
-#define        fd_fft_frame_num_pos 0
-#define        fd_fft_frame_num_len 2
-#define        fd_fft_frame_num_lsb 0
-#define xd_r_fd_fft_symbol_count       0xA2AB
-#define        fd_fft_symbol_count_pos 0
-#define        fd_fft_symbol_count_len 7
-#define        fd_fft_symbol_count_lsb 0
-#define xd_r_reg_fft_idx_max_7_0       0xA2AC
-#define        reg_fft_idx_max_7_0_pos 0
-#define        reg_fft_idx_max_7_0_len 8
-#define        reg_fft_idx_max_7_0_lsb 0
-#define xd_r_reg_fft_idx_max_12_8      0xA2AD
-#define        reg_fft_idx_max_12_8_pos 0
-#define        reg_fft_idx_max_12_8_len 5
-#define        reg_fft_idx_max_12_8_lsb 8
-#define xd_p_reg_cge_program   0xA2AE
-#define        reg_cge_program_pos 0
-#define        reg_cge_program_len 1
-#define        reg_cge_program_lsb 0
-#define xd_p_reg_cge_fixed     0xA2AE
-#define        reg_cge_fixed_pos 1
-#define        reg_cge_fixed_len 1
-#define        reg_cge_fixed_lsb 0
-#define xd_p_reg_fft_rotate_en 0xA2AE
-#define        reg_fft_rotate_en_pos 2
-#define        reg_fft_rotate_en_len 1
-#define        reg_fft_rotate_en_lsb 0
-#define xd_p_reg_fft_rotate_base_4_0   0xA2AE
-#define        reg_fft_rotate_base_4_0_pos 3
-#define        reg_fft_rotate_base_4_0_len 5
-#define        reg_fft_rotate_base_4_0_lsb 0
-#define xd_p_reg_fft_rotate_base_12_5  0xA2AF
-#define        reg_fft_rotate_base_12_5_pos 0
-#define        reg_fft_rotate_base_12_5_len 8
-#define        reg_fft_rotate_base_12_5_lsb 5
-#define xd_p_reg_gp_trigger_fd 0xA2B8
-#define        reg_gp_trigger_fd_pos 0
-#define        reg_gp_trigger_fd_len 1
-#define        reg_gp_trigger_fd_lsb 0
-#define xd_p_reg_trigger_sel_fd        0xA2B8
-#define        reg_trigger_sel_fd_pos 1
-#define        reg_trigger_sel_fd_len 2
-#define        reg_trigger_sel_fd_lsb 0
-#define xd_p_reg_trigger_module_sel_fd 0xA2B9
-#define        reg_trigger_module_sel_fd_pos 0
-#define        reg_trigger_module_sel_fd_len 6
-#define        reg_trigger_module_sel_fd_lsb 0
-#define xd_p_reg_trigger_set_sel_fd    0xA2BA
-#define        reg_trigger_set_sel_fd_pos 0
-#define        reg_trigger_set_sel_fd_len 6
-#define        reg_trigger_set_sel_fd_lsb 0
-#define xd_p_reg_fd_noname_7_0 0xA2BC
-#define        reg_fd_noname_7_0_pos 0
-#define        reg_fd_noname_7_0_len 8
-#define        reg_fd_noname_7_0_lsb 0
-#define xd_p_reg_fd_noname_15_8        0xA2BD
-#define        reg_fd_noname_15_8_pos 0
-#define        reg_fd_noname_15_8_len 8
-#define        reg_fd_noname_15_8_lsb 8
-#define xd_p_reg_fd_noname_23_16       0xA2BE
-#define        reg_fd_noname_23_16_pos 0
-#define        reg_fd_noname_23_16_len 8
-#define        reg_fd_noname_23_16_lsb 16
-#define xd_p_reg_fd_noname_31_24       0xA2BF
-#define        reg_fd_noname_31_24_pos 0
-#define        reg_fd_noname_31_24_len 8
-#define        reg_fd_noname_31_24_lsb 24
-#define xd_r_fd_fpcc_cp_corr_signn     0xA2C0
-#define        fd_fpcc_cp_corr_signn_pos 0
-#define        fd_fpcc_cp_corr_signn_len 8
-#define        fd_fpcc_cp_corr_signn_lsb 0
-#define xd_p_reg_feq_s1        0xA2C1
-#define        reg_feq_s1_pos 0
-#define        reg_feq_s1_len 5
-#define        reg_feq_s1_lsb 0
-#define xd_p_fd_fpcc_cp_corr_tone_th   0xA2C2
-#define        fd_fpcc_cp_corr_tone_th_pos 0
-#define        fd_fpcc_cp_corr_tone_th_len 6
-#define        fd_fpcc_cp_corr_tone_th_lsb 0
-#define xd_p_fd_fpcc_cp_corr_symbol_log_th     0xA2C3
-#define        fd_fpcc_cp_corr_symbol_log_th_pos 0
-#define        fd_fpcc_cp_corr_symbol_log_th_len 4
-#define        fd_fpcc_cp_corr_symbol_log_th_lsb 0
-#define xd_p_fd_fpcc_cp_corr_int       0xA2C4
-#define        fd_fpcc_cp_corr_int_pos 0
-#define        fd_fpcc_cp_corr_int_len 1
-#define        fd_fpcc_cp_corr_int_lsb 0
-#define xd_p_reg_sfoe_ns_7_0   0xA320
-#define        reg_sfoe_ns_7_0_pos 0
-#define        reg_sfoe_ns_7_0_len 8
-#define        reg_sfoe_ns_7_0_lsb 0
-#define xd_p_reg_sfoe_ns_14_8  0xA321
-#define        reg_sfoe_ns_14_8_pos 0
-#define        reg_sfoe_ns_14_8_len 7
-#define        reg_sfoe_ns_14_8_lsb 8
-#define xd_p_reg_sfoe_c1_7_0   0xA322
-#define        reg_sfoe_c1_7_0_pos 0
-#define        reg_sfoe_c1_7_0_len 8
-#define        reg_sfoe_c1_7_0_lsb 0
-#define xd_p_reg_sfoe_c1_15_8  0xA323
-#define        reg_sfoe_c1_15_8_pos 0
-#define        reg_sfoe_c1_15_8_len 8
-#define        reg_sfoe_c1_15_8_lsb 8
-#define xd_p_reg_sfoe_c1_17_16 0xA324
-#define        reg_sfoe_c1_17_16_pos 0
-#define        reg_sfoe_c1_17_16_len 2
-#define        reg_sfoe_c1_17_16_lsb 16
-#define xd_p_reg_sfoe_c2_7_0   0xA325
-#define        reg_sfoe_c2_7_0_pos 0
-#define        reg_sfoe_c2_7_0_len 8
-#define        reg_sfoe_c2_7_0_lsb 0
-#define xd_p_reg_sfoe_c2_15_8  0xA326
-#define        reg_sfoe_c2_15_8_pos 0
-#define        reg_sfoe_c2_15_8_len 8
-#define        reg_sfoe_c2_15_8_lsb 8
-#define xd_p_reg_sfoe_c2_17_16 0xA327
-#define        reg_sfoe_c2_17_16_pos 0
-#define        reg_sfoe_c2_17_16_len 2
-#define        reg_sfoe_c2_17_16_lsb 16
-#define xd_r_reg_sfoe_out_9_2  0xA328
-#define        reg_sfoe_out_9_2_pos 0
-#define        reg_sfoe_out_9_2_len 8
-#define        reg_sfoe_out_9_2_lsb 0
-#define xd_r_reg_sfoe_out_1_0  0xA329
-#define        reg_sfoe_out_1_0_pos 0
-#define        reg_sfoe_out_1_0_len 2
-#define        reg_sfoe_out_1_0_lsb 0
-#define xd_p_reg_sfoe_lm_counter_th    0xA32A
-#define        reg_sfoe_lm_counter_th_pos 0
-#define        reg_sfoe_lm_counter_th_len 4
-#define        reg_sfoe_lm_counter_th_lsb 0
-#define xd_p_reg_sfoe_convg_th 0xA32B
-#define        reg_sfoe_convg_th_pos 0
-#define        reg_sfoe_convg_th_len 8
-#define        reg_sfoe_convg_th_lsb 0
-#define xd_p_reg_sfoe_divg_th  0xA32C
-#define        reg_sfoe_divg_th_pos 0
-#define        reg_sfoe_divg_th_len 8
-#define        reg_sfoe_divg_th_lsb 0
-#define xd_p_fd_tpsd_en        0xA330
-#define        fd_tpsd_en_pos 0
-#define        fd_tpsd_en_len 1
-#define        fd_tpsd_en_lsb 0
-#define xd_p_fd_tpsd_dis       0xA330
-#define        fd_tpsd_dis_pos 1
-#define        fd_tpsd_dis_len 1
-#define        fd_tpsd_dis_lsb 0
-#define xd_p_fd_tpsd_rst       0xA330
-#define        fd_tpsd_rst_pos 2
-#define        fd_tpsd_rst_len 1
-#define        fd_tpsd_rst_lsb 0
-#define xd_p_fd_tpsd_lock      0xA330
-#define        fd_tpsd_lock_pos 3
-#define        fd_tpsd_lock_len 1
-#define        fd_tpsd_lock_lsb 0
-#define xd_r_fd_tpsd_s19       0xA330
-#define        fd_tpsd_s19_pos 4
-#define        fd_tpsd_s19_len 1
-#define        fd_tpsd_s19_lsb 0
-#define xd_r_fd_tpsd_s17       0xA330
-#define        fd_tpsd_s17_pos 5
-#define        fd_tpsd_s17_len 1
-#define        fd_tpsd_s17_lsb 0
-#define xd_p_fd_sfr_ste_en     0xA331
-#define        fd_sfr_ste_en_pos 0
-#define        fd_sfr_ste_en_len 1
-#define        fd_sfr_ste_en_lsb 0
-#define xd_p_fd_sfr_ste_dis    0xA331
-#define        fd_sfr_ste_dis_pos 1
-#define        fd_sfr_ste_dis_len 1
-#define        fd_sfr_ste_dis_lsb 0
-#define xd_p_fd_sfr_ste_rst    0xA331
-#define        fd_sfr_ste_rst_pos 2
-#define        fd_sfr_ste_rst_len 1
-#define        fd_sfr_ste_rst_lsb 0
-#define xd_p_fd_sfr_ste_mode   0xA331
-#define        fd_sfr_ste_mode_pos 3
-#define        fd_sfr_ste_mode_len 1
-#define        fd_sfr_ste_mode_lsb 0
-#define xd_p_fd_sfr_ste_done   0xA331
-#define        fd_sfr_ste_done_pos 4
-#define        fd_sfr_ste_done_len 1
-#define        fd_sfr_ste_done_lsb 0
-#define xd_p_reg_cfoe_ffoe_en  0xA332
-#define        reg_cfoe_ffoe_en_pos 0
-#define        reg_cfoe_ffoe_en_len 1
-#define        reg_cfoe_ffoe_en_lsb 0
-#define xd_p_reg_cfoe_ffoe_dis 0xA332
-#define        reg_cfoe_ffoe_dis_pos 1
-#define        reg_cfoe_ffoe_dis_len 1
-#define        reg_cfoe_ffoe_dis_lsb 0
-#define xd_p_reg_cfoe_ffoe_rst 0xA332
-#define        reg_cfoe_ffoe_rst_pos 2
-#define        reg_cfoe_ffoe_rst_len 1
-#define        reg_cfoe_ffoe_rst_lsb 0
-#define xd_p_reg_cfoe_ifoe_en  0xA332
-#define        reg_cfoe_ifoe_en_pos 3
-#define        reg_cfoe_ifoe_en_len 1
-#define        reg_cfoe_ifoe_en_lsb 0
-#define xd_p_reg_cfoe_ifoe_dis 0xA332
-#define        reg_cfoe_ifoe_dis_pos 4
-#define        reg_cfoe_ifoe_dis_len 1
-#define        reg_cfoe_ifoe_dis_lsb 0
-#define xd_p_reg_cfoe_ifoe_rst 0xA332
-#define        reg_cfoe_ifoe_rst_pos 5
-#define        reg_cfoe_ifoe_rst_len 1
-#define        reg_cfoe_ifoe_rst_lsb 0
-#define xd_p_reg_cfoe_fot_en   0xA332
-#define        reg_cfoe_fot_en_pos 6
-#define        reg_cfoe_fot_en_len 1
-#define        reg_cfoe_fot_en_lsb 0
-#define xd_p_reg_cfoe_fot_lm_en        0xA332
-#define        reg_cfoe_fot_lm_en_pos 7
-#define        reg_cfoe_fot_lm_en_len 1
-#define        reg_cfoe_fot_lm_en_lsb 0
-#define xd_p_reg_cfoe_fot_rst  0xA333
-#define        reg_cfoe_fot_rst_pos 0
-#define        reg_cfoe_fot_rst_len 1
-#define        reg_cfoe_fot_rst_lsb 0
-#define xd_r_fd_cfoe_ffoe_done 0xA333
-#define        fd_cfoe_ffoe_done_pos 1
-#define        fd_cfoe_ffoe_done_len 1
-#define        fd_cfoe_ffoe_done_lsb 0
-#define xd_p_fd_cfoe_metric_vld        0xA333
-#define        fd_cfoe_metric_vld_pos 2
-#define        fd_cfoe_metric_vld_len 1
-#define        fd_cfoe_metric_vld_lsb 0
-#define xd_p_reg_cfoe_ifod_vld 0xA333
-#define        reg_cfoe_ifod_vld_pos 3
-#define        reg_cfoe_ifod_vld_len 1
-#define        reg_cfoe_ifod_vld_lsb 0
-#define xd_r_fd_cfoe_ifoe_done 0xA333
-#define        fd_cfoe_ifoe_done_pos 4
-#define        fd_cfoe_ifoe_done_len 1
-#define        fd_cfoe_ifoe_done_lsb 0
-#define xd_r_fd_cfoe_fot_valid 0xA333
-#define        fd_cfoe_fot_valid_pos 5
-#define        fd_cfoe_fot_valid_len 1
-#define        fd_cfoe_fot_valid_lsb 0
-#define xd_p_reg_cfoe_divg_int 0xA333
-#define        reg_cfoe_divg_int_pos 6
-#define        reg_cfoe_divg_int_len 1
-#define        reg_cfoe_divg_int_lsb 0
-#define xd_r_reg_cfoe_divg_flag        0xA333
-#define        reg_cfoe_divg_flag_pos 7
-#define        reg_cfoe_divg_flag_len 1
-#define        reg_cfoe_divg_flag_lsb 0
-#define xd_p_reg_sfoe_en       0xA334
-#define        reg_sfoe_en_pos 0
-#define        reg_sfoe_en_len 1
-#define        reg_sfoe_en_lsb 0
-#define xd_p_reg_sfoe_dis      0xA334
-#define        reg_sfoe_dis_pos 1
-#define        reg_sfoe_dis_len 1
-#define        reg_sfoe_dis_lsb 0
-#define xd_p_reg_sfoe_rst      0xA334
-#define        reg_sfoe_rst_pos 2
-#define        reg_sfoe_rst_len 1
-#define        reg_sfoe_rst_lsb 0
-#define xd_p_reg_sfoe_vld_int  0xA334
-#define        reg_sfoe_vld_int_pos 3
-#define        reg_sfoe_vld_int_len 1
-#define        reg_sfoe_vld_int_lsb 0
-#define xd_p_reg_sfoe_lm_en    0xA334
-#define        reg_sfoe_lm_en_pos 4
-#define        reg_sfoe_lm_en_len 1
-#define        reg_sfoe_lm_en_lsb 0
-#define xd_p_reg_sfoe_divg_int 0xA334
-#define        reg_sfoe_divg_int_pos 5
-#define        reg_sfoe_divg_int_len 1
-#define        reg_sfoe_divg_int_lsb 0
-#define xd_r_reg_sfoe_divg_flag        0xA334
-#define        reg_sfoe_divg_flag_pos 6
-#define        reg_sfoe_divg_flag_len 1
-#define        reg_sfoe_divg_flag_lsb 0
-#define xd_p_reg_fft_rst       0xA335
-#define        reg_fft_rst_pos 0
-#define        reg_fft_rst_len 1
-#define        reg_fft_rst_lsb 0
-#define xd_p_reg_fft_fast_beacon       0xA335
-#define        reg_fft_fast_beacon_pos 1
-#define        reg_fft_fast_beacon_len 1
-#define        reg_fft_fast_beacon_lsb 0
-#define xd_p_reg_fft_fast_valid        0xA335
-#define        reg_fft_fast_valid_pos 2
-#define        reg_fft_fast_valid_len 1
-#define        reg_fft_fast_valid_lsb 0
-#define xd_p_reg_fft_mask_en   0xA335
-#define        reg_fft_mask_en_pos 3
-#define        reg_fft_mask_en_len 1
-#define        reg_fft_mask_en_lsb 0
-#define xd_p_reg_fft_crc_en    0xA335
-#define        reg_fft_crc_en_pos 4
-#define        reg_fft_crc_en_len 1
-#define        reg_fft_crc_en_lsb 0
-#define xd_p_reg_finr_en       0xA336
-#define        reg_finr_en_pos 0
-#define        reg_finr_en_len 1
-#define        reg_finr_en_lsb 0
-#define xd_p_fd_fste_en        0xA337
-#define        fd_fste_en_pos 1
-#define        fd_fste_en_len 1
-#define        fd_fste_en_lsb 0
-#define xd_p_fd_sqi_tps_level_shift    0xA338
-#define        fd_sqi_tps_level_shift_pos 0
-#define        fd_sqi_tps_level_shift_len 8
-#define        fd_sqi_tps_level_shift_lsb 0
-#define xd_p_fd_pilot_ma_len   0xA339
-#define        fd_pilot_ma_len_pos 0
-#define        fd_pilot_ma_len_len 6
-#define        fd_pilot_ma_len_lsb 0
-#define xd_p_fd_tps_ma_len     0xA33A
-#define        fd_tps_ma_len_pos 0
-#define        fd_tps_ma_len_len 6
-#define        fd_tps_ma_len_lsb 0
-#define xd_p_fd_sqi_s3 0xA33B
-#define        fd_sqi_s3_pos 0
-#define        fd_sqi_s3_len 8
-#define        fd_sqi_s3_lsb 0
-#define xd_p_fd_sqi_dummy_reg_0        0xA33C
-#define        fd_sqi_dummy_reg_0_pos 0
-#define        fd_sqi_dummy_reg_0_len 1
-#define        fd_sqi_dummy_reg_0_lsb 0
-#define xd_p_fd_sqi_debug_sel  0xA33C
-#define        fd_sqi_debug_sel_pos 1
-#define        fd_sqi_debug_sel_len 2
-#define        fd_sqi_debug_sel_lsb 0
-#define xd_p_fd_sqi_s2 0xA33C
-#define        fd_sqi_s2_pos 3
-#define        fd_sqi_s2_len 5
-#define        fd_sqi_s2_lsb 0
-#define xd_p_fd_sqi_dummy_reg_1        0xA33D
-#define        fd_sqi_dummy_reg_1_pos 0
-#define        fd_sqi_dummy_reg_1_len 1
-#define        fd_sqi_dummy_reg_1_lsb 0
-#define xd_p_fd_inr_ignore     0xA33D
-#define        fd_inr_ignore_pos 1
-#define        fd_inr_ignore_len 1
-#define        fd_inr_ignore_lsb 0
-#define xd_p_fd_pilot_ignore   0xA33D
-#define        fd_pilot_ignore_pos 2
-#define        fd_pilot_ignore_len 1
-#define        fd_pilot_ignore_lsb 0
-#define xd_p_fd_etps_ignore    0xA33D
-#define        fd_etps_ignore_pos 3
-#define        fd_etps_ignore_len 1
-#define        fd_etps_ignore_lsb 0
-#define xd_p_fd_sqi_s1 0xA33D
-#define        fd_sqi_s1_pos 4
-#define        fd_sqi_s1_len 4
-#define        fd_sqi_s1_lsb 0
-#define xd_p_reg_fste_ehw_7_0  0xA33E
-#define        reg_fste_ehw_7_0_pos 0
-#define        reg_fste_ehw_7_0_len 8
-#define        reg_fste_ehw_7_0_lsb 0
-#define xd_p_reg_fste_ehw_9_8  0xA33F
-#define        reg_fste_ehw_9_8_pos 0
-#define        reg_fste_ehw_9_8_len 2
-#define        reg_fste_ehw_9_8_lsb 8
-#define xd_p_reg_fste_i_adj_vld        0xA33F
-#define        reg_fste_i_adj_vld_pos 2
-#define        reg_fste_i_adj_vld_len 1
-#define        reg_fste_i_adj_vld_lsb 0
-#define xd_p_reg_fste_phase_ini_7_0    0xA340
-#define        reg_fste_phase_ini_7_0_pos 0
-#define        reg_fste_phase_ini_7_0_len 8
-#define        reg_fste_phase_ini_7_0_lsb 0
-#define xd_p_reg_fste_phase_ini_11_8   0xA341
-#define        reg_fste_phase_ini_11_8_pos 0
-#define        reg_fste_phase_ini_11_8_len 4
-#define        reg_fste_phase_ini_11_8_lsb 8
-#define xd_p_reg_fste_phase_inc_3_0    0xA341
-#define        reg_fste_phase_inc_3_0_pos 4
-#define        reg_fste_phase_inc_3_0_len 4
-#define        reg_fste_phase_inc_3_0_lsb 0
-#define xd_p_reg_fste_phase_inc_11_4   0xA342
-#define        reg_fste_phase_inc_11_4_pos 0
-#define        reg_fste_phase_inc_11_4_len 8
-#define        reg_fste_phase_inc_11_4_lsb 4
-#define xd_p_reg_fste_acum_cost_cnt_max        0xA343
-#define        reg_fste_acum_cost_cnt_max_pos 0
-#define        reg_fste_acum_cost_cnt_max_len 4
-#define        reg_fste_acum_cost_cnt_max_lsb 0
-#define xd_p_reg_fste_step_size_std    0xA343
-#define        reg_fste_step_size_std_pos 4
-#define        reg_fste_step_size_std_len 4
-#define        reg_fste_step_size_std_lsb 0
-#define xd_p_reg_fste_step_size_max    0xA344
-#define        reg_fste_step_size_max_pos 0
-#define        reg_fste_step_size_max_len 4
-#define        reg_fste_step_size_max_lsb 0
-#define xd_p_reg_fste_step_size_min    0xA344
-#define        reg_fste_step_size_min_pos 4
-#define        reg_fste_step_size_min_len 4
-#define        reg_fste_step_size_min_lsb 0
-#define xd_p_reg_fste_frac_step_size_7_0       0xA345
-#define        reg_fste_frac_step_size_7_0_pos 0
-#define        reg_fste_frac_step_size_7_0_len 8
-#define        reg_fste_frac_step_size_7_0_lsb 0
-#define xd_p_reg_fste_frac_step_size_15_8      0xA346
-#define        reg_fste_frac_step_size_15_8_pos 0
-#define        reg_fste_frac_step_size_15_8_len 8
-#define        reg_fste_frac_step_size_15_8_lsb 8
-#define xd_p_reg_fste_frac_step_size_19_16     0xA347
-#define        reg_fste_frac_step_size_19_16_pos 0
-#define        reg_fste_frac_step_size_19_16_len 4
-#define        reg_fste_frac_step_size_19_16_lsb 16
-#define xd_p_reg_fste_rpd_dir_cnt_max  0xA347
-#define        reg_fste_rpd_dir_cnt_max_pos 4
-#define        reg_fste_rpd_dir_cnt_max_len 4
-#define        reg_fste_rpd_dir_cnt_max_lsb 0
-#define xd_p_reg_fste_ehs      0xA348
-#define        reg_fste_ehs_pos 0
-#define        reg_fste_ehs_len 4
-#define        reg_fste_ehs_lsb 0
-#define xd_p_reg_fste_frac_cost_cnt_max_3_0    0xA348
-#define        reg_fste_frac_cost_cnt_max_3_0_pos 4
-#define        reg_fste_frac_cost_cnt_max_3_0_len 4
-#define        reg_fste_frac_cost_cnt_max_3_0_lsb 0
-#define xd_p_reg_fste_frac_cost_cnt_max_9_4    0xA349
-#define        reg_fste_frac_cost_cnt_max_9_4_pos 0
-#define        reg_fste_frac_cost_cnt_max_9_4_len 6
-#define        reg_fste_frac_cost_cnt_max_9_4_lsb 4
-#define xd_p_reg_fste_w0_7_0   0xA34A
-#define        reg_fste_w0_7_0_pos 0
-#define        reg_fste_w0_7_0_len 8
-#define        reg_fste_w0_7_0_lsb 0
-#define xd_p_reg_fste_w0_11_8  0xA34B
-#define        reg_fste_w0_11_8_pos 0
-#define        reg_fste_w0_11_8_len 4
-#define        reg_fste_w0_11_8_lsb 8
-#define xd_p_reg_fste_w1_3_0   0xA34B
-#define        reg_fste_w1_3_0_pos 4
-#define        reg_fste_w1_3_0_len 4
-#define        reg_fste_w1_3_0_lsb 0
-#define xd_p_reg_fste_w1_11_4  0xA34C
-#define        reg_fste_w1_11_4_pos 0
-#define        reg_fste_w1_11_4_len 8
-#define        reg_fste_w1_11_4_lsb 4
-#define xd_p_reg_fste_w2_7_0   0xA34D
-#define        reg_fste_w2_7_0_pos 0
-#define        reg_fste_w2_7_0_len 8
-#define        reg_fste_w2_7_0_lsb 0
-#define xd_p_reg_fste_w2_11_8  0xA34E
-#define        reg_fste_w2_11_8_pos 0
-#define        reg_fste_w2_11_8_len 4
-#define        reg_fste_w2_11_8_lsb 8
-#define xd_p_reg_fste_w3_3_0   0xA34E
-#define        reg_fste_w3_3_0_pos 4
-#define        reg_fste_w3_3_0_len 4
-#define        reg_fste_w3_3_0_lsb 0
-#define xd_p_reg_fste_w3_11_4  0xA34F
-#define        reg_fste_w3_11_4_pos 0
-#define        reg_fste_w3_11_4_len 8
-#define        reg_fste_w3_11_4_lsb 4
-#define xd_p_reg_fste_w4_7_0   0xA350
-#define        reg_fste_w4_7_0_pos 0
-#define        reg_fste_w4_7_0_len 8
-#define        reg_fste_w4_7_0_lsb 0
-#define xd_p_reg_fste_w4_11_8  0xA351
-#define        reg_fste_w4_11_8_pos 0
-#define        reg_fste_w4_11_8_len 4
-#define        reg_fste_w4_11_8_lsb 8
-#define xd_p_reg_fste_w5_3_0   0xA351
-#define        reg_fste_w5_3_0_pos 4
-#define        reg_fste_w5_3_0_len 4
-#define        reg_fste_w5_3_0_lsb 0
-#define xd_p_reg_fste_w5_11_4  0xA352
-#define        reg_fste_w5_11_4_pos 0
-#define        reg_fste_w5_11_4_len 8
-#define        reg_fste_w5_11_4_lsb 4
-#define xd_p_reg_fste_w6_7_0   0xA353
-#define        reg_fste_w6_7_0_pos 0
-#define        reg_fste_w6_7_0_len 8
-#define        reg_fste_w6_7_0_lsb 0
-#define xd_p_reg_fste_w6_11_8  0xA354
-#define        reg_fste_w6_11_8_pos 0
-#define        reg_fste_w6_11_8_len 4
-#define        reg_fste_w6_11_8_lsb 8
-#define xd_p_reg_fste_w7_3_0   0xA354
-#define        reg_fste_w7_3_0_pos 4
-#define        reg_fste_w7_3_0_len 4
-#define        reg_fste_w7_3_0_lsb 0
-#define xd_p_reg_fste_w7_11_4  0xA355
-#define        reg_fste_w7_11_4_pos 0
-#define        reg_fste_w7_11_4_len 8
-#define        reg_fste_w7_11_4_lsb 4
-#define xd_p_reg_fste_w8_7_0   0xA356
-#define        reg_fste_w8_7_0_pos 0
-#define        reg_fste_w8_7_0_len 8
-#define        reg_fste_w8_7_0_lsb 0
-#define xd_p_reg_fste_w8_11_8  0xA357
-#define        reg_fste_w8_11_8_pos 0
-#define        reg_fste_w8_11_8_len 4
-#define        reg_fste_w8_11_8_lsb 8
-#define xd_p_reg_fste_w9_3_0   0xA357
-#define        reg_fste_w9_3_0_pos 4
-#define        reg_fste_w9_3_0_len 4
-#define        reg_fste_w9_3_0_lsb 0
-#define xd_p_reg_fste_w9_11_4  0xA358
-#define        reg_fste_w9_11_4_pos 0
-#define        reg_fste_w9_11_4_len 8
-#define        reg_fste_w9_11_4_lsb 4
-#define xd_p_reg_fste_wa_7_0   0xA359
-#define        reg_fste_wa_7_0_pos 0
-#define        reg_fste_wa_7_0_len 8
-#define        reg_fste_wa_7_0_lsb 0
-#define xd_p_reg_fste_wa_11_8  0xA35A
-#define        reg_fste_wa_11_8_pos 0
-#define        reg_fste_wa_11_8_len 4
-#define        reg_fste_wa_11_8_lsb 8
-#define xd_p_reg_fste_wb_3_0   0xA35A
-#define        reg_fste_wb_3_0_pos 4
-#define        reg_fste_wb_3_0_len 4
-#define        reg_fste_wb_3_0_lsb 0
-#define xd_p_reg_fste_wb_11_4  0xA35B
-#define        reg_fste_wb_11_4_pos 0
-#define        reg_fste_wb_11_4_len 8
-#define        reg_fste_wb_11_4_lsb 4
-#define xd_r_fd_fste_i_adj     0xA35C
-#define        fd_fste_i_adj_pos 0
-#define        fd_fste_i_adj_len 5
-#define        fd_fste_i_adj_lsb 0
-#define xd_r_fd_fste_f_adj_7_0 0xA35D
-#define        fd_fste_f_adj_7_0_pos 0
-#define        fd_fste_f_adj_7_0_len 8
-#define        fd_fste_f_adj_7_0_lsb 0
-#define xd_r_fd_fste_f_adj_15_8        0xA35E
-#define        fd_fste_f_adj_15_8_pos 0
-#define        fd_fste_f_adj_15_8_len 8
-#define        fd_fste_f_adj_15_8_lsb 8
-#define xd_r_fd_fste_f_adj_19_16       0xA35F
-#define        fd_fste_f_adj_19_16_pos 0
-#define        fd_fste_f_adj_19_16_len 4
-#define        fd_fste_f_adj_19_16_lsb 16
-#define xd_p_reg_feq_Leak_Bypass       0xA366
-#define        reg_feq_Leak_Bypass_pos 0
-#define        reg_feq_Leak_Bypass_len 1
-#define        reg_feq_Leak_Bypass_lsb 0
-#define xd_p_reg_feq_Leak_Mneg1        0xA366
-#define        reg_feq_Leak_Mneg1_pos 1
-#define        reg_feq_Leak_Mneg1_len 3
-#define        reg_feq_Leak_Mneg1_lsb 0
-#define xd_p_reg_feq_Leak_B_ShiftQ     0xA366
-#define        reg_feq_Leak_B_ShiftQ_pos 4
-#define        reg_feq_Leak_B_ShiftQ_len 4
-#define        reg_feq_Leak_B_ShiftQ_lsb 0
-#define xd_p_reg_feq_Leak_B_Float0     0xA367
-#define        reg_feq_Leak_B_Float0_pos 0
-#define        reg_feq_Leak_B_Float0_len 8
-#define        reg_feq_Leak_B_Float0_lsb 0
-#define xd_p_reg_feq_Leak_B_Float1     0xA368
-#define        reg_feq_Leak_B_Float1_pos 0
-#define        reg_feq_Leak_B_Float1_len 8
-#define        reg_feq_Leak_B_Float1_lsb 0
-#define xd_p_reg_feq_Leak_B_Float2     0xA369
-#define        reg_feq_Leak_B_Float2_pos 0
-#define        reg_feq_Leak_B_Float2_len 8
-#define        reg_feq_Leak_B_Float2_lsb 0
-#define xd_p_reg_feq_Leak_B_Float3     0xA36A
-#define        reg_feq_Leak_B_Float3_pos 0
-#define        reg_feq_Leak_B_Float3_len 8
-#define        reg_feq_Leak_B_Float3_lsb 0
-#define xd_p_reg_feq_Leak_B_Float4     0xA36B
-#define        reg_feq_Leak_B_Float4_pos 0
-#define        reg_feq_Leak_B_Float4_len 8
-#define        reg_feq_Leak_B_Float4_lsb 0
-#define xd_p_reg_feq_Leak_B_Float5     0xA36C
-#define        reg_feq_Leak_B_Float5_pos 0
-#define        reg_feq_Leak_B_Float5_len 8
-#define        reg_feq_Leak_B_Float5_lsb 0
-#define xd_p_reg_feq_Leak_B_Float6     0xA36D
-#define        reg_feq_Leak_B_Float6_pos 0
-#define        reg_feq_Leak_B_Float6_len 8
-#define        reg_feq_Leak_B_Float6_lsb 0
-#define xd_p_reg_feq_Leak_B_Float7     0xA36E
-#define        reg_feq_Leak_B_Float7_pos 0
-#define        reg_feq_Leak_B_Float7_len 8
-#define        reg_feq_Leak_B_Float7_lsb 0
-#define xd_r_reg_feq_data_h2_7_0       0xA36F
-#define        reg_feq_data_h2_7_0_pos 0
-#define        reg_feq_data_h2_7_0_len 8
-#define        reg_feq_data_h2_7_0_lsb 0
-#define xd_r_reg_feq_data_h2_9_8       0xA370
-#define        reg_feq_data_h2_9_8_pos 0
-#define        reg_feq_data_h2_9_8_len 2
-#define        reg_feq_data_h2_9_8_lsb 8
-#define xd_p_reg_feq_leak_use_slice_tps        0xA371
-#define        reg_feq_leak_use_slice_tps_pos 0
-#define        reg_feq_leak_use_slice_tps_len 1
-#define        reg_feq_leak_use_slice_tps_lsb 0
-#define xd_p_reg_feq_read_update       0xA371
-#define        reg_feq_read_update_pos 1
-#define        reg_feq_read_update_len 1
-#define        reg_feq_read_update_lsb 0
-#define xd_p_reg_feq_data_vld  0xA371
-#define        reg_feq_data_vld_pos 2
-#define        reg_feq_data_vld_len 1
-#define        reg_feq_data_vld_lsb 0
-#define xd_p_reg_feq_tone_idx_4_0      0xA371
-#define        reg_feq_tone_idx_4_0_pos 3
-#define        reg_feq_tone_idx_4_0_len 5
-#define        reg_feq_tone_idx_4_0_lsb 0
-#define xd_p_reg_feq_tone_idx_12_5     0xA372
-#define        reg_feq_tone_idx_12_5_pos 0
-#define        reg_feq_tone_idx_12_5_len 8
-#define        reg_feq_tone_idx_12_5_lsb 5
-#define xd_r_reg_feq_data_re_7_0       0xA373
-#define        reg_feq_data_re_7_0_pos 0
-#define        reg_feq_data_re_7_0_len 8
-#define        reg_feq_data_re_7_0_lsb 0
-#define xd_r_reg_feq_data_re_10_8      0xA374
-#define        reg_feq_data_re_10_8_pos 0
-#define        reg_feq_data_re_10_8_len 3
-#define        reg_feq_data_re_10_8_lsb 8
-#define xd_r_reg_feq_data_im_7_0       0xA375
-#define        reg_feq_data_im_7_0_pos 0
-#define        reg_feq_data_im_7_0_len 8
-#define        reg_feq_data_im_7_0_lsb 0
-#define xd_r_reg_feq_data_im_10_8      0xA376
-#define        reg_feq_data_im_10_8_pos 0
-#define        reg_feq_data_im_10_8_len 3
-#define        reg_feq_data_im_10_8_lsb 8
-#define xd_r_reg_feq_y_re      0xA377
-#define        reg_feq_y_re_pos 0
-#define        reg_feq_y_re_len 8
-#define        reg_feq_y_re_lsb 0
-#define xd_r_reg_feq_y_im      0xA378
-#define        reg_feq_y_im_pos 0
-#define        reg_feq_y_im_len 8
-#define        reg_feq_y_im_lsb 0
-#define xd_r_reg_feq_h_re_7_0  0xA379
-#define        reg_feq_h_re_7_0_pos 0
-#define        reg_feq_h_re_7_0_len 8
-#define        reg_feq_h_re_7_0_lsb 0
-#define xd_r_reg_feq_h_re_8    0xA37A
-#define        reg_feq_h_re_8_pos 0
-#define        reg_feq_h_re_8_len 1
-#define        reg_feq_h_re_8_lsb 0
-#define xd_r_reg_feq_h_im_7_0  0xA37B
-#define        reg_feq_h_im_7_0_pos 0
-#define        reg_feq_h_im_7_0_len 8
-#define        reg_feq_h_im_7_0_lsb 0
-#define xd_r_reg_feq_h_im_8    0xA37C
-#define        reg_feq_h_im_8_pos 0
-#define        reg_feq_h_im_8_len 1
-#define        reg_feq_h_im_8_lsb 0
-#define xd_p_fec_super_frm_unit_7_0    0xA380
-#define        fec_super_frm_unit_7_0_pos 0
-#define        fec_super_frm_unit_7_0_len 8
-#define        fec_super_frm_unit_7_0_lsb 0
-#define xd_p_fec_super_frm_unit_15_8   0xA381
-#define        fec_super_frm_unit_15_8_pos 0
-#define        fec_super_frm_unit_15_8_len 8
-#define        fec_super_frm_unit_15_8_lsb 8
-#define xd_r_fec_vtb_err_bit_cnt_7_0   0xA382
-#define        fec_vtb_err_bit_cnt_7_0_pos 0
-#define        fec_vtb_err_bit_cnt_7_0_len 8
-#define        fec_vtb_err_bit_cnt_7_0_lsb 0
-#define xd_r_fec_vtb_err_bit_cnt_15_8  0xA383
-#define        fec_vtb_err_bit_cnt_15_8_pos 0
-#define        fec_vtb_err_bit_cnt_15_8_len 8
-#define        fec_vtb_err_bit_cnt_15_8_lsb 8
-#define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384
-#define        fec_vtb_err_bit_cnt_23_16_pos 0
-#define        fec_vtb_err_bit_cnt_23_16_len 8
-#define        fec_vtb_err_bit_cnt_23_16_lsb 16
-#define xd_p_fec_rsd_packet_unit_7_0   0xA385
-#define        fec_rsd_packet_unit_7_0_pos 0
-#define        fec_rsd_packet_unit_7_0_len 8
-#define        fec_rsd_packet_unit_7_0_lsb 0
-#define xd_p_fec_rsd_packet_unit_15_8  0xA386
-#define        fec_rsd_packet_unit_15_8_pos 0
-#define        fec_rsd_packet_unit_15_8_len 8
-#define        fec_rsd_packet_unit_15_8_lsb 8
-#define xd_r_fec_rsd_bit_err_cnt_7_0   0xA387
-#define        fec_rsd_bit_err_cnt_7_0_pos 0
-#define        fec_rsd_bit_err_cnt_7_0_len 8
-#define        fec_rsd_bit_err_cnt_7_0_lsb 0
-#define xd_r_fec_rsd_bit_err_cnt_15_8  0xA388
-#define        fec_rsd_bit_err_cnt_15_8_pos 0
-#define        fec_rsd_bit_err_cnt_15_8_len 8
-#define        fec_rsd_bit_err_cnt_15_8_lsb 8
-#define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389
-#define        fec_rsd_bit_err_cnt_23_16_pos 0
-#define        fec_rsd_bit_err_cnt_23_16_len 8
-#define        fec_rsd_bit_err_cnt_23_16_lsb 16
-#define xd_r_fec_rsd_abort_packet_cnt_7_0      0xA38A
-#define        fec_rsd_abort_packet_cnt_7_0_pos 0
-#define        fec_rsd_abort_packet_cnt_7_0_len 8
-#define        fec_rsd_abort_packet_cnt_7_0_lsb 0
-#define xd_r_fec_rsd_abort_packet_cnt_15_8     0xA38B
-#define        fec_rsd_abort_packet_cnt_15_8_pos 0
-#define        fec_rsd_abort_packet_cnt_15_8_len 8
-#define        fec_rsd_abort_packet_cnt_15_8_lsb 8
-#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0      0xA38C
-#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0
-#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8
-#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0
-#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8     0xA38D
-#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0
-#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8
-#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8
-#define xd_p_fec_RS_TH_1_7_0   0xA38E
-#define        fec_RS_TH_1_7_0_pos 0
-#define        fec_RS_TH_1_7_0_len 8
-#define        fec_RS_TH_1_7_0_lsb 0
-#define xd_p_fec_RS_TH_1_15_8  0xA38F
-#define        fec_RS_TH_1_15_8_pos 0
-#define        fec_RS_TH_1_15_8_len 8
-#define        fec_RS_TH_1_15_8_lsb 8
-#define xd_p_fec_RS_TH_2       0xA390
-#define        fec_RS_TH_2_pos 0
-#define        fec_RS_TH_2_len 8
-#define        fec_RS_TH_2_lsb 0
-#define xd_p_fec_mon_en        0xA391
-#define        fec_mon_en_pos 0
-#define        fec_mon_en_len 1
-#define        fec_mon_en_lsb 0
-#define xd_p_reg_b8to47        0xA391
-#define        reg_b8to47_pos 1
-#define        reg_b8to47_len 1
-#define        reg_b8to47_lsb 0
-#define xd_p_reg_rsd_sync_rep  0xA391
-#define        reg_rsd_sync_rep_pos 2
-#define        reg_rsd_sync_rep_len 1
-#define        reg_rsd_sync_rep_lsb 0
-#define xd_p_fec_rsd_retrain_rst       0xA391
-#define        fec_rsd_retrain_rst_pos 3
-#define        fec_rsd_retrain_rst_len 1
-#define        fec_rsd_retrain_rst_lsb 0
-#define xd_r_fec_rsd_ber_rdy   0xA391
-#define        fec_rsd_ber_rdy_pos 4
-#define        fec_rsd_ber_rdy_len 1
-#define        fec_rsd_ber_rdy_lsb 0
-#define xd_p_fec_rsd_ber_rst   0xA391
-#define        fec_rsd_ber_rst_pos 5
-#define        fec_rsd_ber_rst_len 1
-#define        fec_rsd_ber_rst_lsb 0
-#define xd_r_fec_vtb_ber_rdy   0xA391
-#define        fec_vtb_ber_rdy_pos 6
-#define        fec_vtb_ber_rdy_len 1
-#define        fec_vtb_ber_rdy_lsb 0
-#define xd_p_fec_vtb_ber_rst   0xA391
-#define        fec_vtb_ber_rst_pos 7
-#define        fec_vtb_ber_rst_len 1
-#define        fec_vtb_ber_rst_lsb 0
-#define xd_p_reg_vtb_clk40en   0xA392
-#define        reg_vtb_clk40en_pos 0
-#define        reg_vtb_clk40en_len 1
-#define        reg_vtb_clk40en_lsb 0
-#define xd_p_fec_vtb_rsd_mon_en        0xA392
-#define        fec_vtb_rsd_mon_en_pos 1
-#define        fec_vtb_rsd_mon_en_len 1
-#define        fec_vtb_rsd_mon_en_lsb 0
-#define xd_p_reg_fec_data_en   0xA392
-#define        reg_fec_data_en_pos 2
-#define        reg_fec_data_en_len 1
-#define        reg_fec_data_en_lsb 0
-#define xd_p_fec_dummy_reg_2   0xA392
-#define        fec_dummy_reg_2_pos 3
-#define        fec_dummy_reg_2_len 3
-#define        fec_dummy_reg_2_lsb 0
-#define xd_p_reg_sync_chk      0xA392
-#define        reg_sync_chk_pos 6
-#define        reg_sync_chk_len 1
-#define        reg_sync_chk_lsb 0
-#define xd_p_fec_rsd_bypass    0xA392
-#define        fec_rsd_bypass_pos 7
-#define        fec_rsd_bypass_len 1
-#define        fec_rsd_bypass_lsb 0
-#define xd_p_fec_sw_rst        0xA393
-#define        fec_sw_rst_pos 0
-#define        fec_sw_rst_len 1
-#define        fec_sw_rst_lsb 0
-#define xd_r_fec_vtb_pm_crc    0xA394
-#define        fec_vtb_pm_crc_pos 0
-#define        fec_vtb_pm_crc_len 8
-#define        fec_vtb_pm_crc_lsb 0
-#define xd_r_fec_vtb_tb_7_crc  0xA395
-#define        fec_vtb_tb_7_crc_pos 0
-#define        fec_vtb_tb_7_crc_len 8
-#define        fec_vtb_tb_7_crc_lsb 0
-#define xd_r_fec_vtb_tb_6_crc  0xA396
-#define        fec_vtb_tb_6_crc_pos 0
-#define        fec_vtb_tb_6_crc_len 8
-#define        fec_vtb_tb_6_crc_lsb 0
-#define xd_r_fec_vtb_tb_5_crc  0xA397
-#define        fec_vtb_tb_5_crc_pos 0
-#define        fec_vtb_tb_5_crc_len 8
-#define        fec_vtb_tb_5_crc_lsb 0
-#define xd_r_fec_vtb_tb_4_crc  0xA398
-#define        fec_vtb_tb_4_crc_pos 0
-#define        fec_vtb_tb_4_crc_len 8
-#define        fec_vtb_tb_4_crc_lsb 0
-#define xd_r_fec_vtb_tb_3_crc  0xA399
-#define        fec_vtb_tb_3_crc_pos 0
-#define        fec_vtb_tb_3_crc_len 8
-#define        fec_vtb_tb_3_crc_lsb 0
-#define xd_r_fec_vtb_tb_2_crc  0xA39A
-#define        fec_vtb_tb_2_crc_pos 0
-#define        fec_vtb_tb_2_crc_len 8
-#define        fec_vtb_tb_2_crc_lsb 0
-#define xd_r_fec_vtb_tb_1_crc  0xA39B
-#define        fec_vtb_tb_1_crc_pos 0
-#define        fec_vtb_tb_1_crc_len 8
-#define        fec_vtb_tb_1_crc_lsb 0
-#define xd_r_fec_vtb_tb_0_crc  0xA39C
-#define        fec_vtb_tb_0_crc_pos 0
-#define        fec_vtb_tb_0_crc_len 8
-#define        fec_vtb_tb_0_crc_lsb 0
-#define xd_r_fec_rsd_bank0_crc 0xA39D
-#define        fec_rsd_bank0_crc_pos 0
-#define        fec_rsd_bank0_crc_len 8
-#define        fec_rsd_bank0_crc_lsb 0
-#define xd_r_fec_rsd_bank1_crc 0xA39E
-#define        fec_rsd_bank1_crc_pos 0
-#define        fec_rsd_bank1_crc_len 8
-#define        fec_rsd_bank1_crc_lsb 0
-#define xd_r_fec_idi_vtb_crc   0xA39F
-#define        fec_idi_vtb_crc_pos 0
-#define        fec_idi_vtb_crc_len 8
-#define        fec_idi_vtb_crc_lsb 0
-#define xd_g_reg_tpsd_txmod    0xA3C0
-#define        reg_tpsd_txmod_pos 0
-#define        reg_tpsd_txmod_len 2
-#define        reg_tpsd_txmod_lsb 0
-#define xd_g_reg_tpsd_gi       0xA3C0
-#define        reg_tpsd_gi_pos 2
-#define        reg_tpsd_gi_len 2
-#define        reg_tpsd_gi_lsb 0
-#define xd_g_reg_tpsd_hier     0xA3C0
-#define        reg_tpsd_hier_pos 4
-#define        reg_tpsd_hier_len 3
-#define        reg_tpsd_hier_lsb 0
-#define xd_g_reg_bw    0xA3C1
-#define        reg_bw_pos 2
-#define        reg_bw_len 2
-#define        reg_bw_lsb 0
-#define xd_g_reg_dec_pri       0xA3C1
-#define        reg_dec_pri_pos 4
-#define        reg_dec_pri_len 1
-#define        reg_dec_pri_lsb 0
-#define xd_g_reg_tpsd_const    0xA3C1
-#define        reg_tpsd_const_pos 6
-#define        reg_tpsd_const_len 2
-#define        reg_tpsd_const_lsb 0
-#define xd_g_reg_tpsd_hpcr     0xA3C2
-#define        reg_tpsd_hpcr_pos 0
-#define        reg_tpsd_hpcr_len 3
-#define        reg_tpsd_hpcr_lsb 0
-#define xd_g_reg_tpsd_lpcr     0xA3C2
-#define        reg_tpsd_lpcr_pos 3
-#define        reg_tpsd_lpcr_len 3
-#define        reg_tpsd_lpcr_lsb 0
-#define xd_g_reg_ofsm_clk      0xA3D0
-#define        reg_ofsm_clk_pos 0
-#define        reg_ofsm_clk_len 3
-#define        reg_ofsm_clk_lsb 0
-#define xd_g_reg_fclk_cfg      0xA3D1
-#define        reg_fclk_cfg_pos 0
-#define        reg_fclk_cfg_len 1
-#define        reg_fclk_cfg_lsb 0
-#define xd_g_reg_fclk_idi      0xA3D1
-#define        reg_fclk_idi_pos 1
-#define        reg_fclk_idi_len 1
-#define        reg_fclk_idi_lsb 0
-#define xd_g_reg_fclk_odi      0xA3D1
-#define        reg_fclk_odi_pos 2
-#define        reg_fclk_odi_len 1
-#define        reg_fclk_odi_lsb 0
-#define xd_g_reg_fclk_rsd      0xA3D1
-#define        reg_fclk_rsd_pos 3
-#define        reg_fclk_rsd_len 1
-#define        reg_fclk_rsd_lsb 0
-#define xd_g_reg_fclk_vtb      0xA3D1
-#define        reg_fclk_vtb_pos 4
-#define        reg_fclk_vtb_len 1
-#define        reg_fclk_vtb_lsb 0
-#define xd_g_reg_fclk_cste     0xA3D1
-#define        reg_fclk_cste_pos 5
-#define        reg_fclk_cste_len 1
-#define        reg_fclk_cste_lsb 0
-#define xd_g_reg_fclk_mp2if    0xA3D1
-#define        reg_fclk_mp2if_pos 6
-#define        reg_fclk_mp2if_len 1
-#define        reg_fclk_mp2if_lsb 0
-#define xd_I2C_i2c_m_slave_addr        0xA400
-#define        i2c_m_slave_addr_pos 0
-#define        i2c_m_slave_addr_len 8
-#define        i2c_m_slave_addr_lsb 0
-#define xd_I2C_i2c_m_data1     0xA401
-#define        i2c_m_data1_pos 0
-#define        i2c_m_data1_len 8
-#define        i2c_m_data1_lsb 0
-#define xd_I2C_i2c_m_data2     0xA402
-#define        i2c_m_data2_pos 0
-#define        i2c_m_data2_len 8
-#define        i2c_m_data2_lsb 0
-#define xd_I2C_i2c_m_data3     0xA403
-#define        i2c_m_data3_pos 0
-#define        i2c_m_data3_len 8
-#define        i2c_m_data3_lsb 0
-#define xd_I2C_i2c_m_data4     0xA404
-#define        i2c_m_data4_pos 0
-#define        i2c_m_data4_len 8
-#define        i2c_m_data4_lsb 0
-#define xd_I2C_i2c_m_data5     0xA405
-#define        i2c_m_data5_pos 0
-#define        i2c_m_data5_len 8
-#define        i2c_m_data5_lsb 0
-#define xd_I2C_i2c_m_data6     0xA406
-#define        i2c_m_data6_pos 0
-#define        i2c_m_data6_len 8
-#define        i2c_m_data6_lsb 0
-#define xd_I2C_i2c_m_data7     0xA407
-#define        i2c_m_data7_pos 0
-#define        i2c_m_data7_len 8
-#define        i2c_m_data7_lsb 0
-#define xd_I2C_i2c_m_data8     0xA408
-#define        i2c_m_data8_pos 0
-#define        i2c_m_data8_len 8
-#define        i2c_m_data8_lsb 0
-#define xd_I2C_i2c_m_data9     0xA409
-#define        i2c_m_data9_pos 0
-#define        i2c_m_data9_len 8
-#define        i2c_m_data9_lsb 0
-#define xd_I2C_i2c_m_data10    0xA40A
-#define        i2c_m_data10_pos 0
-#define        i2c_m_data10_len 8
-#define        i2c_m_data10_lsb 0
-#define xd_I2C_i2c_m_data11    0xA40B
-#define        i2c_m_data11_pos 0
-#define        i2c_m_data11_len 8
-#define        i2c_m_data11_lsb 0
-#define xd_I2C_i2c_m_cmd_rw    0xA40C
-#define        i2c_m_cmd_rw_pos 0
-#define        i2c_m_cmd_rw_len 1
-#define        i2c_m_cmd_rw_lsb 0
-#define xd_I2C_i2c_m_cmd_rwlen 0xA40C
-#define        i2c_m_cmd_rwlen_pos 3
-#define        i2c_m_cmd_rwlen_len 4
-#define        i2c_m_cmd_rwlen_lsb 0
-#define xd_I2C_i2c_m_status_cmd_exe    0xA40D
-#define        i2c_m_status_cmd_exe_pos 0
-#define        i2c_m_status_cmd_exe_len 1
-#define        i2c_m_status_cmd_exe_lsb 0
-#define xd_I2C_i2c_m_status_wdat_done  0xA40D
-#define        i2c_m_status_wdat_done_pos 1
-#define        i2c_m_status_wdat_done_len 1
-#define        i2c_m_status_wdat_done_lsb 0
-#define xd_I2C_i2c_m_status_wdat_fail  0xA40D
-#define        i2c_m_status_wdat_fail_pos 2
-#define        i2c_m_status_wdat_fail_len 1
-#define        i2c_m_status_wdat_fail_lsb 0
-#define xd_I2C_i2c_m_period    0xA40E
-#define        i2c_m_period_pos 0
-#define        i2c_m_period_len 8
-#define        i2c_m_period_lsb 0
-#define xd_I2C_i2c_m_reg_msb_lsb       0xA40F
-#define        i2c_m_reg_msb_lsb_pos 0
-#define        i2c_m_reg_msb_lsb_len 1
-#define        i2c_m_reg_msb_lsb_lsb 0
-#define xd_I2C_reg_ofdm_rst    0xA40F
-#define        reg_ofdm_rst_pos 1
-#define        reg_ofdm_rst_len 1
-#define        reg_ofdm_rst_lsb 0
-#define xd_I2C_reg_sample_period_on_tuner      0xA40F
-#define        reg_sample_period_on_tuner_pos 2
-#define        reg_sample_period_on_tuner_len 1
-#define        reg_sample_period_on_tuner_lsb 0
-#define xd_I2C_reg_rst_i2c     0xA40F
-#define        reg_rst_i2c_pos 3
-#define        reg_rst_i2c_len 1
-#define        reg_rst_i2c_lsb 0
-#define xd_I2C_reg_ofdm_rst_en 0xA40F
-#define        reg_ofdm_rst_en_pos 4
-#define        reg_ofdm_rst_en_len 1
-#define        reg_ofdm_rst_en_lsb 0
-#define xd_I2C_reg_tuner_sda_sync_on   0xA40F
-#define        reg_tuner_sda_sync_on_pos 5
-#define        reg_tuner_sda_sync_on_len 1
-#define        reg_tuner_sda_sync_on_lsb 0
-#define xd_p_mp2if_data_access_disable_ofsm    0xA500
-#define        mp2if_data_access_disable_ofsm_pos 0
-#define        mp2if_data_access_disable_ofsm_len 1
-#define        mp2if_data_access_disable_ofsm_lsb 0
-#define xd_p_reg_mp2_sw_rst_ofsm       0xA500
-#define        reg_mp2_sw_rst_ofsm_pos 1
-#define        reg_mp2_sw_rst_ofsm_len 1
-#define        reg_mp2_sw_rst_ofsm_lsb 0
-#define xd_p_reg_mp2if_clk_en_ofsm     0xA500
-#define        reg_mp2if_clk_en_ofsm_pos 2
-#define        reg_mp2if_clk_en_ofsm_len 1
-#define        reg_mp2if_clk_en_ofsm_lsb 0
-#define xd_r_mp2if_sync_byte_locked    0xA500
-#define        mp2if_sync_byte_locked_pos 3
-#define        mp2if_sync_byte_locked_len 1
-#define        mp2if_sync_byte_locked_lsb 0
-#define xd_r_mp2if_ts_not_188  0xA500
-#define        mp2if_ts_not_188_pos 4
-#define        mp2if_ts_not_188_len 1
-#define        mp2if_ts_not_188_lsb 0
-#define xd_r_mp2if_psb_empty   0xA500
-#define        mp2if_psb_empty_pos 5
-#define        mp2if_psb_empty_len 1
-#define        mp2if_psb_empty_lsb 0
-#define xd_r_mp2if_psb_overflow        0xA500
-#define        mp2if_psb_overflow_pos 6
-#define        mp2if_psb_overflow_len 1
-#define        mp2if_psb_overflow_lsb 0
-#define xd_p_mp2if_keep_sf_sync_byte_ofsm      0xA500
-#define        mp2if_keep_sf_sync_byte_ofsm_pos 7
-#define        mp2if_keep_sf_sync_byte_ofsm_len 1
-#define        mp2if_keep_sf_sync_byte_ofsm_lsb 0
-#define xd_r_mp2if_psb_mp2if_num_pkt   0xA501
-#define        mp2if_psb_mp2if_num_pkt_pos 0
-#define        mp2if_psb_mp2if_num_pkt_len 6
-#define        mp2if_psb_mp2if_num_pkt_lsb 0
-#define xd_p_reg_mpeg_full_speed_ofsm  0xA501
-#define        reg_mpeg_full_speed_ofsm_pos 6
-#define        reg_mpeg_full_speed_ofsm_len 1
-#define        reg_mpeg_full_speed_ofsm_lsb 0
-#define xd_p_mp2if_mpeg_ser_mode_ofsm  0xA501
-#define        mp2if_mpeg_ser_mode_ofsm_pos 7
-#define        mp2if_mpeg_ser_mode_ofsm_len 1
-#define        mp2if_mpeg_ser_mode_ofsm_lsb 0
-#define xd_p_reg_sw_mon51      0xA600
-#define        reg_sw_mon51_pos 0
-#define        reg_sw_mon51_len 8
-#define        reg_sw_mon51_lsb 0
-#define xd_p_reg_top_pcsel     0xA601
-#define        reg_top_pcsel_pos 0
-#define        reg_top_pcsel_len 1
-#define        reg_top_pcsel_lsb 0
-#define xd_p_reg_top_rs232     0xA601
-#define        reg_top_rs232_pos 1
-#define        reg_top_rs232_len 1
-#define        reg_top_rs232_lsb 0
-#define xd_p_reg_top_pcout     0xA601
-#define        reg_top_pcout_pos 2
-#define        reg_top_pcout_len 1
-#define        reg_top_pcout_lsb 0
-#define xd_p_reg_top_debug     0xA601
-#define        reg_top_debug_pos 3
-#define        reg_top_debug_len 1
-#define        reg_top_debug_lsb 0
-#define xd_p_reg_top_adcdly    0xA601
-#define        reg_top_adcdly_pos 4
-#define        reg_top_adcdly_len 2
-#define        reg_top_adcdly_lsb 0
-#define xd_p_reg_top_pwrdw     0xA601
-#define        reg_top_pwrdw_pos 6
-#define        reg_top_pwrdw_len 1
-#define        reg_top_pwrdw_lsb 0
-#define xd_p_reg_top_pwrdw_inv 0xA601
-#define        reg_top_pwrdw_inv_pos 7
-#define        reg_top_pwrdw_inv_len 1
-#define        reg_top_pwrdw_inv_lsb 0
-#define xd_p_reg_top_int_inv   0xA602
-#define        reg_top_int_inv_pos 0
-#define        reg_top_int_inv_len 1
-#define        reg_top_int_inv_lsb 0
-#define xd_p_reg_top_dio_sel   0xA602
-#define        reg_top_dio_sel_pos 1
-#define        reg_top_dio_sel_len 1
-#define        reg_top_dio_sel_lsb 0
-#define xd_p_reg_top_gpioon0   0xA603
-#define        reg_top_gpioon0_pos 0
-#define        reg_top_gpioon0_len 1
-#define        reg_top_gpioon0_lsb 0
-#define xd_p_reg_top_gpioon1   0xA603
-#define        reg_top_gpioon1_pos 1
-#define        reg_top_gpioon1_len 1
-#define        reg_top_gpioon1_lsb 0
-#define xd_p_reg_top_gpioon2   0xA603
-#define        reg_top_gpioon2_pos 2
-#define        reg_top_gpioon2_len 1
-#define        reg_top_gpioon2_lsb 0
-#define xd_p_reg_top_gpioon3   0xA603
-#define        reg_top_gpioon3_pos 3
-#define        reg_top_gpioon3_len 1
-#define        reg_top_gpioon3_lsb 0
-#define xd_p_reg_top_lockon1   0xA603
-#define        reg_top_lockon1_pos 4
-#define        reg_top_lockon1_len 1
-#define        reg_top_lockon1_lsb 0
-#define xd_p_reg_top_lockon2   0xA603
-#define        reg_top_lockon2_pos 5
-#define        reg_top_lockon2_len 1
-#define        reg_top_lockon2_lsb 0
-#define xd_p_reg_top_gpioo0    0xA604
-#define        reg_top_gpioo0_pos 0
-#define        reg_top_gpioo0_len 1
-#define        reg_top_gpioo0_lsb 0
-#define xd_p_reg_top_gpioo1    0xA604
-#define        reg_top_gpioo1_pos 1
-#define        reg_top_gpioo1_len 1
-#define        reg_top_gpioo1_lsb 0
-#define xd_p_reg_top_gpioo2    0xA604
-#define        reg_top_gpioo2_pos 2
-#define        reg_top_gpioo2_len 1
-#define        reg_top_gpioo2_lsb 0
-#define xd_p_reg_top_gpioo3    0xA604
-#define        reg_top_gpioo3_pos 3
-#define        reg_top_gpioo3_len 1
-#define        reg_top_gpioo3_lsb 0
-#define xd_p_reg_top_lock1     0xA604
-#define        reg_top_lock1_pos 4
-#define        reg_top_lock1_len 1
-#define        reg_top_lock1_lsb 0
-#define xd_p_reg_top_lock2     0xA604
-#define        reg_top_lock2_pos 5
-#define        reg_top_lock2_len 1
-#define        reg_top_lock2_lsb 0
-#define xd_p_reg_top_gpioen0   0xA605
-#define        reg_top_gpioen0_pos 0
-#define        reg_top_gpioen0_len 1
-#define        reg_top_gpioen0_lsb 0
-#define xd_p_reg_top_gpioen1   0xA605
-#define        reg_top_gpioen1_pos 1
-#define        reg_top_gpioen1_len 1
-#define        reg_top_gpioen1_lsb 0
-#define xd_p_reg_top_gpioen2   0xA605
-#define        reg_top_gpioen2_pos 2
-#define        reg_top_gpioen2_len 1
-#define        reg_top_gpioen2_lsb 0
-#define xd_p_reg_top_gpioen3   0xA605
-#define        reg_top_gpioen3_pos 3
-#define        reg_top_gpioen3_len 1
-#define        reg_top_gpioen3_lsb 0
-#define xd_p_reg_top_locken1   0xA605
-#define        reg_top_locken1_pos 4
-#define        reg_top_locken1_len 1
-#define        reg_top_locken1_lsb 0
-#define xd_p_reg_top_locken2   0xA605
-#define        reg_top_locken2_pos 5
-#define        reg_top_locken2_len 1
-#define        reg_top_locken2_lsb 0
-#define xd_r_reg_top_gpioi0    0xA606
-#define        reg_top_gpioi0_pos 0
-#define        reg_top_gpioi0_len 1
-#define        reg_top_gpioi0_lsb 0
-#define xd_r_reg_top_gpioi1    0xA606
-#define        reg_top_gpioi1_pos 1
-#define        reg_top_gpioi1_len 1
-#define        reg_top_gpioi1_lsb 0
-#define xd_r_reg_top_gpioi2    0xA606
-#define        reg_top_gpioi2_pos 2
-#define        reg_top_gpioi2_len 1
-#define        reg_top_gpioi2_lsb 0
-#define xd_r_reg_top_gpioi3    0xA606
-#define        reg_top_gpioi3_pos 3
-#define        reg_top_gpioi3_len 1
-#define        reg_top_gpioi3_lsb 0
-#define xd_r_reg_top_locki1    0xA606
-#define        reg_top_locki1_pos 4
-#define        reg_top_locki1_len 1
-#define        reg_top_locki1_lsb 0
-#define xd_r_reg_top_locki2    0xA606
-#define        reg_top_locki2_pos 5
-#define        reg_top_locki2_len 1
-#define        reg_top_locki2_lsb 0
-#define xd_p_reg_dummy_7_0     0xA608
-#define        reg_dummy_7_0_pos 0
-#define        reg_dummy_7_0_len 8
-#define        reg_dummy_7_0_lsb 0
-#define xd_p_reg_dummy_15_8    0xA609
-#define        reg_dummy_15_8_pos 0
-#define        reg_dummy_15_8_len 8
-#define        reg_dummy_15_8_lsb 8
-#define xd_p_reg_dummy_23_16   0xA60A
-#define        reg_dummy_23_16_pos 0
-#define        reg_dummy_23_16_len 8
-#define        reg_dummy_23_16_lsb 16
-#define xd_p_reg_dummy_31_24   0xA60B
-#define        reg_dummy_31_24_pos 0
-#define        reg_dummy_31_24_len 8
-#define        reg_dummy_31_24_lsb 24
-#define xd_p_reg_dummy_39_32   0xA60C
-#define        reg_dummy_39_32_pos 0
-#define        reg_dummy_39_32_len 8
-#define        reg_dummy_39_32_lsb 32
-#define xd_p_reg_dummy_47_40   0xA60D
-#define        reg_dummy_47_40_pos 0
-#define        reg_dummy_47_40_len 8
-#define        reg_dummy_47_40_lsb 40
-#define xd_p_reg_dummy_55_48   0xA60E
-#define        reg_dummy_55_48_pos 0
-#define        reg_dummy_55_48_len 8
-#define        reg_dummy_55_48_lsb 48
-#define xd_p_reg_dummy_63_56   0xA60F
-#define        reg_dummy_63_56_pos 0
-#define        reg_dummy_63_56_len 8
-#define        reg_dummy_63_56_lsb 56
-#define xd_p_reg_dummy_71_64   0xA610
-#define        reg_dummy_71_64_pos 0
-#define        reg_dummy_71_64_len 8
-#define        reg_dummy_71_64_lsb 64
-#define xd_p_reg_dummy_79_72   0xA611
-#define        reg_dummy_79_72_pos 0
-#define        reg_dummy_79_72_len 8
-#define        reg_dummy_79_72_lsb 72
-#define xd_p_reg_dummy_87_80   0xA612
-#define        reg_dummy_87_80_pos 0
-#define        reg_dummy_87_80_len 8
-#define        reg_dummy_87_80_lsb 80
-#define xd_p_reg_dummy_95_88   0xA613
-#define        reg_dummy_95_88_pos 0
-#define        reg_dummy_95_88_len 8
-#define        reg_dummy_95_88_lsb 88
-#define xd_p_reg_dummy_103_96  0xA614
-#define        reg_dummy_103_96_pos 0
-#define        reg_dummy_103_96_len 8
-#define        reg_dummy_103_96_lsb 96
-
-#define xd_p_reg_unplug_flag   0xA615
-#define        reg_unplug_flag_pos 0
-#define        reg_unplug_flag_len 1
-#define        reg_unplug_flag_lsb 104
-
-#define xd_p_reg_api_dca_stes_request   0xA615
-#define reg_api_dca_stes_request_pos 1
-#define reg_api_dca_stes_request_len 1
-#define reg_api_dca_stes_request_lsb 0
-
-#define xd_p_reg_back_to_dca_flag      0xA615
-#define        reg_back_to_dca_flag_pos 2
-#define        reg_back_to_dca_flag_len 1
-#define        reg_back_to_dca_flag_lsb 106
-
-#define xd_p_reg_api_retrain_request    0xA615
-#define reg_api_retrain_request_pos 3
-#define reg_api_retrain_request_len 1
-#define reg_api_retrain_request_lsb 0
-
-#define xd_p_reg_Dyn_Top_Try_flag      0xA615
-#define        reg_Dyn_Top_Try_flag_pos 3
-#define        reg_Dyn_Top_Try_flag_len 1
-#define        reg_Dyn_Top_Try_flag_lsb 107
-
-#define xd_p_reg_API_retrain_freeze_flag       0xA615
-#define        reg_API_retrain_freeze_flag_pos 4
-#define        reg_API_retrain_freeze_flag_len 1
-#define        reg_API_retrain_freeze_flag_lsb 108
-
-#define xd_p_reg_dummy_111_104 0xA615
-#define        reg_dummy_111_104_pos 0
-#define        reg_dummy_111_104_len 8
-#define        reg_dummy_111_104_lsb 104
-#define xd_p_reg_dummy_119_112 0xA616
-#define        reg_dummy_119_112_pos 0
-#define        reg_dummy_119_112_len 8
-#define        reg_dummy_119_112_lsb 112
-#define xd_p_reg_dummy_127_120 0xA617
-#define        reg_dummy_127_120_pos 0
-#define        reg_dummy_127_120_len 8
-#define        reg_dummy_127_120_lsb 120
-#define xd_p_reg_dummy_135_128 0xA618
-#define        reg_dummy_135_128_pos 0
-#define        reg_dummy_135_128_len 8
-#define        reg_dummy_135_128_lsb 128
-
-#define xd_p_reg_dummy_143_136 0xA619
-#define        reg_dummy_143_136_pos 0
-#define        reg_dummy_143_136_len 8
-#define        reg_dummy_143_136_lsb 136
-
-#define xd_p_reg_CCIR_dis      0xA619
-#define        reg_CCIR_dis_pos 0
-#define        reg_CCIR_dis_len 1
-#define        reg_CCIR_dis_lsb 0
-
-#define xd_p_reg_dummy_151_144 0xA61A
-#define        reg_dummy_151_144_pos 0
-#define        reg_dummy_151_144_len 8
-#define        reg_dummy_151_144_lsb 144
-
-#define xd_p_reg_dummy_159_152 0xA61B
-#define        reg_dummy_159_152_pos 0
-#define        reg_dummy_159_152_len 8
-#define        reg_dummy_159_152_lsb 152
-
-#define xd_p_reg_dummy_167_160 0xA61C
-#define        reg_dummy_167_160_pos 0
-#define        reg_dummy_167_160_len 8
-#define        reg_dummy_167_160_lsb 160
-
-#define xd_p_reg_dummy_175_168 0xA61D
-#define        reg_dummy_175_168_pos 0
-#define        reg_dummy_175_168_len 8
-#define        reg_dummy_175_168_lsb 168
-
-#define xd_p_reg_dummy_183_176 0xA61E
-#define        reg_dummy_183_176_pos 0
-#define        reg_dummy_183_176_len 8
-#define        reg_dummy_183_176_lsb 176
-
-#define xd_p_reg_ofsm_read_rbc_en  0xA61E
-#define reg_ofsm_read_rbc_en_pos 2
-#define reg_ofsm_read_rbc_en_len 1
-#define reg_ofsm_read_rbc_en_lsb 0
-
-#define xd_p_reg_ce_filter_selection_dis  0xA61E
-#define reg_ce_filter_selection_dis_pos 1
-#define reg_ce_filter_selection_dis_len 1
-#define reg_ce_filter_selection_dis_lsb 0
-
-#define xd_p_reg_OFSM_version_control_7_0  0xA611
-#define reg_OFSM_version_control_7_0_pos 0
-#define reg_OFSM_version_control_7_0_len 8
-#define reg_OFSM_version_control_7_0_lsb 0
-
-#define xd_p_reg_OFSM_version_control_15_8  0xA61F
-#define reg_OFSM_version_control_15_8_pos 0
-#define reg_OFSM_version_control_15_8_len 8
-#define reg_OFSM_version_control_15_8_lsb 0
-
-#define xd_p_reg_OFSM_version_control_23_16  0xA620
-#define reg_OFSM_version_control_23_16_pos 0
-#define reg_OFSM_version_control_23_16_len 8
-#define reg_OFSM_version_control_23_16_lsb 0
-
-#define xd_p_reg_dummy_191_184 0xA61F
-#define        reg_dummy_191_184_pos 0
-#define        reg_dummy_191_184_len 8
-#define        reg_dummy_191_184_lsb 184
-
-#define xd_p_reg_dummy_199_192 0xA620
-#define        reg_dummy_199_192_pos 0
-#define        reg_dummy_199_192_len 8
-#define        reg_dummy_199_192_lsb 192
-
-#define xd_p_reg_ce_en 0xABC0
-#define        reg_ce_en_pos 0
-#define        reg_ce_en_len 1
-#define        reg_ce_en_lsb 0
-#define xd_p_reg_ce_fctrl_en   0xABC0
-#define        reg_ce_fctrl_en_pos 1
-#define        reg_ce_fctrl_en_len 1
-#define        reg_ce_fctrl_en_lsb 0
-#define xd_p_reg_ce_fste_tdi   0xABC0
-#define        reg_ce_fste_tdi_pos 2
-#define        reg_ce_fste_tdi_len 1
-#define        reg_ce_fste_tdi_lsb 0
-#define xd_p_reg_ce_dynamic    0xABC0
-#define        reg_ce_dynamic_pos 3
-#define        reg_ce_dynamic_len 1
-#define        reg_ce_dynamic_lsb 0
-#define xd_p_reg_ce_conf       0xABC0
-#define        reg_ce_conf_pos 4
-#define        reg_ce_conf_len 2
-#define        reg_ce_conf_lsb 0
-#define xd_p_reg_ce_dyn12      0xABC0
-#define        reg_ce_dyn12_pos 6
-#define        reg_ce_dyn12_len 1
-#define        reg_ce_dyn12_lsb 0
-#define xd_p_reg_ce_derot_en   0xABC0
-#define        reg_ce_derot_en_pos 7
-#define        reg_ce_derot_en_len 1
-#define        reg_ce_derot_en_lsb 0
-#define xd_p_reg_ce_dynamic_th_7_0     0xABC1
-#define        reg_ce_dynamic_th_7_0_pos 0
-#define        reg_ce_dynamic_th_7_0_len 8
-#define        reg_ce_dynamic_th_7_0_lsb 0
-#define xd_p_reg_ce_dynamic_th_15_8    0xABC2
-#define        reg_ce_dynamic_th_15_8_pos 0
-#define        reg_ce_dynamic_th_15_8_len 8
-#define        reg_ce_dynamic_th_15_8_lsb 8
-#define xd_p_reg_ce_s1 0xABC3
-#define        reg_ce_s1_pos 0
-#define        reg_ce_s1_len 5
-#define        reg_ce_s1_lsb 0
-#define xd_p_reg_ce_var_forced_value   0xABC3
-#define        reg_ce_var_forced_value_pos 5
-#define        reg_ce_var_forced_value_len 3
-#define        reg_ce_var_forced_value_lsb 0
-#define xd_p_reg_ce_data_im_7_0        0xABC4
-#define        reg_ce_data_im_7_0_pos 0
-#define        reg_ce_data_im_7_0_len 8
-#define        reg_ce_data_im_7_0_lsb 0
-#define xd_p_reg_ce_data_im_8  0xABC5
-#define        reg_ce_data_im_8_pos 0
-#define        reg_ce_data_im_8_len 1
-#define        reg_ce_data_im_8_lsb 0
-#define xd_p_reg_ce_data_re_6_0        0xABC5
-#define        reg_ce_data_re_6_0_pos 1
-#define        reg_ce_data_re_6_0_len 7
-#define        reg_ce_data_re_6_0_lsb 0
-#define xd_p_reg_ce_data_re_8_7        0xABC6
-#define        reg_ce_data_re_8_7_pos 0
-#define        reg_ce_data_re_8_7_len 2
-#define        reg_ce_data_re_8_7_lsb 7
-#define xd_p_reg_ce_tone_5_0   0xABC6
-#define        reg_ce_tone_5_0_pos 2
-#define        reg_ce_tone_5_0_len 6
-#define        reg_ce_tone_5_0_lsb 0
-#define xd_p_reg_ce_tone_12_6  0xABC7
-#define        reg_ce_tone_12_6_pos 0
-#define        reg_ce_tone_12_6_len 7
-#define        reg_ce_tone_12_6_lsb 6
-#define xd_p_reg_ce_centroid_drift_th  0xABC8
-#define        reg_ce_centroid_drift_th_pos 0
-#define        reg_ce_centroid_drift_th_len 8
-#define        reg_ce_centroid_drift_th_lsb 0
-#define xd_p_reg_ce_centroid_count_max 0xABC9
-#define        reg_ce_centroid_count_max_pos 0
-#define        reg_ce_centroid_count_max_len 4
-#define        reg_ce_centroid_count_max_lsb 0
-#define xd_p_reg_ce_centroid_bias_inc_7_0      0xABCA
-#define        reg_ce_centroid_bias_inc_7_0_pos 0
-#define        reg_ce_centroid_bias_inc_7_0_len 8
-#define        reg_ce_centroid_bias_inc_7_0_lsb 0
-#define xd_p_reg_ce_centroid_bias_inc_8        0xABCB
-#define        reg_ce_centroid_bias_inc_8_pos 0
-#define        reg_ce_centroid_bias_inc_8_len 1
-#define        reg_ce_centroid_bias_inc_8_lsb 0
-#define xd_p_reg_ce_var_th0_7_0        0xABCC
-#define        reg_ce_var_th0_7_0_pos 0
-#define        reg_ce_var_th0_7_0_len 8
-#define        reg_ce_var_th0_7_0_lsb 0
-#define xd_p_reg_ce_var_th0_15_8       0xABCD
-#define        reg_ce_var_th0_15_8_pos 0
-#define        reg_ce_var_th0_15_8_len 8
-#define        reg_ce_var_th0_15_8_lsb 8
-#define xd_p_reg_ce_var_th1_7_0        0xABCE
-#define        reg_ce_var_th1_7_0_pos 0
-#define        reg_ce_var_th1_7_0_len 8
-#define        reg_ce_var_th1_7_0_lsb 0
-#define xd_p_reg_ce_var_th1_15_8       0xABCF
-#define        reg_ce_var_th1_15_8_pos 0
-#define        reg_ce_var_th1_15_8_len 8
-#define        reg_ce_var_th1_15_8_lsb 8
-#define xd_p_reg_ce_var_th2_7_0        0xABD0
-#define        reg_ce_var_th2_7_0_pos 0
-#define        reg_ce_var_th2_7_0_len 8
-#define        reg_ce_var_th2_7_0_lsb 0
-#define xd_p_reg_ce_var_th2_15_8       0xABD1
-#define        reg_ce_var_th2_15_8_pos 0
-#define        reg_ce_var_th2_15_8_len 8
-#define        reg_ce_var_th2_15_8_lsb 8
-#define xd_p_reg_ce_var_th3_7_0        0xABD2
-#define        reg_ce_var_th3_7_0_pos 0
-#define        reg_ce_var_th3_7_0_len 8
-#define        reg_ce_var_th3_7_0_lsb 0
-#define xd_p_reg_ce_var_th3_15_8       0xABD3
-#define        reg_ce_var_th3_15_8_pos 0
-#define        reg_ce_var_th3_15_8_len 8
-#define        reg_ce_var_th3_15_8_lsb 8
-#define xd_p_reg_ce_var_th4_7_0        0xABD4
-#define        reg_ce_var_th4_7_0_pos 0
-#define        reg_ce_var_th4_7_0_len 8
-#define        reg_ce_var_th4_7_0_lsb 0
-#define xd_p_reg_ce_var_th4_15_8       0xABD5
-#define        reg_ce_var_th4_15_8_pos 0
-#define        reg_ce_var_th4_15_8_len 8
-#define        reg_ce_var_th4_15_8_lsb 8
-#define xd_p_reg_ce_var_th5_7_0        0xABD6
-#define        reg_ce_var_th5_7_0_pos 0
-#define        reg_ce_var_th5_7_0_len 8
-#define        reg_ce_var_th5_7_0_lsb 0
-#define xd_p_reg_ce_var_th5_15_8       0xABD7
-#define        reg_ce_var_th5_15_8_pos 0
-#define        reg_ce_var_th5_15_8_len 8
-#define        reg_ce_var_th5_15_8_lsb 8
-#define xd_p_reg_ce_var_th6_7_0        0xABD8
-#define        reg_ce_var_th6_7_0_pos 0
-#define        reg_ce_var_th6_7_0_len 8
-#define        reg_ce_var_th6_7_0_lsb 0
-#define xd_p_reg_ce_var_th6_15_8       0xABD9
-#define        reg_ce_var_th6_15_8_pos 0
-#define        reg_ce_var_th6_15_8_len 8
-#define        reg_ce_var_th6_15_8_lsb 8
-#define xd_p_reg_ce_fctrl_reset        0xABDA
-#define        reg_ce_fctrl_reset_pos 0
-#define        reg_ce_fctrl_reset_len 1
-#define        reg_ce_fctrl_reset_lsb 0
-#define xd_p_reg_ce_cent_auto_clr_en   0xABDA
-#define        reg_ce_cent_auto_clr_en_pos 1
-#define        reg_ce_cent_auto_clr_en_len 1
-#define        reg_ce_cent_auto_clr_en_lsb 0
-#define xd_p_reg_ce_fctrl_auto_reset_en        0xABDA
-#define        reg_ce_fctrl_auto_reset_en_pos 2
-#define        reg_ce_fctrl_auto_reset_en_len 1
-#define        reg_ce_fctrl_auto_reset_en_lsb 0
-#define xd_p_reg_ce_var_forced_en      0xABDA
-#define        reg_ce_var_forced_en_pos 3
-#define        reg_ce_var_forced_en_len 1
-#define        reg_ce_var_forced_en_lsb 0
-#define xd_p_reg_ce_cent_forced_en     0xABDA
-#define        reg_ce_cent_forced_en_pos 4
-#define        reg_ce_cent_forced_en_len 1
-#define        reg_ce_cent_forced_en_lsb 0
-#define xd_p_reg_ce_var_max    0xABDA
-#define        reg_ce_var_max_pos 5
-#define        reg_ce_var_max_len 3
-#define        reg_ce_var_max_lsb 0
-#define xd_p_reg_ce_cent_forced_value_7_0      0xABDB
-#define        reg_ce_cent_forced_value_7_0_pos 0
-#define        reg_ce_cent_forced_value_7_0_len 8
-#define        reg_ce_cent_forced_value_7_0_lsb 0
-#define xd_p_reg_ce_cent_forced_value_11_8     0xABDC
-#define        reg_ce_cent_forced_value_11_8_pos 0
-#define        reg_ce_cent_forced_value_11_8_len 4
-#define        reg_ce_cent_forced_value_11_8_lsb 8
-#define xd_p_reg_ce_fctrl_rd   0xABDD
-#define        reg_ce_fctrl_rd_pos 0
-#define        reg_ce_fctrl_rd_len 1
-#define        reg_ce_fctrl_rd_lsb 0
-#define xd_p_reg_ce_centroid_max_6_0   0xABDD
-#define        reg_ce_centroid_max_6_0_pos 1
-#define        reg_ce_centroid_max_6_0_len 7
-#define        reg_ce_centroid_max_6_0_lsb 0
-#define xd_p_reg_ce_centroid_max_11_7  0xABDE
-#define        reg_ce_centroid_max_11_7_pos 0
-#define        reg_ce_centroid_max_11_7_len 5
-#define        reg_ce_centroid_max_11_7_lsb 7
-#define xd_p_reg_ce_var        0xABDF
-#define        reg_ce_var_pos 0
-#define        reg_ce_var_len 3
-#define        reg_ce_var_lsb 0
-#define xd_p_reg_ce_fctrl_rdy  0xABDF
-#define        reg_ce_fctrl_rdy_pos 3
-#define        reg_ce_fctrl_rdy_len 1
-#define        reg_ce_fctrl_rdy_lsb 0
-#define xd_p_reg_ce_centroid_out_3_0   0xABDF
-#define        reg_ce_centroid_out_3_0_pos 4
-#define        reg_ce_centroid_out_3_0_len 4
-#define        reg_ce_centroid_out_3_0_lsb 0
-#define xd_p_reg_ce_centroid_out_11_4  0xABE0
-#define        reg_ce_centroid_out_11_4_pos 0
-#define        reg_ce_centroid_out_11_4_len 8
-#define        reg_ce_centroid_out_11_4_lsb 4
-#define xd_p_reg_ce_bias_7_0   0xABE1
-#define        reg_ce_bias_7_0_pos 0
-#define        reg_ce_bias_7_0_len 8
-#define        reg_ce_bias_7_0_lsb 0
-#define xd_p_reg_ce_bias_11_8  0xABE2
-#define        reg_ce_bias_11_8_pos 0
-#define        reg_ce_bias_11_8_len 4
-#define        reg_ce_bias_11_8_lsb 8
-#define xd_p_reg_ce_m1_3_0     0xABE2
-#define        reg_ce_m1_3_0_pos 4
-#define        reg_ce_m1_3_0_len 4
-#define        reg_ce_m1_3_0_lsb 0
-#define xd_p_reg_ce_m1_11_4    0xABE3
-#define        reg_ce_m1_11_4_pos 0
-#define        reg_ce_m1_11_4_len 8
-#define        reg_ce_m1_11_4_lsb 4
-#define xd_p_reg_ce_rh0_7_0    0xABE4
-#define        reg_ce_rh0_7_0_pos 0
-#define        reg_ce_rh0_7_0_len 8
-#define        reg_ce_rh0_7_0_lsb 0
-#define xd_p_reg_ce_rh0_15_8   0xABE5
-#define        reg_ce_rh0_15_8_pos 0
-#define        reg_ce_rh0_15_8_len 8
-#define        reg_ce_rh0_15_8_lsb 8
-#define xd_p_reg_ce_rh0_23_16  0xABE6
-#define        reg_ce_rh0_23_16_pos 0
-#define        reg_ce_rh0_23_16_len 8
-#define        reg_ce_rh0_23_16_lsb 16
-#define xd_p_reg_ce_rh0_31_24  0xABE7
-#define        reg_ce_rh0_31_24_pos 0
-#define        reg_ce_rh0_31_24_len 8
-#define        reg_ce_rh0_31_24_lsb 24
-#define xd_p_reg_ce_rh3_real_7_0       0xABE8
-#define        reg_ce_rh3_real_7_0_pos 0
-#define        reg_ce_rh3_real_7_0_len 8
-#define        reg_ce_rh3_real_7_0_lsb 0
-#define xd_p_reg_ce_rh3_real_15_8      0xABE9
-#define        reg_ce_rh3_real_15_8_pos 0
-#define        reg_ce_rh3_real_15_8_len 8
-#define        reg_ce_rh3_real_15_8_lsb 8
-#define xd_p_reg_ce_rh3_real_23_16     0xABEA
-#define        reg_ce_rh3_real_23_16_pos 0
-#define        reg_ce_rh3_real_23_16_len 8
-#define        reg_ce_rh3_real_23_16_lsb 16
-#define xd_p_reg_ce_rh3_real_31_24     0xABEB
-#define        reg_ce_rh3_real_31_24_pos 0
-#define        reg_ce_rh3_real_31_24_len 8
-#define        reg_ce_rh3_real_31_24_lsb 24
-#define xd_p_reg_ce_rh3_imag_7_0       0xABEC
-#define        reg_ce_rh3_imag_7_0_pos 0
-#define        reg_ce_rh3_imag_7_0_len 8
-#define        reg_ce_rh3_imag_7_0_lsb 0
-#define xd_p_reg_ce_rh3_imag_15_8      0xABED
-#define        reg_ce_rh3_imag_15_8_pos 0
-#define        reg_ce_rh3_imag_15_8_len 8
-#define        reg_ce_rh3_imag_15_8_lsb 8
-#define xd_p_reg_ce_rh3_imag_23_16     0xABEE
-#define        reg_ce_rh3_imag_23_16_pos 0
-#define        reg_ce_rh3_imag_23_16_len 8
-#define        reg_ce_rh3_imag_23_16_lsb 16
-#define xd_p_reg_ce_rh3_imag_31_24     0xABEF
-#define        reg_ce_rh3_imag_31_24_pos 0
-#define        reg_ce_rh3_imag_31_24_len 8
-#define        reg_ce_rh3_imag_31_24_lsb 24
-#define xd_p_reg_feq_fix_eh2_7_0       0xABF0
-#define        reg_feq_fix_eh2_7_0_pos 0
-#define        reg_feq_fix_eh2_7_0_len 8
-#define        reg_feq_fix_eh2_7_0_lsb 0
-#define xd_p_reg_feq_fix_eh2_15_8      0xABF1
-#define        reg_feq_fix_eh2_15_8_pos 0
-#define        reg_feq_fix_eh2_15_8_len 8
-#define        reg_feq_fix_eh2_15_8_lsb 8
-#define xd_p_reg_feq_fix_eh2_23_16     0xABF2
-#define        reg_feq_fix_eh2_23_16_pos 0
-#define        reg_feq_fix_eh2_23_16_len 8
-#define        reg_feq_fix_eh2_23_16_lsb 16
-#define xd_p_reg_feq_fix_eh2_31_24     0xABF3
-#define        reg_feq_fix_eh2_31_24_pos 0
-#define        reg_feq_fix_eh2_31_24_len 8
-#define        reg_feq_fix_eh2_31_24_lsb 24
-#define xd_p_reg_ce_m2_central_7_0     0xABF4
-#define        reg_ce_m2_central_7_0_pos 0
-#define        reg_ce_m2_central_7_0_len 8
-#define        reg_ce_m2_central_7_0_lsb 0
-#define xd_p_reg_ce_m2_central_15_8    0xABF5
-#define        reg_ce_m2_central_15_8_pos 0
-#define        reg_ce_m2_central_15_8_len 8
-#define        reg_ce_m2_central_15_8_lsb 8
-#define xd_p_reg_ce_fftshift   0xABF6
-#define        reg_ce_fftshift_pos 0
-#define        reg_ce_fftshift_len 4
-#define        reg_ce_fftshift_lsb 0
-#define xd_p_reg_ce_fftshift1  0xABF6
-#define        reg_ce_fftshift1_pos 4
-#define        reg_ce_fftshift1_len 4
-#define        reg_ce_fftshift1_lsb 0
-#define xd_p_reg_ce_fftshift2  0xABF7
-#define        reg_ce_fftshift2_pos 0
-#define        reg_ce_fftshift2_len 4
-#define        reg_ce_fftshift2_lsb 0
-#define xd_p_reg_ce_top_mobile 0xABF7
-#define        reg_ce_top_mobile_pos 4
-#define        reg_ce_top_mobile_len 1
-#define        reg_ce_top_mobile_lsb 0
-#define xd_p_reg_strong_sginal_detected 0xA2BC
-#define reg_strong_sginal_detected_pos 2
-#define reg_strong_sginal_detected_len 1
-#define reg_strong_sginal_detected_lsb 0
-
-#define XD_MP2IF_BASE                           0xB000
-#define XD_MP2IF_CSR                        (0x00 + XD_MP2IF_BASE)
-#define XD_MP2IF_DMX_CTRL                       (0x03 + XD_MP2IF_BASE)
-#define XD_MP2IF_PID_IDX                        (0x04 + XD_MP2IF_BASE)
-#define XD_MP2IF_PID_DATA_L                     (0x05 + XD_MP2IF_BASE)
-#define XD_MP2IF_PID_DATA_H                     (0x06 + XD_MP2IF_BASE)
-#define XD_MP2IF_MISC                       (0x07 + XD_MP2IF_BASE)
-
-extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d);
-extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg,
-                                    u8 * value);
-extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
-                                     u8 * values, int len);
-extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg,
-                                     u8 value);
-extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
-                                      u8 * values, int len);
-extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg,
-                                      u8 addr, u8 * values, int len);
-extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
-                                       u8 * values, int len);
-extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg,
-                                    u8 pos, u8 len, u8 * value);
-extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg,
-                                     u8 pos, u8 len, u8 value);
-extern int af9005_send_command(struct dvb_usb_device *d, u8 command,
-                              u8 * wbuf, int wlen, u8 * rbuf, int rlen);
-extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address,
-                             u8 * values, int len);
-extern int af9005_tuner_attach(struct dvb_usb_adapter *adap);
-extern int af9005_led_control(struct dvb_usb_device *d, int onoff);
-
-extern u8 regmask[8];
-
-/* remote control decoder */
-extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
-                           u32 * event, int *state);
-extern struct rc_map_table rc_map_af9005_table[];
-extern int rc_map_af9005_table_size;
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
deleted file mode 100644 (file)
index 5e45ae6..0000000
+++ /dev/null
@@ -1,1182 +0,0 @@
-/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
- * receiver.
- *
- * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "az6027.h"
-
-#include "stb0899_drv.h"
-#include "stb0899_reg.h"
-#include "stb0899_cfg.h"
-
-#include "stb6100.h"
-#include "stb6100_cfg.h"
-#include "dvb_ca_en50221.h"
-
-int dvb_usb_az6027_debug;
-module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct az6027_device_state {
-       struct dvb_ca_en50221 ca;
-       struct mutex ca_mutex;
-       u8 power_state;
-};
-
-static const struct stb0899_s1_reg az6027_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 az6027_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 az6027_stb0899_config = {
-       .init_dev               = az6027_stb0899_s1_init_1,
-       .init_s2_demod          = stb0899_s2_init_2,
-       .init_s1_demod          = az6027_stb0899_s1_init_3,
-       .init_s2_fec            = stb0899_s2_init_4,
-       .init_tst               = stb0899_s1_init_5,
-
-       .demod_address          = 0xd0, /* 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 az6027_stb6100_config = {
-       .tuner_address  = 0xc0,
-       .refclock       = 27000000,
-};
-
-
-/* check for mutex FIXME */
-int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
-{
-       int ret = -1;
-       if (mutex_lock_interruptible(&d->usb_mutex))
-               return -EAGAIN;
-
-       ret = usb_control_msg(d->udev,
-                             usb_rcvctrlpipe(d->udev, 0),
-                             req,
-                             USB_TYPE_VENDOR | USB_DIR_IN,
-                             value,
-                             index,
-                             b,
-                             blen,
-                             2000);
-
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EIO;
-       } else
-               ret = 0;
-
-       deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
-       debug_dump(b, blen, deb_xfer);
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-
-static int az6027_usb_out_op(struct dvb_usb_device *d,
-                            u8 req,
-                            u16 value,
-                            u16 index,
-                            u8 *b,
-                            int blen)
-{
-       int ret;
-
-       deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
-       debug_dump(b, blen, deb_xfer);
-
-       if (mutex_lock_interruptible(&d->usb_mutex))
-               return -EAGAIN;
-
-       ret = usb_control_msg(d->udev,
-                             usb_sndctrlpipe(d->udev, 0),
-                             req,
-                             USB_TYPE_VENDOR | USB_DIR_OUT,
-                             value,
-                             index,
-                             b,
-                             blen,
-                             2000);
-
-       if (ret != blen) {
-               warn("usb out operation failed. (%d)", ret);
-               mutex_unlock(&d->usb_mutex);
-               return -EIO;
-       } else{
-               mutex_unlock(&d->usb_mutex);
-               return 0;
-       }
-}
-
-static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       deb_info("%s %d", __func__, onoff);
-
-       req = 0xBC;
-       value = onoff;
-       index = 0;
-       blen = 0;
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               warn("usb out operation failed. (%d)", ret);
-
-       return ret;
-}
-
-/* keys for the enclosed remote control */
-static struct rc_map_table rc_map_az6027_table[] = {
-       { 0x01, KEY_1 },
-       { 0x02, KEY_2 },
-};
-
-/* remote control stuff (does not work with my box) */
-static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       return 0;
-}
-
-/*
-int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 v = onoff;
-       return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
-}
-*/
-
-static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
-                                       int slot,
-                                       int address)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC1;
-       value = address;
-       index = 0;
-       blen = 1;
-
-       ret = az6027_usb_in_op(d, req, value, index, b, blen);
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EINVAL;
-       } else {
-               ret = b[0];
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
-                                        int slot,
-                                        int address,
-                                        u8 value)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret;
-       u8 req;
-       u16 value1;
-       u16 index;
-       int blen;
-
-       deb_info("%s %d", __func__, slot);
-       if (slot != 0)
-               return -EINVAL;
-
-       mutex_lock(&state->ca_mutex);
-       req = 0xC2;
-       value1 = address;
-       index = value;
-       blen = 0;
-
-       ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
-       if (ret != 0)
-               warn("usb out operation failed. (%d)", ret);
-
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
-                                     int slot,
-                                     u8 address)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC3;
-       value = address;
-       index = 0;
-       blen = 2;
-
-       ret = az6027_usb_in_op(d, req, value, index, b, blen);
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EINVAL;
-       } else {
-               if (b[0] == 0)
-                       warn("Read CI IO error");
-
-               ret = b[1];
-               deb_info("read cam data = %x from 0x%x", b[1], value);
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
-                                      int slot,
-                                      u8 address,
-                                      u8 value)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret;
-       u8 req;
-       u16 value1;
-       u16 index;
-       int blen;
-
-       if (slot != 0)
-               return -EINVAL;
-
-       mutex_lock(&state->ca_mutex);
-       req = 0xC4;
-       value1 = address;
-       index = value;
-       blen = 0;
-
-       ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
-       if (ret != 0) {
-               warn("usb out operation failed. (%d)", ret);
-               goto failed;
-       }
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       req = 0xC8;
-       value = 0;
-       index = 0;
-       blen = 1;
-
-       ret = az6027_usb_in_op(d, req, value, index, b, blen);
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EIO;
-       } else{
-               ret = b[0];
-       }
-       kfree(b);
-       return ret;
-}
-
-static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret, i;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC6;
-       value = 1;
-       index = 0;
-       blen = 0;
-
-       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               warn("usb out operation failed. (%d)", ret);
-               goto failed;
-       }
-
-       msleep(500);
-       req = 0xC6;
-       value = 0;
-       index = 0;
-       blen = 0;
-
-       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               warn("usb out operation failed. (%d)", ret);
-               goto failed;
-       }
-
-       for (i = 0; i < 15; i++) {
-               msleep(100);
-
-               if (CI_CamReady(ca, slot)) {
-                       deb_info("CAM Ready");
-                       break;
-               }
-       }
-       msleep(5000);
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       return 0;
-}
-
-static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       deb_info("%s", __func__);
-       mutex_lock(&state->ca_mutex);
-       req = 0xC7;
-       value = 1;
-       index = 0;
-       blen = 0;
-
-       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
-       if (ret != 0) {
-               warn("usb out operation failed. (%d)", ret);
-               goto failed;
-       }
-
-failed:
-       mutex_unlock(&state->ca_mutex);
-       return ret;
-}
-
-static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-       u8 *b;
-
-       b = kmalloc(12, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-       mutex_lock(&state->ca_mutex);
-
-       req = 0xC5;
-       value = 0;
-       index = 0;
-       blen = 1;
-
-       ret = az6027_usb_in_op(d, req, value, index, b, blen);
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EIO;
-       } else
-               ret = 0;
-
-       if (!ret && b[0] == 1) {
-               ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
-                     DVB_CA_EN50221_POLL_CAM_READY;
-       }
-
-       mutex_unlock(&state->ca_mutex);
-       kfree(b);
-       return ret;
-}
-
-
-static void az6027_ci_uninit(struct dvb_usb_device *d)
-{
-       struct az6027_device_state *state;
-
-       deb_info("%s", __func__);
-
-       if (NULL == d)
-               return;
-
-       state = (struct az6027_device_state *)d->priv;
-       if (NULL == state)
-               return;
-
-       if (NULL == state->ca.data)
-               return;
-
-       dvb_ca_en50221_release(&state->ca);
-
-       memset(&state->ca, 0, sizeof(state->ca));
-}
-
-
-static int az6027_ci_init(struct dvb_usb_adapter *a)
-{
-       struct dvb_usb_device *d = a->dev;
-       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
-       int ret;
-
-       deb_info("%s", __func__);
-
-       mutex_init(&state->ca_mutex);
-
-       state->ca.owner                 = THIS_MODULE;
-       state->ca.read_attribute_mem    = az6027_ci_read_attribute_mem;
-       state->ca.write_attribute_mem   = az6027_ci_write_attribute_mem;
-       state->ca.read_cam_control      = az6027_ci_read_cam_control;
-       state->ca.write_cam_control     = az6027_ci_write_cam_control;
-       state->ca.slot_reset            = az6027_ci_slot_reset;
-       state->ca.slot_shutdown         = az6027_ci_slot_shutdown;
-       state->ca.slot_ts_enable        = az6027_ci_slot_ts_enable;
-       state->ca.poll_slot_status      = az6027_ci_poll_slot_status;
-       state->ca.data                  = d;
-
-       ret = dvb_ca_en50221_init(&a->dvb_adap,
-                                 &state->ca,
-                                 0, /* flags */
-                                 1);/* n_slots */
-       if (ret != 0) {
-               err("Cannot initialize CI: Error %d.", ret);
-               memset(&state->ca, 0, sizeof(state->ca));
-               return ret;
-       }
-
-       deb_info("CI initialized.");
-
-       return 0;
-}
-
-/*
-static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
-{
-       az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
-       return 0;
-}
-*/
-
-static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-
-       u8 buf;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-
-       struct i2c_msg i2c_msg = {
-               .addr   = 0x99,
-               .flags  = 0,
-               .buf    = &buf,
-               .len    = 1
-       };
-
-       /*
-        * 2   --18v
-        * 1   --13v
-        * 0   --off
-        */
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               buf = 1;
-               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
-               break;
-
-       case SEC_VOLTAGE_18:
-               buf = 2;
-               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
-               break;
-
-       case SEC_VOLTAGE_OFF:
-               buf = 0;
-               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-
-static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       req = 0xBC;
-       value = 1; /* power on */
-       index = 3;
-       blen = 0;
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               return -EIO;
-
-       return 0;
-}
-static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       /* reset demodulator */
-       req = 0xC0;
-       value = 1; /* high */
-       index = 3;
-       blen = 0;
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               return -EIO;
-
-       req = 0xC0;
-       value = 0; /* low */
-       index = 3;
-       blen = 0;
-       msleep_interruptible(200);
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               return -EIO;
-
-       msleep_interruptible(200);
-
-       req = 0xC0;
-       value = 1; /*high */
-       index = 3;
-       blen = 0;
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               return -EIO;
-
-       msleep_interruptible(200);
-       return 0;
-}
-
-static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-       u8 req;
-       u16 value;
-       u16 index;
-       int blen;
-
-       /* TS passthrough */
-       req = 0xC7;
-       value = onoff;
-       index = 0;
-       blen = 0;
-
-       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
-       if (ret != 0)
-               return -EIO;
-
-       return 0;
-}
-
-static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
-{
-
-       az6027_frontend_poweron(adap);
-       az6027_frontend_reset(adap);
-
-       deb_info("adap = %p, dev = %p\n", adap, adap->dev);
-       adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
-
-       if (adap->fe_adap[0].fe) {
-               deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
-               if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
-                       deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
-                       adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage;
-                       az6027_ci_init(adap);
-               } else {
-                       adap->fe_adap[0].fe = NULL;
-               }
-       } else
-               warn("no front-end attached\n");
-
-       az6027_frontend_tsbypass(adap, 0);
-
-       return 0;
-}
-
-static struct dvb_usb_device_properties az6027_properties;
-
-static void az6027_usb_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       az6027_ci_uninit(d);
-       dvb_usb_device_exit(intf);
-}
-
-
-static int az6027_usb_probe(struct usb_interface *intf,
-                           const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf,
-                                  &az6027_properties,
-                                  THIS_MODULE,
-                                  NULL,
-                                  adapter_nr);
-}
-
-/* I2C */
-static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i = 0, j = 0, len = 0;
-       u16 index;
-       u16 value;
-       int length;
-       u8 req;
-       u8 *data;
-
-       data = kmalloc(256, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
-               kfree(data);
-               return -EAGAIN;
-       }
-
-       if (num > 2)
-               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
-       for (i = 0; i < num; i++) {
-
-               if (msg[i].addr == 0x99) {
-                       req = 0xBE;
-                       index = 0;
-                       value = msg[i].buf[0] & 0x00ff;
-                       length = 1;
-                       az6027_usb_out_op(d, req, value, index, data, length);
-               }
-
-               if (msg[i].addr == 0xd0) {
-                       /* write/read request */
-                       if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
-                               req = 0xB9;
-                               index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
-                               value = msg[i].addr + (msg[i].len << 8);
-                               length = msg[i + 1].len + 6;
-                               az6027_usb_in_op(d, req, value, index, data, length);
-                               len = msg[i + 1].len;
-                               for (j = 0; j < len; j++)
-                                       msg[i + 1].buf[j] = data[j + 5];
-
-                               i++;
-                       } else {
-
-                               /* demod 16bit addr */
-                               req = 0xBD;
-                               index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
-                               value = msg[i].addr + (2 << 8);
-                               length = msg[i].len - 2;
-                               len = msg[i].len - 2;
-                               for (j = 0; j < len; j++)
-                                       data[j] = msg[i].buf[j + 2];
-                               az6027_usb_out_op(d, req, value, index, data, length);
-                       }
-               }
-
-               if (msg[i].addr == 0xc0) {
-                       if (msg[i].flags & I2C_M_RD) {
-
-                               req = 0xB9;
-                               index = 0x0;
-                               value = msg[i].addr;
-                               length = msg[i].len + 6;
-                               az6027_usb_in_op(d, req, value, index, data, length);
-                               len = msg[i].len;
-                               for (j = 0; j < len; j++)
-                                       msg[i].buf[j] = data[j + 5];
-
-                       } else {
-
-                               req = 0xBD;
-                               index = msg[i].buf[0] & 0x00FF;
-                               value = msg[i].addr + (1 << 8);
-                               length = msg[i].len - 1;
-                               len = msg[i].len - 1;
-
-                               for (j = 0; j < len; j++)
-                                       data[j] = msg[i].buf[j + 1];
-
-                               az6027_usb_out_op(d, req, value, index, data, length);
-                       }
-               }
-       }
-       mutex_unlock(&d->i2c_mutex);
-       kfree(data);
-
-       return i;
-}
-
-
-static u32 az6027_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm az6027_i2c_algo = {
-       .master_xfer   = az6027_i2c_xfer,
-       .functionality = az6027_i2c_func,
-};
-
-int az6027_identify_state(struct usb_device *udev,
-                         struct dvb_usb_device_properties *props,
-                         struct dvb_usb_device_description **desc,
-                         int *cold)
-{
-       u8 *b;
-       s16 ret;
-
-       b = kmalloc(16, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       ret = usb_control_msg(udev,
-                                 usb_rcvctrlpipe(udev, 0),
-                                 0xb7,
-                                 USB_TYPE_VENDOR | USB_DIR_IN,
-                                 6,
-                                 0,
-                                 b,
-                                 6,
-                                 USB_CTRL_GET_TIMEOUT);
-
-       *cold = ret <= 0;
-       kfree(b);
-       deb_info("cold: %d\n", *cold);
-       return 0;
-}
-
-
-static struct usb_device_id az6027_usb_table[] = {
-       { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V1) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V2) },
-       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
-       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
-       { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
-       { },
-};
-
-MODULE_DEVICE_TABLE(usb, az6027_usb_table);
-
-static struct dvb_usb_device_properties az6027_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware            = "dvb-usb-az6027-03.fw",
-       .no_reconnect        = 1,
-
-       .size_of_priv     = sizeof(struct az6027_device_state),
-       .identify_state         = az6027_identify_state,
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = az6027_streaming_ctrl,
-                       .frontend_attach  = az6027_frontend_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 10,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-/*
-       .power_ctrl       = az6027_power_ctrl,
-       .read_mac_address = az6027_read_mac_addr,
- */
-       .rc.legacy = {
-               .rc_map_table     = rc_map_az6027_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_az6027_table),
-               .rc_interval      = 400,
-               .rc_query         = az6027_rc_query,
-       },
-
-       .i2c_algo         = &az6027_i2c_algo,
-
-       .num_device_descs = 6,
-       .devices = {
-               {
-                       .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
-                       .cold_ids = { &az6027_usb_table[0], NULL },
-                       .warm_ids = { NULL },
-               }, {
-                       .name = "TERRATEC S7",
-                       .cold_ids = { &az6027_usb_table[1], NULL },
-                       .warm_ids = { NULL },
-               }, {
-                       .name = "TERRATEC S7 MKII",
-                       .cold_ids = { &az6027_usb_table[2], NULL },
-                       .warm_ids = { NULL },
-               }, {
-                       .name = "Technisat SkyStar USB 2 HD CI",
-                       .cold_ids = { &az6027_usb_table[3], NULL },
-                       .warm_ids = { NULL },
-               }, {
-                       .name = "Technisat SkyStar USB 2 HD CI",
-                       .cold_ids = { &az6027_usb_table[4], NULL },
-                       .warm_ids = { NULL },
-               }, {
-                       .name = "Elgato EyeTV Sat",
-                       .cold_ids = { &az6027_usb_table[5], NULL },
-                       .warm_ids = { NULL },
-               },
-               { NULL },
-       }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver az6027_usb_driver = {
-       .name           = "dvb_usb_az6027",
-       .probe          = az6027_usb_probe,
-       .disconnect     = az6027_usb_disconnect,
-       .id_table       = az6027_usb_table,
-};
-
-module_usb_driver(az6027_usb_driver);
-
-MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
-MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/az6027.h b/drivers/media/dvb/dvb-usb/az6027.h
deleted file mode 100644 (file)
index f3afe17..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _DVB_USB_VP6027_H_
-#define _DVB_USB_VP6027_H_
-
-#define DVB_USB_LOG_PREFIX "az6027"
-#include "dvb-usb.h"
-
-
-extern int dvb_usb_az6027_debug;
-#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
-#define deb_rc(args...)   dprintk(dvb_usb_az6027_debug, 0x04, args)
-#define deb_fe(args...)   dprintk(dvb_usb_az6027_debug, 0x08, args)
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
deleted file mode 100644 (file)
index 0a98548..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
- *
- * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
- *
- * Based on the dvb-usb-framework code and the
- * original Terratec Cinergy T2 driver by:
- *
- * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
- *                 Holger Waechtler <holger@qanu.de>
- *
- *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
- *
- * 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 "cinergyT2.h"
-
-
-/* debug */
-int dvb_usb_cinergyt2_debug;
-
-module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
-               "(or-able)).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct cinergyt2_state {
-       u8 rc_counter;
-};
-
-/* We are missing a release hook with usb_device data */
-static struct dvb_usb_device *cinergyt2_usb_device;
-
-static struct dvb_usb_device_properties cinergyt2_properties;
-
-static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
-{
-       char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
-       char result[64];
-       return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
-                               sizeof(result), 0);
-}
-
-static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
-{
-       char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
-       char state[3];
-       return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
-}
-
-static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
-       char state[3];
-       int ret;
-
-       adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
-
-       ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
-                               sizeof(state), 0);
-       if (ret < 0) {
-               deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
-                       "state info\n");
-       }
-
-       /* Copy this pointer as we are gonna need it in the release phase */
-       cinergyt2_usb_device = adap->dev;
-
-       return 0;
-}
-
-static struct rc_map_table rc_map_cinergyt2_table[] = {
-       { 0x0401, KEY_POWER },
-       { 0x0402, KEY_1 },
-       { 0x0403, KEY_2 },
-       { 0x0404, KEY_3 },
-       { 0x0405, KEY_4 },
-       { 0x0406, KEY_5 },
-       { 0x0407, KEY_6 },
-       { 0x0408, KEY_7 },
-       { 0x0409, KEY_8 },
-       { 0x040a, KEY_9 },
-       { 0x040c, KEY_0 },
-       { 0x040b, KEY_VIDEO },
-       { 0x040d, KEY_REFRESH },
-       { 0x040e, KEY_SELECT },
-       { 0x040f, KEY_EPG },
-       { 0x0410, KEY_UP },
-       { 0x0414, KEY_DOWN },
-       { 0x0411, KEY_LEFT },
-       { 0x0413, KEY_RIGHT },
-       { 0x0412, KEY_OK },
-       { 0x0415, KEY_TEXT },
-       { 0x0416, KEY_INFO },
-       { 0x0417, KEY_RED },
-       { 0x0418, KEY_GREEN },
-       { 0x0419, KEY_YELLOW },
-       { 0x041a, KEY_BLUE },
-       { 0x041c, KEY_VOLUMEUP },
-       { 0x041e, KEY_VOLUMEDOWN },
-       { 0x041d, KEY_MUTE },
-       { 0x041b, KEY_CHANNELUP },
-       { 0x041f, KEY_CHANNELDOWN },
-       { 0x0440, KEY_PAUSE },
-       { 0x044c, KEY_PLAY },
-       { 0x0458, KEY_RECORD },
-       { 0x0454, KEY_PREVIOUS },
-       { 0x0448, KEY_STOP },
-       { 0x045c, KEY_NEXT }
-};
-
-/* Number of keypresses to ignore before detect repeating */
-#define RC_REPEAT_DELAY 3
-
-static int repeatable_keys[] = {
-       KEY_UP,
-       KEY_DOWN,
-       KEY_LEFT,
-       KEY_RIGHT,
-       KEY_VOLUMEUP,
-       KEY_VOLUMEDOWN,
-       KEY_CHANNELUP,
-       KEY_CHANNELDOWN
-};
-
-static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       struct cinergyt2_state *st = d->priv;
-       u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
-       int i;
-
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
-       if (key[4] == 0xff) {
-               /* key repeat */
-               st->rc_counter++;
-               if (st->rc_counter > RC_REPEAT_DELAY) {
-                       for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
-                               if (d->last_event == repeatable_keys[i]) {
-                                       *state = REMOTE_KEY_REPEAT;
-                                       *event = d->last_event;
-                                       deb_rc("repeat key, event %x\n",
-                                                  *event);
-                                       return 0;
-                               }
-                       }
-                       deb_rc("repeated key (non repeatable)\n");
-               }
-               return 0;
-       }
-
-       /* hack to pass checksum on the custom field */
-       key[2] = ~key[1];
-       dvb_usb_nec_rc_key_to_event(d, key, event, state);
-       if (key[0] != 0) {
-               if (*event != d->last_event)
-                       st->rc_counter = 0;
-
-               deb_rc("key: %x %x %x %x %x\n",
-                      key[0], key[1], key[2], key[3], key[4]);
-       }
-       return 0;
-}
-
-static int cinergyt2_usb_probe(struct usb_interface *intf,
-                               const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &cinergyt2_properties,
-                                       THIS_MODULE, NULL, adapter_nr);
-}
-
-
-static struct usb_device_id cinergyt2_usb_table[] = {
-       { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
-       { 0 }
-};
-
-MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
-
-static struct dvb_usb_device_properties cinergyt2_properties = {
-       .size_of_priv = sizeof(struct cinergyt2_state),
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cinergyt2_streaming_ctrl,
-                       .frontend_attach  = cinergyt2_frontend_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 512,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-
-       .power_ctrl       = cinergyt2_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = 50,
-               .rc_map_table     = rc_map_cinergyt2_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_cinergyt2_table),
-               .rc_query         = cinergyt2_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 1,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
-                 .cold_ids = {NULL},
-                 .warm_ids = { &cinergyt2_usb_table[0], NULL },
-               },
-               { NULL },
-       }
-};
-
-
-static struct usb_driver cinergyt2_driver = {
-       .name           = "cinergyT2",
-       .probe          = cinergyt2_usb_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = cinergyt2_usb_table
-};
-
-module_usb_driver(cinergyt2_driver);
-
-MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
deleted file mode 100644 (file)
index 1efc028..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
- *
- * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
- *
- * Based on the dvb-usb-framework code and the
- * original Terratec Cinergy T2 driver by:
- *
- * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
- *                  Holger Waechtler <holger@qanu.de>
- *
- *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
- *
- * 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 "cinergyT2.h"
-
-
-/**
- *  convert linux-dvb frontend parameter set into TPS.
- *  See ETSI ETS-300744, section 4.6.2, table 9 for details.
- *
- *  This function is probably reusable and may better get placed in a support
- *  library.
- *
- *  We replace errornous fields by default TPS fields (the ones with value 0).
- */
-
-static uint16_t compute_tps(struct dtv_frontend_properties *op)
-{
-       uint16_t tps = 0;
-
-       switch (op->code_rate_HP) {
-       case FEC_2_3:
-               tps |= (1 << 7);
-               break;
-       case FEC_3_4:
-               tps |= (2 << 7);
-               break;
-       case FEC_5_6:
-               tps |= (3 << 7);
-               break;
-       case FEC_7_8:
-               tps |= (4 << 7);
-               break;
-       case FEC_1_2:
-       case FEC_AUTO:
-       default:
-               /* tps |= (0 << 7) */;
-       }
-
-       switch (op->code_rate_LP) {
-       case FEC_2_3:
-               tps |= (1 << 4);
-               break;
-       case FEC_3_4:
-               tps |= (2 << 4);
-               break;
-       case FEC_5_6:
-               tps |= (3 << 4);
-               break;
-       case FEC_7_8:
-               tps |= (4 << 4);
-               break;
-       case FEC_1_2:
-       case FEC_AUTO:
-       default:
-               /* tps |= (0 << 4) */;
-       }
-
-       switch (op->modulation) {
-       case QAM_16:
-               tps |= (1 << 13);
-               break;
-       case QAM_64:
-               tps |= (2 << 13);
-               break;
-       case QPSK:
-       default:
-               /* tps |= (0 << 13) */;
-       }
-
-       switch (op->transmission_mode) {
-       case TRANSMISSION_MODE_8K:
-               tps |= (1 << 0);
-               break;
-       case TRANSMISSION_MODE_2K:
-       default:
-               /* tps |= (0 << 0) */;
-       }
-
-       switch (op->guard_interval) {
-       case GUARD_INTERVAL_1_16:
-               tps |= (1 << 2);
-               break;
-       case GUARD_INTERVAL_1_8:
-               tps |= (2 << 2);
-               break;
-       case GUARD_INTERVAL_1_4:
-               tps |= (3 << 2);
-               break;
-       case GUARD_INTERVAL_1_32:
-       default:
-               /* tps |= (0 << 2) */;
-       }
-
-       switch (op->hierarchy) {
-       case HIERARCHY_1:
-               tps |= (1 << 10);
-               break;
-       case HIERARCHY_2:
-               tps |= (2 << 10);
-               break;
-       case HIERARCHY_4:
-               tps |= (3 << 10);
-               break;
-       case HIERARCHY_NONE:
-       default:
-               /* tps |= (0 << 10) */;
-       }
-
-       return tps;
-}
-
-struct cinergyt2_fe_state {
-       struct dvb_frontend fe;
-       struct dvb_usb_device *d;
-};
-
-static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
-                                       fe_status_t *status)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_get_status_msg result;
-       u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-       int ret;
-
-       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
-                       sizeof(result), 0);
-       if (ret < 0)
-               return ret;
-
-       *status = 0;
-
-       if (0xffff - le16_to_cpu(result.gain) > 30)
-               *status |= FE_HAS_SIGNAL;
-       if (result.lock_bits & (1 << 6))
-               *status |= FE_HAS_LOCK;
-       if (result.lock_bits & (1 << 5))
-               *status |= FE_HAS_SYNC;
-       if (result.lock_bits & (1 << 4))
-               *status |= FE_HAS_CARRIER;
-       if (result.lock_bits & (1 << 1))
-               *status |= FE_HAS_VITERBI;
-
-       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
-                       (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
-               *status &= ~FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_get_status_msg status;
-       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-       int ret;
-
-       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-                               sizeof(status), 0);
-       if (ret < 0)
-               return ret;
-
-       *ber = le32_to_cpu(status.viterbi_error_rate);
-       return 0;
-}
-
-static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_get_status_msg status;
-       u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-       int ret;
-
-       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
-                               sizeof(status), 0);
-       if (ret < 0) {
-               err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
-                       ret);
-               return ret;
-       }
-       *unc = le32_to_cpu(status.uncorrected_block_count);
-       return 0;
-}
-
-static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
-                                               u16 *strength)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_get_status_msg status;
-       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-       int ret;
-
-       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-                               sizeof(status), 0);
-       if (ret < 0) {
-               err("cinergyt2_fe_read_signal_strength() Failed!"
-                       " (Error=%d)\n", ret);
-               return ret;
-       }
-       *strength = (0xffff - le16_to_cpu(status.gain));
-       return 0;
-}
-
-static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_get_status_msg status;
-       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-       int ret;
-
-       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-                               sizeof(status), 0);
-       if (ret < 0) {
-               err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
-               return ret;
-       }
-       *snr = (status.snr << 8) | status.snr;
-       return 0;
-}
-
-static int cinergyt2_fe_init(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
-{
-       deb_info("cinergyt2_fe_sleep() Called\n");
-       return 0;
-}
-
-static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
-                               struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 800;
-       return 0;
-}
-
-static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       struct dvbt_set_parameters_msg param;
-       char result[2];
-       int err;
-
-       param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
-       param.tps = cpu_to_le16(compute_tps(fep));
-       param.freq = cpu_to_le32(fep->frequency / 1000);
-       param.flags = 0;
-
-       switch (fep->bandwidth_hz) {
-       default:
-       case 8000000:
-               param.bandwidth = 8;
-               break;
-       case 7000000:
-               param.bandwidth = 7;
-               break;
-       case 6000000:
-               param.bandwidth = 6;
-               break;
-       }
-
-       err = dvb_usb_generic_rw(state->d,
-                       (char *)&param, sizeof(param),
-                       result, sizeof(result), 0);
-       if (err < 0)
-               err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
-
-       return (err < 0) ? err : 0;
-}
-
-static void cinergyt2_fe_release(struct dvb_frontend *fe)
-{
-       struct cinergyt2_fe_state *state = fe->demodulator_priv;
-       if (state != NULL)
-               kfree(state);
-}
-
-static struct dvb_frontend_ops cinergyt2_fe_ops;
-
-struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
-{
-       struct cinergyt2_fe_state *s = kzalloc(sizeof(
-                                       struct cinergyt2_fe_state), GFP_KERNEL);
-       if (s == NULL)
-               return NULL;
-
-       s->d = d;
-       memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
-       s->fe.demodulator_priv = s;
-       return &s->fe;
-}
-
-
-static struct dvb_frontend_ops cinergyt2_fe_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = DRIVER_NAME,
-               .frequency_min          = 174000000,
-               .frequency_max          = 862000000,
-               .frequency_stepsize     = 166667,
-               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
-                       | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
-                       | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
-                       | FE_CAN_FEC_AUTO | FE_CAN_QPSK
-                       | FE_CAN_QAM_16 | FE_CAN_QAM_64
-                       | FE_CAN_QAM_AUTO
-                       | FE_CAN_TRANSMISSION_MODE_AUTO
-                       | FE_CAN_GUARD_INTERVAL_AUTO
-                       | FE_CAN_HIERARCHY_AUTO
-                       | FE_CAN_RECOVER
-                       | FE_CAN_MUTE_TS
-       },
-
-       .release                = cinergyt2_fe_release,
-
-       .init                   = cinergyt2_fe_init,
-       .sleep                  = cinergyt2_fe_sleep,
-
-       .set_frontend           = cinergyt2_fe_set_frontend,
-       .get_tune_settings      = cinergyt2_fe_get_tune_settings,
-
-       .read_status            = cinergyt2_fe_read_status,
-       .read_ber               = cinergyt2_fe_read_ber,
-       .read_signal_strength   = cinergyt2_fe_read_signal_strength,
-       .read_snr               = cinergyt2_fe_read_snr,
-       .read_ucblocks          = cinergyt2_fe_read_unc_blocks,
-};
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h
deleted file mode 100644 (file)
index 84efe03..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
- *
- * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
- *
- * Based on the dvb-usb-framework code and the
- * original Terratec Cinergy T2 driver by:
- *
- * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
- *                  Holger Waechtler <holger@qanu.de>
- *
- *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
- *
- * 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_USB_CINERGYT2_H_
-#define _DVB_USB_CINERGYT2_H_
-
-#include <linux/usb/input.h>
-
-#define DVB_USB_LOG_PREFIX "cinergyT2"
-#include "dvb-usb.h"
-
-#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
-
-extern int dvb_usb_cinergyt2_debug;
-
-#define deb_info(args...)  dprintk(dvb_usb_cinergyt2_debug,  0x001, args)
-#define deb_xfer(args...)  dprintk(dvb_usb_cinergyt2_debug,  0x002, args)
-#define deb_pll(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x004, args)
-#define deb_ts(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x008, args)
-#define deb_err(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x010, args)
-#define deb_rc(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x020, args)
-#define deb_fw(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x040, args)
-#define deb_mem(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x080, args)
-#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug,  0x100, args)
-
-
-
-enum cinergyt2_ep1_cmd {
-       CINERGYT2_EP1_PID_TABLE_RESET           = 0x01,
-       CINERGYT2_EP1_PID_SETUP                 = 0x02,
-       CINERGYT2_EP1_CONTROL_STREAM_TRANSFER   = 0x03,
-       CINERGYT2_EP1_SET_TUNER_PARAMETERS      = 0x04,
-       CINERGYT2_EP1_GET_TUNER_STATUS          = 0x05,
-       CINERGYT2_EP1_START_SCAN                = 0x06,
-       CINERGYT2_EP1_CONTINUE_SCAN             = 0x07,
-       CINERGYT2_EP1_GET_RC_EVENTS             = 0x08,
-       CINERGYT2_EP1_SLEEP_MODE                = 0x09,
-       CINERGYT2_EP1_GET_FIRMWARE_VERSION      = 0x0A
-};
-
-
-struct dvbt_get_status_msg {
-       uint32_t freq;
-       uint8_t bandwidth;
-       uint16_t tps;
-       uint8_t flags;
-       __le16 gain;
-       uint8_t snr;
-       __le32 viterbi_error_rate;
-       uint32_t rs_error_rate;
-       __le32 uncorrected_block_count;
-       uint8_t lock_bits;
-       uint8_t prev_lock_bits;
-} __attribute__((packed));
-
-
-struct dvbt_set_parameters_msg {
-       uint8_t cmd;
-       __le32 freq;
-       uint8_t bandwidth;
-       __le16 tps;
-       uint8_t flags;
-} __attribute__((packed));
-
-
-extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
-
-#endif /* _DVB_USB_CINERGYT2_H_ */
-
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
deleted file mode 100644 (file)
index 3940bb0..0000000
+++ /dev/null
@@ -1,2043 +0,0 @@
-/* DVB USB compliant linux driver for Conexant USB reference design.
- *
- * The Conexant reference design I saw on their website was only for analogue
- * capturing (using the cx25842). The box I took to write this driver (reverse
- * engineered) is the one labeled Medion MD95700. In addition to the cx25842
- * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
- * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
- *
- * Maybe it is a little bit premature to call this driver cxusb, but I assume
- * the USB protocol is identical or at least inherited from the reference
- * design, so it can be reused for the "analogue-only" device (if it will
- * appear at all).
- *
- * TODO: Use the cx25840-driver for the analogue part
- *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
- * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
- * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
- *
- *   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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include <media/tuner.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#include "cxusb.h"
-
-#include "cx22702.h"
-#include "lgdt330x.h"
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "zl10353.h"
-#include "tuner-xc2028.h"
-#include "tuner-simple.h"
-#include "mxl5005s.h"
-#include "max2165.h"
-#include "dib7000p.h"
-#include "dib0070.h"
-#include "lgs8gxx.h"
-#include "atbm8830.h"
-
-/* debug */
-static int dvb_usb_cxusb_debug;
-module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_info(args...)   dprintk(dvb_usb_cxusb_debug, 0x03, args)
-#define deb_i2c(args...)    dprintk(dvb_usb_cxusb_debug, 0x02, args)
-
-static int cxusb_ctrl_msg(struct dvb_usb_device *d,
-                         u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       int wo = (rbuf == NULL || rlen == 0); /* write-only */
-       u8 sndbuf[1+wlen];
-       memset(sndbuf, 0, 1+wlen);
-
-       sndbuf[0] = cmd;
-       memcpy(&sndbuf[1], wbuf, wlen);
-       if (wo)
-               return dvb_usb_generic_write(d, sndbuf, 1+wlen);
-       else
-               return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
-}
-
-/* GPIO */
-static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
-{
-       struct cxusb_state *st = d->priv;
-       u8 o[2], i;
-
-       if (st->gpio_write_state[GPIO_TUNER] == onoff)
-               return;
-
-       o[0] = GPIO_TUNER;
-       o[1] = onoff;
-       cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
-
-       if (i != 0x01)
-               deb_info("gpio_write failed.\n");
-
-       st->gpio_write_state[GPIO_TUNER] = onoff;
-}
-
-static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
-                                u8 newval)
-{
-       u8 o[2], gpio_state;
-       int rc;
-
-       o[0] = 0xff & ~changemask;      /* mask of bits to keep */
-       o[1] = newval & changemask;     /* new values for bits  */
-
-       rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
-       if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
-               deb_info("bluebird_gpio_write failed.\n");
-
-       return rc < 0 ? rc : gpio_state;
-}
-
-static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
-{
-       cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
-       msleep(5);
-       cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
-}
-
-static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
-{
-       cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
-}
-
-static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
-               u8 addr, int onoff)
-{
-       u8  o[2] = {addr, onoff};
-       u8  i;
-       int rc;
-
-       rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
-
-       if (rc < 0)
-               return rc;
-       if (i == 0x01)
-               return 0;
-       else {
-               deb_info("gpio_write failed.\n");
-               return -EIO;
-       }
-}
-
-/* I2C */
-static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-
-               if (d->udev->descriptor.idVendor == USB_VID_MEDION)
-                       switch (msg[i].addr) {
-                       case 0x63:
-                               cxusb_gpio_tuner(d, 0);
-                               break;
-                       default:
-                               cxusb_gpio_tuner(d, 1);
-                               break;
-                       }
-
-               if (msg[i].flags & I2C_M_RD) {
-                       /* read only */
-                       u8 obuf[3], ibuf[1+msg[i].len];
-                       obuf[0] = 0;
-                       obuf[1] = msg[i].len;
-                       obuf[2] = msg[i].addr;
-                       if (cxusb_ctrl_msg(d, CMD_I2C_READ,
-                                          obuf, 3,
-                                          ibuf, 1+msg[i].len) < 0) {
-                               warn("i2c read failed");
-                               break;
-                       }
-                       memcpy(msg[i].buf, &ibuf[1], msg[i].len);
-               } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
-                          msg[i].addr == msg[i+1].addr) {
-                       /* write to then read from same address */
-                       u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
-                       obuf[0] = msg[i].len;
-                       obuf[1] = msg[i+1].len;
-                       obuf[2] = msg[i].addr;
-                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
-
-                       if (cxusb_ctrl_msg(d, CMD_I2C_READ,
-                                          obuf, 3+msg[i].len,
-                                          ibuf, 1+msg[i+1].len) < 0)
-                               break;
-
-                       if (ibuf[0] != 0x08)
-                               deb_i2c("i2c read may have failed\n");
-
-                       memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
-
-                       i++;
-               } else {
-                       /* write only */
-                       u8 obuf[2+msg[i].len], ibuf;
-                       obuf[0] = msg[i].addr;
-                       obuf[1] = msg[i].len;
-                       memcpy(&obuf[2], msg[i].buf, msg[i].len);
-
-                       if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
-                                          2+msg[i].len, &ibuf,1) < 0)
-                               break;
-                       if (ibuf != 0x08)
-                               deb_i2c("i2c write may have failed\n");
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i == num ? num : -EREMOTEIO;
-}
-
-static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm cxusb_i2c_algo = {
-       .master_xfer   = cxusb_i2c_xfer,
-       .functionality = cxusb_i2c_func,
-};
-
-static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 b = 0;
-       if (onoff)
-               return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
-       else
-               return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
-}
-
-static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-       if (!onoff)
-               return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
-       if (d->state == DVB_USB_STATE_INIT &&
-           usb_set_interface(d->udev, 0, 0) < 0)
-               err("set interface failed");
-       do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
-                  !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
-                  !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
-       if (!ret) {
-               /* FIXME: We don't know why, but we need to configure the
-                * lgdt3303 with the register settings below on resume */
-               int i;
-               u8 buf, bufs[] = {
-                       0x0e, 0x2, 0x00, 0x7f,
-                       0x0e, 0x2, 0x02, 0xfe,
-                       0x0e, 0x2, 0x02, 0x01,
-                       0x0e, 0x2, 0x00, 0x03,
-                       0x0e, 0x2, 0x0d, 0x40,
-                       0x0e, 0x2, 0x0e, 0x87,
-                       0x0e, 0x2, 0x0f, 0x8e,
-                       0x0e, 0x2, 0x10, 0x01,
-                       0x0e, 0x2, 0x14, 0xd7,
-                       0x0e, 0x2, 0x47, 0x88,
-               };
-               msleep(20);
-               for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
-                       ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
-                                            bufs+i, 4, &buf, 1);
-                       if (ret)
-                               break;
-                       if (buf != 0x8)
-                               return -EREMOTEIO;
-               }
-       }
-       return ret;
-}
-
-static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 b = 0;
-       if (onoff)
-               return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
-       else
-               return 0;
-}
-
-static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int rc = 0;
-
-       rc = cxusb_power_ctrl(d, onoff);
-       if (!onoff)
-               cxusb_nano2_led(d, 0);
-
-       return rc;
-}
-
-static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-       u8  b;
-       ret = cxusb_power_ctrl(d, onoff);
-       if (!onoff)
-               return ret;
-
-       msleep(128);
-       cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
-       msleep(100);
-       return ret;
-}
-
-static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       u8 buf[2] = { 0x03, 0x00 };
-       if (onoff)
-               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
-       else
-               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
-
-       return 0;
-}
-
-static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       if (onoff)
-               cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
-       else
-               cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
-                              NULL, 0, NULL, 0);
-       return 0;
-}
-
-static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
-{
-       int       ep = d->props.generic_bulk_ctrl_endpoint;
-       const int timeout = 100;
-       const int junk_len = 32;
-       u8        *junk;
-       int       rd_count;
-
-       /* Discard remaining data in video pipe */
-       junk = kmalloc(junk_len, GFP_KERNEL);
-       if (!junk)
-               return;
-       while (1) {
-               if (usb_bulk_msg(d->udev,
-                       usb_rcvbulkpipe(d->udev, ep),
-                       junk, junk_len, &rd_count, timeout) < 0)
-                       break;
-               if (!rd_count)
-                       break;
-       }
-       kfree(junk);
-}
-
-static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
-{
-       struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
-       const int timeout = 100;
-       const int junk_len = p->u.bulk.buffersize;
-       u8        *junk;
-       int       rd_count;
-
-       /* Discard remaining data in video pipe */
-       junk = kmalloc(junk_len, GFP_KERNEL);
-       if (!junk)
-               return;
-       while (1) {
-               if (usb_bulk_msg(d->udev,
-                       usb_rcvbulkpipe(d->udev, p->endpoint),
-                       junk, junk_len, &rd_count, timeout) < 0)
-                       break;
-               if (!rd_count)
-                       break;
-       }
-       kfree(junk);
-}
-
-static int cxusb_d680_dmb_streaming_ctrl(
-               struct dvb_usb_adapter *adap, int onoff)
-{
-       if (onoff) {
-               u8 buf[2] = { 0x03, 0x00 };
-               cxusb_d680_dmb_drain_video(adap->dev);
-               return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
-                       buf, sizeof(buf), NULL, 0);
-       } else {
-               int ret = cxusb_ctrl_msg(adap->dev,
-                       CMD_STREAMING_OFF, NULL, 0, NULL, 0);
-               return ret;
-       }
-}
-
-static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       u8 ircode[4];
-       int i;
-
-       cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
-
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[2] &&
-                   rc5_data(&keymap[i]) == ircode[3]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
-       return 0;
-}
-
-static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
-                                   int *state)
-{
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       u8 ircode[4];
-       int i;
-       struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
-                              .buf = ircode, .len = 4 };
-
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
-               return 0;
-
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[1] &&
-                   rc5_data(&keymap[i]) == ircode[2]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
-       return 0;
-}
-
-static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
-               int *state)
-{
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       u8 ircode[2];
-       int i;
-
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
-               return 0;
-
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[0] &&
-                   rc5_data(&keymap[i]) == ircode[1]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
-       return 0;
-}
-
-static struct rc_map_table rc_map_dvico_mce_table[] = {
-       { 0xfe02, KEY_TV },
-       { 0xfe0e, KEY_MP3 },
-       { 0xfe1a, KEY_DVD },
-       { 0xfe1e, KEY_FAVORITES },
-       { 0xfe16, KEY_SETUP },
-       { 0xfe46, KEY_POWER2 },
-       { 0xfe0a, KEY_EPG },
-       { 0xfe49, KEY_BACK },
-       { 0xfe4d, KEY_MENU },
-       { 0xfe51, KEY_UP },
-       { 0xfe5b, KEY_LEFT },
-       { 0xfe5f, KEY_RIGHT },
-       { 0xfe53, KEY_DOWN },
-       { 0xfe5e, KEY_OK },
-       { 0xfe59, KEY_INFO },
-       { 0xfe55, KEY_TAB },
-       { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
-       { 0xfe12, KEY_NEXTSONG },       /* Skip */
-       { 0xfe42, KEY_ENTER      },     /* Windows/Start */
-       { 0xfe15, KEY_VOLUMEUP },
-       { 0xfe05, KEY_VOLUMEDOWN },
-       { 0xfe11, KEY_CHANNELUP },
-       { 0xfe09, KEY_CHANNELDOWN },
-       { 0xfe52, KEY_CAMERA },
-       { 0xfe5a, KEY_TUNER },  /* Live */
-       { 0xfe19, KEY_OPEN },
-       { 0xfe0b, KEY_1 },
-       { 0xfe17, KEY_2 },
-       { 0xfe1b, KEY_3 },
-       { 0xfe07, KEY_4 },
-       { 0xfe50, KEY_5 },
-       { 0xfe54, KEY_6 },
-       { 0xfe48, KEY_7 },
-       { 0xfe4c, KEY_8 },
-       { 0xfe58, KEY_9 },
-       { 0xfe13, KEY_ANGLE },  /* Aspect */
-       { 0xfe03, KEY_0 },
-       { 0xfe1f, KEY_ZOOM },
-       { 0xfe43, KEY_REWIND },
-       { 0xfe47, KEY_PLAYPAUSE },
-       { 0xfe4f, KEY_FASTFORWARD },
-       { 0xfe57, KEY_MUTE },
-       { 0xfe0d, KEY_STOP },
-       { 0xfe01, KEY_RECORD },
-       { 0xfe4e, KEY_POWER },
-};
-
-static struct rc_map_table rc_map_dvico_portable_table[] = {
-       { 0xfc02, KEY_SETUP },       /* Profile */
-       { 0xfc43, KEY_POWER2 },
-       { 0xfc06, KEY_EPG },
-       { 0xfc5a, KEY_BACK },
-       { 0xfc05, KEY_MENU },
-       { 0xfc47, KEY_INFO },
-       { 0xfc01, KEY_TAB },
-       { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
-       { 0xfc49, KEY_VOLUMEUP },
-       { 0xfc09, KEY_VOLUMEDOWN },
-       { 0xfc54, KEY_CHANNELUP },
-       { 0xfc0b, KEY_CHANNELDOWN },
-       { 0xfc16, KEY_CAMERA },
-       { 0xfc40, KEY_TUNER },  /* ATV/DTV */
-       { 0xfc45, KEY_OPEN },
-       { 0xfc19, KEY_1 },
-       { 0xfc18, KEY_2 },
-       { 0xfc1b, KEY_3 },
-       { 0xfc1a, KEY_4 },
-       { 0xfc58, KEY_5 },
-       { 0xfc59, KEY_6 },
-       { 0xfc15, KEY_7 },
-       { 0xfc14, KEY_8 },
-       { 0xfc17, KEY_9 },
-       { 0xfc44, KEY_ANGLE },  /* Aspect */
-       { 0xfc55, KEY_0 },
-       { 0xfc07, KEY_ZOOM },
-       { 0xfc0a, KEY_REWIND },
-       { 0xfc08, KEY_PLAYPAUSE },
-       { 0xfc4b, KEY_FASTFORWARD },
-       { 0xfc5b, KEY_MUTE },
-       { 0xfc04, KEY_STOP },
-       { 0xfc56, KEY_RECORD },
-       { 0xfc57, KEY_POWER },
-       { 0xfc41, KEY_UNKNOWN },    /* INPUT */
-       { 0xfc00, KEY_UNKNOWN },    /* HD */
-};
-
-static struct rc_map_table rc_map_d680_dmb_table[] = {
-       { 0x0038, KEY_UNKNOWN },        /* TV/AV */
-       { 0x080c, KEY_ZOOM },
-       { 0x0800, KEY_0 },
-       { 0x0001, KEY_1 },
-       { 0x0802, KEY_2 },
-       { 0x0003, KEY_3 },
-       { 0x0804, KEY_4 },
-       { 0x0005, KEY_5 },
-       { 0x0806, KEY_6 },
-       { 0x0007, KEY_7 },
-       { 0x0808, KEY_8 },
-       { 0x0009, KEY_9 },
-       { 0x000a, KEY_MUTE },
-       { 0x0829, KEY_BACK },
-       { 0x0012, KEY_CHANNELUP },
-       { 0x0813, KEY_CHANNELDOWN },
-       { 0x002b, KEY_VOLUMEUP },
-       { 0x082c, KEY_VOLUMEDOWN },
-       { 0x0020, KEY_UP },
-       { 0x0821, KEY_DOWN },
-       { 0x0011, KEY_LEFT },
-       { 0x0810, KEY_RIGHT },
-       { 0x000d, KEY_OK },
-       { 0x081f, KEY_RECORD },
-       { 0x0017, KEY_PLAYPAUSE },
-       { 0x0816, KEY_PLAYPAUSE },
-       { 0x000b, KEY_STOP },
-       { 0x0827, KEY_FASTFORWARD },
-       { 0x0026, KEY_REWIND },
-       { 0x081e, KEY_UNKNOWN },    /* Time Shift */
-       { 0x000e, KEY_UNKNOWN },    /* Snapshot */
-       { 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
-       { 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
-       { 0x0814, KEY_UNKNOWN },    /* Shuffle */
-       { 0x0025, KEY_POWER },
-};
-
-static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
-{
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
-       static u8 reset []         = { RESET,      0x80 };
-       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
-       static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
-       static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
-       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
-       mt352_write(fe, clock_config,   sizeof(clock_config));
-       udelay(200);
-       mt352_write(fe, reset,          sizeof(reset));
-       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
-
-       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
-       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
-       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
-       return 0;
-}
-
-static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
-{      /* used in both lgz201 and th7579 */
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
-       static u8 reset []         = { RESET,      0x80 };
-       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
-       static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
-       static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
-       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
-       mt352_write(fe, clock_config,   sizeof(clock_config));
-       udelay(200);
-       mt352_write(fe, reset,          sizeof(reset));
-       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
-
-       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
-       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
-       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-       return 0;
-}
-
-static struct cx22702_config cxusb_cx22702_config = {
-       .demod_address = 0x63,
-       .output_mode = CX22702_PARALLEL_OUTPUT,
-};
-
-static struct lgdt330x_config cxusb_lgdt3303_config = {
-       .demod_address = 0x0e,
-       .demod_chip    = LGDT3303,
-};
-
-static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
-       .demod_address       = 0x0e,
-       .demod_chip          = LGDT3303,
-       .clock_polarity_flip = 2,
-};
-
-static struct mt352_config cxusb_dee1601_config = {
-       .demod_address = 0x0f,
-       .demod_init    = cxusb_dee1601_demod_init,
-};
-
-static struct zl10353_config cxusb_zl10353_dee1601_config = {
-       .demod_address = 0x0f,
-       .parallel_ts = 1,
-};
-
-static struct mt352_config cxusb_mt352_config = {
-       /* used in both lgz201 and th7579 */
-       .demod_address = 0x0f,
-       .demod_init    = cxusb_mt352_demod_init,
-};
-
-static struct zl10353_config cxusb_zl10353_xc3028_config = {
-       .demod_address = 0x0f,
-       .if2 = 45600,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
-       .demod_address = 0x0f,
-       .if2 = 45600,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-       .disable_i2c_gate_ctrl = 1,
-};
-
-static struct mt352_config cxusb_mt352_xc3028_config = {
-       .demod_address = 0x0f,
-       .if2 = 4560,
-       .no_tuner = 1,
-       .demod_init = cxusb_mt352_demod_init,
-};
-
-/* FIXME: needs tweaking */
-static struct mxl5005s_config aver_a868r_tuner = {
-       .i2c_address     = 0x63,
-       .if_freq         = 6000000UL,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_C,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-/* FIXME: needs tweaking */
-static struct mxl5005s_config d680_dmb_tuner = {
-       .i2c_address     = 0x63,
-       .if_freq         = 36125000UL,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_C,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static struct max2165_config mygica_d689_max2165_cfg = {
-       .i2c_address = 0x60,
-       .osc_clk = 20
-};
-
-/* Callbacks for DVB USB */
-static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
-                  &adap->dev->i2c_adap, 0x61,
-                  TUNER_PHILIPS_FMD1216ME_MK3);
-       return 0;
-}
-
-static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
-                  NULL, DVB_PLL_THOMSON_DTT7579);
-       return 0;
-}
-
-static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
-       return 0;
-}
-
-static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
-                  NULL, DVB_PLL_THOMSON_DTT7579);
-       return 0;
-}
-
-static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
-                  &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
-       return 0;
-}
-
-static int dvico_bluebird_xc2028_callback(void *ptr, int component,
-                                         int command, int arg)
-{
-       struct dvb_usb_adapter *adap = ptr;
-       struct dvb_usb_device *d = adap->dev;
-
-       switch (command) {
-       case XC2028_TUNER_RESET:
-               deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
-               cxusb_bluebird_gpio_pulse(d, 0x01, 1);
-               break;
-       case XC2028_RESET_CLK:
-               deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
-               break;
-       default:
-               deb_info("%s: unknown command %d, arg %d\n", __func__,
-                        command, arg);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_frontend      *fe;
-       struct xc2028_config      cfg = {
-               .i2c_adap  = &adap->dev->i2c_adap,
-               .i2c_addr  = 0x61,
-       };
-       static struct xc2028_ctrl ctl = {
-               .fname       = XC2028_DEFAULT_FIRMWARE,
-               .max_len     = 64,
-               .demod       = XC3028_FE_ZARLINK456,
-       };
-
-       /* FIXME: generalize & move to common area */
-       adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
-
-       fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
-       if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
-               return -EIO;
-
-       fe->ops.tuner_ops.set_config(fe, &ctl);
-
-       return 0;
-}
-
-static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
-                  &adap->dev->i2c_adap, &aver_a868r_tuner);
-       return 0;
-}
-
-static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_frontend *fe;
-       fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
-                       &adap->dev->i2c_adap, &d680_dmb_tuner);
-       return (fe == NULL) ? -EIO : 0;
-}
-
-static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_frontend *fe;
-       fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
-                       &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
-       return (fe == NULL) ? -EIO : 0;
-}
-
-static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       u8 b;
-       if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
-
-       adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
-                                        &cxusb_lgdt3303_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
-                             &adap->dev->i2c_adap);
-       if (adap->fe_adap[0].fe != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       /* used in both lgz201 and th7579 */
-       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
-                                        &cxusb_zl10353_dee1601_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       u8 ircode[4];
-       int i;
-       struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
-                              .buf = ircode, .len = 4 };
-
-       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       /* reset the tuner and demodulator */
-       cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
-       cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
-       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
-
-       adap->fe_adap[0].fe =
-               dvb_attach(zl10353_attach,
-                          &cxusb_zl10353_xc3028_config_no_i2c_gate,
-                          &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) == NULL)
-               return -EIO;
-
-       /* try to determine if there is no IR decoder on the I2C bus */
-       for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
-               msleep(20);
-               if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
-                       goto no_IR;
-               if (ircode[0] == 0 && ircode[1] == 0)
-                       continue;
-               if (ircode[2] + ircode[3] != 0xff) {
-no_IR:
-                       adap->dev->props.rc.legacy.rc_map_table = NULL;
-                       info("No IR receiver detected on this device.");
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static struct dibx000_agc_config dib7070_agc_config = {
-       .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
-
-       /*
-        * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
-        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
-        */
-       .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
-                (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-       .inv_gain = 600,
-       .time_stabiliz = 10,
-       .alpha_level = 0,
-       .thlock = 118,
-       .wbd_inv = 0,
-       .wbd_ref = 3530,
-       .wbd_sel = 1,
-       .wbd_alpha = 5,
-       .agc1_max = 65535,
-       .agc1_min = 0,
-       .agc2_max = 65535,
-       .agc2_min = 0,
-       .agc1_pt1 = 0,
-       .agc1_pt2 = 40,
-       .agc1_pt3 = 183,
-       .agc1_slope1 = 206,
-       .agc1_slope2 = 255,
-       .agc2_pt1 = 72,
-       .agc2_pt2 = 152,
-       .agc2_slope1 = 88,
-       .agc2_slope2 = 90,
-       .alpha_mant = 17,
-       .alpha_exp = 27,
-       .beta_mant = 23,
-       .beta_exp = 51,
-       .perform_agc_softsplit = 0,
-};
-
-static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
-       .internal = 60000,
-       .sampling = 15000,
-       .pll_prediv = 1,
-       .pll_ratio = 20,
-       .pll_range = 3,
-       .pll_reset = 1,
-       .pll_bypass = 0,
-       .enable_refdiv = 0,
-       .bypclk_div = 0,
-       .IO_CLK_en_core = 1,
-       .ADClkSrc = 1,
-       .modulo = 2,
-       /* refsel, sel, freq_15k */
-       .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
-       .ifreq = (0 << 25) | 0,
-       .timf = 20452225,
-       .xtal_hz = 12000000,
-};
-
-static struct dib7000p_config cxusb_dualdig4_rev2_config = {
-       .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 1,
-       .agc = &dib7070_agc_config,
-       .bw  = &dib7070_bw_config_12_mhz,
-       .tuner_is_baseband = 1,
-       .spur_protect = 1,
-
-       .gpio_dir = 0xfcef,
-       .gpio_val = 0x0110,
-
-       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .hostbus_diversity = 1,
-};
-
-static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                                    &cxusb_dualdig4_rev2_config) < 0) {
-               printk(KERN_WARNING "Unable to enumerate dib7000p\n");
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
-                             &cxusb_dualdig4_rev2_config);
-       if (adap->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
-{
-       return dib7000p_set_gpio(fe, 8, 0, !onoff);
-}
-
-static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       return 0;
-}
-
-static struct dib0070_config dib7070p_dib0070_config = {
-       .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-       .reset = dib7070_tuner_reset,
-       .sleep = dib7070_tuner_sleep,
-       .clock_khz = 12000,
-};
-
-struct dib0700_adapter_state {
-       int (*set_param_save) (struct dvb_frontend *);
-};
-
-static int dib7070_set_param_override(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-
-       u16 offset;
-       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
-       switch (band) {
-       case BAND_VHF: offset = 950; break;
-       default:
-       case BAND_UHF: offset = 550; break;
-       }
-
-       dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
-
-       return state->set_param_save(fe);
-}
-
-static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c =
-               dib7000p_get_i2c_master(adap->fe_adap[0].fe,
-                                       DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
-           &dib7070p_dib0070_config) == NULL)
-               return -ENODEV;
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
-       return 0;
-}
-
-static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
-               err("set interface failed");
-
-       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
-
-       /* reset the tuner and demodulator */
-       cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
-       cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
-       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
-
-       adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
-                                        &cxusb_zl10353_xc3028_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach,
-                                        &cxusb_mt352_xc3028_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL)
-               return 0;
-
-       return -EIO;
-}
-
-static struct lgs8gxx_config d680_lgs8gl5_cfg = {
-       .prod = LGS8GXX_PROD_LGS8GL5,
-       .demod_address = 0x19,
-       .serial_ts = 0,
-       .ts_clk_pol = 0,
-       .ts_clk_gated = 1,
-       .if_clk_freq = 30400, /* 30.4 MHz */
-       .if_freq = 5725, /* 5.725 MHz */
-       .if_neg_center = 0,
-       .ext_adc = 0,
-       .adc_signed = 0,
-       .if_neg_edge = 0,
-};
-
-static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap->dev;
-       int n;
-
-       /* Select required USB configuration */
-       if (usb_set_interface(d->udev, 0, 0) < 0)
-               err("set interface failed");
-
-       /* Unblock all USB pipes */
-       usb_clear_halt(d->udev,
-               usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-       usb_clear_halt(d->udev,
-               usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-       usb_clear_halt(d->udev,
-               usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
-
-       /* Drain USB pipes to avoid hang after reboot */
-       for (n = 0;  n < 5;  n++) {
-               cxusb_d680_dmb_drain_message(d);
-               cxusb_d680_dmb_drain_video(d);
-               msleep(200);
-       }
-
-       /* Reset the tuner */
-       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
-               err("clear tuner gpio failed");
-               return -EIO;
-       }
-       msleep(100);
-       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
-               err("set tuner gpio failed");
-               return -EIO;
-       }
-       msleep(100);
-
-       /* Attach frontend */
-       adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
-       if (adap->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static struct atbm8830_config mygica_d689_atbm8830_cfg = {
-       .prod = ATBM8830_PROD_8830,
-       .demod_address = 0x40,
-       .serial_ts = 0,
-       .ts_sampling_edge = 1,
-       .ts_clk_gated = 0,
-       .osc_clk_freq = 30400, /* in kHz */
-       .if_freq = 0, /* zero IF */
-       .zif_swap_iq = 1,
-       .agc_min = 0x2E,
-       .agc_max = 0x90,
-       .agc_hold_loop = 0,
-};
-
-static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap->dev;
-
-       /* Select required USB configuration */
-       if (usb_set_interface(d->udev, 0, 0) < 0)
-               err("set interface failed");
-
-       /* Unblock all USB pipes */
-       usb_clear_halt(d->udev,
-               usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-       usb_clear_halt(d->udev,
-               usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-       usb_clear_halt(d->udev,
-               usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
-
-
-       /* Reset the tuner */
-       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
-               err("clear tuner gpio failed");
-               return -EIO;
-       }
-       msleep(100);
-       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
-               err("set tuner gpio failed");
-               return -EIO;
-       }
-       msleep(100);
-
-       /* Attach frontend */
-       adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
-               &d->i2c_adap);
-       if (adap->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-/*
- * DViCO has shipped two devices with the same USB ID, but only one of them
- * needs a firmware download.  Check the device class details to see if they
- * have non-default values to decide whether the device is actually cold or
- * not, and forget a match if it turns out we selected the wrong device.
- */
-static int bluebird_fx2_identify_state(struct usb_device *udev,
-                                      struct dvb_usb_device_properties *props,
-                                      struct dvb_usb_device_description **desc,
-                                      int *cold)
-{
-       int wascold = *cold;
-
-       *cold = udev->descriptor.bDeviceClass == 0xff &&
-               udev->descriptor.bDeviceSubClass == 0xff &&
-               udev->descriptor.bDeviceProtocol == 0xff;
-
-       if (*cold && !wascold)
-               *desc = NULL;
-
-       return 0;
-}
-
-/*
- * DViCO bluebird firmware needs the "warm" product ID to be patched into the
- * firmware file before download.
- */
-
-static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
-static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
-                                                 const struct firmware *fw)
-{
-       int pos;
-
-       for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
-               int idoff = dvico_firmware_id_offsets[pos];
-
-               if (fw->size < idoff + 4)
-                       continue;
-
-               if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
-                   fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
-                       struct firmware new_fw;
-                       u8 *new_fw_data = vmalloc(fw->size);
-                       int ret;
-
-                       if (!new_fw_data)
-                               return -ENOMEM;
-
-                       memcpy(new_fw_data, fw->data, fw->size);
-                       new_fw.size = fw->size;
-                       new_fw.data = new_fw_data;
-
-                       new_fw_data[idoff + 2] =
-                               le16_to_cpu(udev->descriptor.idProduct) + 1;
-                       new_fw_data[idoff + 3] =
-                               le16_to_cpu(udev->descriptor.idProduct) >> 8;
-
-                       ret = usb_cypress_load_firmware(udev, &new_fw,
-                                                       CYPRESS_FX2);
-                       vfree(new_fw_data);
-                       return ret;
-               }
-       }
-
-       return -EINVAL;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties cxusb_medion_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
-static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
-static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
-static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
-static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
-
-static int cxusb_probe(struct usb_interface *intf,
-                      const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf,
-                               &cxusb_bluebird_nano2_needsfirmware_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf,
-                                    &cxusb_bluebird_dualdig4_rev2_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0)
-               return 0;
-
-       return -EINVAL;
-}
-
-static struct usb_device_id cxusb_table [] = {
-       { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
-       { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
-       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
-       { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
-       { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
-       {}              /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, cxusb_table);
-
-static struct dvb_usb_device_properties cxusb_medion_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_cx22702_frontend_attach,
-                       .tuner_attach     = cxusb_fmd1216me_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                                       .stream = {
-                                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-       .power_ctrl       = cxusb_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Medion MD95700 (MDUSBTV-HYBRID)",
-                       { NULL },
-                       { &cxusb_table[0], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = DEVICE_SPECIFIC,
-       .firmware          = "dvb-usb-bluebird-01.fw",
-       .download_firmware = bluebird_patch_dvico_firmware_download,
-       /* use usb alt setting 0 for EP4 transfer (dvb-t),
-          use usb alt setting 7 for EP2 transfer (atsc) */
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_lgdt3303_frontend_attach,
-                       .tuner_attach     = cxusb_lgh064f_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                                       .stream = {
-                                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV5 USB Gold",
-                       { &cxusb_table[1], NULL },
-                       { &cxusb_table[2], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = DEVICE_SPECIFIC,
-       .firmware          = "dvb-usb-bluebird-01.fw",
-       .download_firmware = bluebird_patch_dvico_firmware_download,
-       /* use usb alt setting 0 for EP4 transfer (dvb-t),
-          use usb alt setting 7 for EP2 transfer (atsc) */
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_dee1601_frontend_attach,
-                       .tuner_attach     = cxusb_dee1601_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x04,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc.legacy = {
-               .rc_interval      = 150,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 3,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T Dual USB",
-                       { &cxusb_table[3], NULL },
-                       { &cxusb_table[4], NULL },
-               },
-               {   "DigitalNow DVB-T Dual USB",
-                       { &cxusb_table[9],  NULL },
-                       { &cxusb_table[10], NULL },
-               },
-               {   "DViCO FusionHDTV DVB-T Dual Digital 2",
-                       { &cxusb_table[11], NULL },
-                       { &cxusb_table[12], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = DEVICE_SPECIFIC,
-       .firmware          = "dvb-usb-bluebird-01.fw",
-       .download_firmware = bluebird_patch_dvico_firmware_download,
-       /* use usb alt setting 0 for EP4 transfer (dvb-t),
-          use usb alt setting 7 for EP2 transfer (atsc) */
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 2,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_mt352_frontend_attach,
-                       .tuner_attach     = cxusb_lgz201_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x04,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
-                       { &cxusb_table[5], NULL },
-                       { &cxusb_table[6], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = DEVICE_SPECIFIC,
-       .firmware          = "dvb-usb-bluebird-01.fw",
-       .download_firmware = bluebird_patch_dvico_firmware_download,
-       /* use usb alt setting 0 for EP4 transfer (dvb-t),
-          use usb alt setting 7 for EP2 transfer (atsc) */
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_mt352_frontend_attach,
-                       .tuner_attach     = cxusb_dtt7579_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x04,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T USB (TH7579)",
-                       { &cxusb_table[7], NULL },
-                       { &cxusb_table[8], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_dualdig4_frontend_attach,
-                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_bluebird2_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T Dual Digital 4",
-                       { NULL },
-                       { &cxusb_table[13], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-       .identify_state   = bluebird_fx2_identify_state,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_nano2_frontend_attach,
-                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_nano2_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_bluebird2_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T NANO2",
-                       { NULL },
-                       { &cxusb_table[14], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = DEVICE_SPECIFIC,
-       .firmware          = "dvb-usb-bluebird-02.fw",
-       .download_firmware = bluebird_patch_dvico_firmware_download,
-       .identify_state    = bluebird_fx2_identify_state,
-
-       .size_of_priv      = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_streaming_ctrl,
-                       .frontend_attach  = cxusb_nano2_frontend_attach,
-                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_nano2_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
-                       { &cxusb_table[14], NULL },
-                       { &cxusb_table[15], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_aver_streaming_ctrl,
-                       .frontend_attach  = cxusb_aver_lgdt3303_frontend_attach,
-                       .tuner_attach     = cxusb_mxl5003s_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x04,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-       .power_ctrl       = cxusb_aver_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "AVerMedia AVerTVHD Volar (A868R)",
-                       { NULL },
-                       { &cxusb_table[16], NULL },
-               },
-       }
-};
-
-static
-struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .size_of_priv    = sizeof(struct dib0700_adapter_state),
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl  = cxusb_streaming_ctrl,
-                       .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
-                       .tuner_attach    = cxusb_dualdig4_rev2_tuner_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
-                       { NULL },
-                       { &cxusb_table[17], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
-                       .frontend_attach  = cxusb_d680_dmb_frontend_attach,
-                       .tuner_attach     = cxusb_d680_dmb_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_d680_dmb_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_d680_dmb_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
-               .rc_query         = cxusb_d680_dmb_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {
-                       "Conexant DMB-TH Stick",
-                       { NULL },
-                       { &cxusb_table[18], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl         = CYPRESS_FX2,
-
-       .size_of_priv     = sizeof(struct cxusb_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
-                       .frontend_attach  = cxusb_mygica_d689_frontend_attach,
-                       .tuner_attach     = cxusb_mygica_d689_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               },
-       },
-
-       .power_ctrl       = cxusb_d680_dmb_power_ctrl,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_d680_dmb_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
-               .rc_query         = cxusb_d680_dmb_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {
-                       "Mygica D689 DMB-TH",
-                       { NULL },
-                       { &cxusb_table[19], NULL },
-               },
-       }
-};
-
-static struct usb_driver cxusb_driver = {
-       .name           = "dvb_usb_cxusb",
-       .probe          = cxusb_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = cxusb_table,
-};
-
-module_usb_driver(cxusb_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
-MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
-MODULE_VERSION("1.0-alpha");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
deleted file mode 100644 (file)
index 1a51eaf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _DVB_USB_CXUSB_H_
-#define _DVB_USB_CXUSB_H_
-
-#define DVB_USB_LOG_PREFIX "cxusb"
-#include "dvb-usb.h"
-
-/* usb commands - some of it are guesses, don't have a reference yet */
-#define CMD_BLUEBIRD_GPIO_RW 0x05
-
-#define CMD_I2C_WRITE     0x08
-#define CMD_I2C_READ      0x09
-
-#define CMD_GPIO_READ     0x0d
-#define CMD_GPIO_WRITE    0x0e
-#define     GPIO_TUNER         0x02
-
-#define CMD_POWER_OFF     0xdc
-#define CMD_POWER_ON      0xde
-
-#define CMD_STREAMING_ON  0x36
-#define CMD_STREAMING_OFF 0x37
-
-#define CMD_AVER_STREAM_ON  0x18
-#define CMD_AVER_STREAM_OFF 0x19
-
-#define CMD_GET_IR_CODE   0x47
-
-#define CMD_ANALOG        0x50
-#define CMD_DIGITAL       0x51
-
-struct cxusb_state {
-       u8 gpio_write_state[3];
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
deleted file mode 100644 (file)
index 7de125c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
- *
- *     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, version 2.
- *
- *  Copyright (C) 2005-6 DiBcom, SA
- */
-#ifndef _DIB0700_H_
-#define _DIB0700_H_
-
-#define DVB_USB_LOG_PREFIX "dib0700"
-#include "dvb-usb.h"
-
-#include "dib07x0.h"
-
-extern int dvb_usb_dib0700_debug;
-#define deb_info(args...)   dprintk(dvb_usb_dib0700_debug,0x01,args)
-#define deb_fw(args...)     dprintk(dvb_usb_dib0700_debug,0x02,args)
-#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
-#define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
-
-#define REQUEST_SET_USB_XFER_LEN    0x0 /* valid only for firmware version */
-                                       /* higher than 1.21 */
-#define REQUEST_I2C_READ            0x2
-#define REQUEST_I2C_WRITE           0x3
-#define REQUEST_POLL_RC             0x4 /* deprecated in firmware v1.20 */
-#define REQUEST_JUMPRAM             0x8
-#define REQUEST_SET_CLOCK           0xB
-#define REQUEST_SET_GPIO            0xC
-#define REQUEST_ENABLE_VIDEO        0xF
-       // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
-       // 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
-       // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
-#define REQUEST_SET_I2C_PARAM       0x10
-#define REQUEST_SET_RC              0x11
-#define REQUEST_NEW_I2C_READ        0x12
-#define REQUEST_NEW_I2C_WRITE       0x13
-#define REQUEST_GET_VERSION         0x15
-
-struct dib0700_state {
-       u8 channel_state;
-       u16 mt2060_if1[2];
-       u8 rc_toggle;
-       u8 rc_counter;
-       u8 is_dib7000pc;
-       u8 fw_use_new_i2c_api;
-       u8 disable_streaming_master_mode;
-       u32 fw_version;
-       u32 nb_packet_buffer_size;
-       int (*read_status)(struct dvb_frontend *, fe_status_t *);
-       int (*sleep)(struct dvb_frontend* fe);
-       u8 buf[255];
-};
-
-extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
-                              u32 *romversion, u32 *ramversion, u32 *fwtype);
-extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
-extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
-extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
-extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
-extern int dib0700_rc_setup(struct dvb_usb_device *d);
-extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
-extern struct i2c_algorithm dib0700_i2c_algo;
-extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
-                       struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
-extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
-
-extern int dib0700_device_count;
-extern int dvb_usb_dib0700_ir_proto;
-extern struct dvb_usb_device_properties dib0700_devices[];
-extern struct usb_device_id dib0700_usb_id_table[];
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
deleted file mode 100644 (file)
index ef87229..0000000
+++ /dev/null
@@ -1,845 +0,0 @@
-/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
- *
- *     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, version 2.
- *
- *  Copyright (C) 2005-6 DiBcom, SA
- */
-#include "dib0700.h"
-
-/* debug */
-int dvb_usb_dib0700_debug;
-module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
-
-static int nb_packet_buffer_size = 21;
-module_param(nb_packet_buffer_size, int, 0644);
-MODULE_PARM_DESC(nb_packet_buffer_size,
-       "Set the dib0700 driver data buffer size. This parameter "
-       "corresponds to the number of TS packets. The actual size of "
-       "the data buffer corresponds to this parameter "
-       "multiplied by 188 (default: 21)");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-
-int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
-                       u32 *romversion, u32 *ramversion, u32 *fwtype)
-{
-       struct dib0700_state *st = d->priv;
-       int ret;
-
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-                                 REQUEST_GET_VERSION,
-                                 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-                                 st->buf, 16, USB_CTRL_GET_TIMEOUT);
-       if (hwversion != NULL)
-               *hwversion  = (st->buf[0] << 24)  | (st->buf[1] << 16)  |
-                       (st->buf[2] << 8)  | st->buf[3];
-       if (romversion != NULL)
-               *romversion = (st->buf[4] << 24)  | (st->buf[5] << 16)  |
-                       (st->buf[6] << 8)  | st->buf[7];
-       if (ramversion != NULL)
-               *ramversion = (st->buf[8] << 24)  | (st->buf[9] << 16)  |
-                       (st->buf[10] << 8) | st->buf[11];
-       if (fwtype != NULL)
-               *fwtype     = (st->buf[12] << 24) | (st->buf[13] << 16) |
-                       (st->buf[14] << 8) | st->buf[15];
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-
-/* expecting rx buffer: request data[0] data[1] ... data[2] */
-static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
-{
-       int status;
-
-       deb_data(">>> ");
-       debug_dump(tx, txlen, deb_data);
-
-       status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
-               tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
-               USB_CTRL_GET_TIMEOUT);
-
-       if (status != txlen)
-               deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
-
-       return status < 0 ? status : 0;
-}
-
-/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
-int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
-{
-       u16 index, value;
-       int status;
-
-       if (txlen < 2) {
-               err("tx buffer length is smaller than 2. Makes no sense.");
-               return -EINVAL;
-       }
-       if (txlen > 4) {
-               err("tx buffer length is larger than 4. Not supported.");
-               return -EINVAL;
-       }
-
-       deb_data(">>> ");
-       debug_dump(tx,txlen,deb_data);
-
-       value = ((txlen - 2) << 8) | tx[1];
-       index = 0;
-       if (txlen > 2)
-               index |= (tx[2] << 8);
-       if (txlen > 3)
-               index |= tx[3];
-
-       status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
-                       USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
-                       USB_CTRL_GET_TIMEOUT);
-
-       if (status < 0)
-               deb_info("ep 0 read error (status = %d)\n",status);
-
-       deb_data("<<< ");
-       debug_dump(rx, rxlen, deb_data);
-
-       return status; /* length in case of success */
-}
-
-int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
-{
-       struct dib0700_state *st = d->priv;
-       int ret;
-
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       st->buf[0] = REQUEST_SET_GPIO;
-       st->buf[1] = gpio;
-       st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
-
-       ret = dib0700_ctrl_wr(d, st->buf, 3);
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-
-static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
-{
-       struct dib0700_state *st = d->priv;
-       int ret;
-
-       if (st->fw_version >= 0x10201) {
-               if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-                       err("could not acquire lock");
-                       return -EINTR;
-               }
-
-               st->buf[0] = REQUEST_SET_USB_XFER_LEN;
-               st->buf[1] = (nb_ts_packets >> 8) & 0xff;
-               st->buf[2] = nb_ts_packets & 0xff;
-
-               deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
-
-               ret = dib0700_ctrl_wr(d, st->buf, 3);
-               mutex_unlock(&d->usb_mutex);
-       } else {
-               deb_info("this firmware does not allow to change the USB xfer len\n");
-               ret = -EIO;
-       }
-
-       return ret;
-}
-
-/*
- * I2C master xfer function (supported in 1.20 firmware)
- */
-static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
-                               int num)
-{
-       /* The new i2c firmware messages are more reliable and in particular
-          properly support i2c read calls not preceded by a write */
-
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct dib0700_state *st = d->priv;
-       uint8_t bus_mode = 1;  /* 0=eeprom bus, 1=frontend bus */
-       uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
-       uint8_t en_start = 0;
-       uint8_t en_stop = 0;
-       int result, i;
-
-       /* Ensure nobody else hits the i2c bus while we're sending our
-          sequence of messages, (such as the remote control thread) */
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EINTR;
-
-       for (i = 0; i < num; i++) {
-               if (i == 0) {
-                       /* First message in the transaction */
-                       en_start = 1;
-               } else if (!(msg[i].flags & I2C_M_NOSTART)) {
-                       /* Device supports repeated-start */
-                       en_start = 1;
-               } else {
-                       /* Not the first packet and device doesn't support
-                          repeated start */
-                       en_start = 0;
-               }
-               if (i == (num - 1)) {
-                       /* Last message in the transaction */
-                       en_stop = 1;
-               }
-
-               if (msg[i].flags & I2C_M_RD) {
-                       /* Read request */
-                       u16 index, value;
-                       uint8_t i2c_dest;
-
-                       i2c_dest = (msg[i].addr << 1);
-                       value = ((en_start << 7) | (en_stop << 6) |
-                                (msg[i].len & 0x3F)) << 8 | i2c_dest;
-                       /* I2C ctrl + FE bus; */
-                       index = ((gen_mode << 6) & 0xC0) |
-                               ((bus_mode << 4) & 0x30);
-
-                       result = usb_control_msg(d->udev,
-                                                usb_rcvctrlpipe(d->udev, 0),
-                                                REQUEST_NEW_I2C_READ,
-                                                USB_TYPE_VENDOR | USB_DIR_IN,
-                                                value, index, msg[i].buf,
-                                                msg[i].len,
-                                                USB_CTRL_GET_TIMEOUT);
-                       if (result < 0) {
-                               deb_info("i2c read error (status = %d)\n", result);
-                               break;
-                       }
-
-                       deb_data("<<< ");
-                       debug_dump(msg[i].buf, msg[i].len, deb_data);
-
-               } else {
-                       /* Write request */
-                       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-                               err("could not acquire lock");
-                               mutex_unlock(&d->i2c_mutex);
-                               return -EINTR;
-                       }
-                       st->buf[0] = REQUEST_NEW_I2C_WRITE;
-                       st->buf[1] = msg[i].addr << 1;
-                       st->buf[2] = (en_start << 7) | (en_stop << 6) |
-                               (msg[i].len & 0x3F);
-                       /* I2C ctrl + FE bus; */
-                       st->buf[3] = ((gen_mode << 6) & 0xC0) |
-                                ((bus_mode << 4) & 0x30);
-                       /* The Actual i2c payload */
-                       memcpy(&st->buf[4], msg[i].buf, msg[i].len);
-
-                       deb_data(">>> ");
-                       debug_dump(st->buf, msg[i].len + 4, deb_data);
-
-                       result = usb_control_msg(d->udev,
-                                                usb_sndctrlpipe(d->udev, 0),
-                                                REQUEST_NEW_I2C_WRITE,
-                                                USB_TYPE_VENDOR | USB_DIR_OUT,
-                                                0, 0, st->buf, msg[i].len + 4,
-                                                USB_CTRL_GET_TIMEOUT);
-                       mutex_unlock(&d->usb_mutex);
-                       if (result < 0) {
-                               deb_info("i2c write error (status = %d)\n", result);
-                               break;
-                       }
-               }
-       }
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-/*
- * I2C master xfer function (pre-1.20 firmware)
- */
-static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
-                                  struct i2c_msg *msg, int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct dib0700_state *st = d->priv;
-       int i,len;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EINTR;
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               mutex_unlock(&d->i2c_mutex);
-               return -EINTR;
-       }
-
-       for (i = 0; i < num; i++) {
-               /* fill in the address */
-               st->buf[1] = msg[i].addr << 1;
-               /* fill the buffer */
-               memcpy(&st->buf[2], msg[i].buf, msg[i].len);
-
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       st->buf[0] = REQUEST_I2C_READ;
-                       st->buf[1] |= 1;
-
-                       /* special thing in the current firmware: when length is zero the read-failed */
-                       len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
-                                       msg[i+1].buf, msg[i+1].len);
-                       if (len <= 0) {
-                               deb_info("I2C read failed on address 0x%02x\n",
-                                               msg[i].addr);
-                               break;
-                       }
-
-                       msg[i+1].len = len;
-
-                       i++;
-               } else {
-                       st->buf[0] = REQUEST_I2C_WRITE;
-                       if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
-                               break;
-               }
-       }
-       mutex_unlock(&d->usb_mutex);
-       mutex_unlock(&d->i2c_mutex);
-
-       return i;
-}
-
-static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
-                           int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct dib0700_state *st = d->priv;
-
-       if (st->fw_use_new_i2c_api == 1) {
-               /* User running at least fw 1.20 */
-               return dib0700_i2c_xfer_new(adap, msg, num);
-       } else {
-               /* Use legacy calls */
-               return dib0700_i2c_xfer_legacy(adap, msg, num);
-       }
-}
-
-static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-struct i2c_algorithm dib0700_i2c_algo = {
-       .master_xfer   = dib0700_i2c_xfer,
-       .functionality = dib0700_i2c_func,
-};
-
-int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
-                       struct dvb_usb_device_description **desc, int *cold)
-{
-       s16 ret;
-       u8 *b;
-
-       b = kmalloc(16, GFP_KERNEL);
-       if (!b)
-               return  -ENOMEM;
-
-
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-               REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
-
-       deb_info("FW GET_VERSION length: %d\n",ret);
-
-       *cold = ret <= 0;
-       deb_info("cold: %d\n", *cold);
-
-       kfree(b);
-       return 0;
-}
-
-static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
-       u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
-       u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
-{
-       struct dib0700_state *st = d->priv;
-       int ret;
-
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       st->buf[0] = REQUEST_SET_CLOCK;
-       st->buf[1] = (en_pll << 7) | (pll_src << 6) |
-               (pll_range << 5) | (clock_gpio3 << 4);
-       st->buf[2] = (pll_prediv >> 8)  & 0xff; /* MSB */
-       st->buf[3] =  pll_prediv        & 0xff; /* LSB */
-       st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
-       st->buf[5] =  pll_loopdiv       & 0xff; /* LSB */
-       st->buf[6] = (free_div >> 8)    & 0xff; /* MSB */
-       st->buf[7] =  free_div          & 0xff; /* LSB */
-       st->buf[8] = (dsuScaler >> 8)   & 0xff; /* MSB */
-       st->buf[9] =  dsuScaler         & 0xff; /* LSB */
-
-       ret = dib0700_ctrl_wr(d, st->buf, 10);
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
-{
-       struct dib0700_state *st = d->priv;
-       u16 divider;
-       int ret;
-
-       if (scl_kHz == 0)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       st->buf[0] = REQUEST_SET_I2C_PARAM;
-       divider = (u16) (30000 / scl_kHz);
-       st->buf[1] = 0;
-       st->buf[2] = (u8) (divider >> 8);
-       st->buf[3] = (u8) (divider & 0xff);
-       divider = (u16) (72000 / scl_kHz);
-       st->buf[4] = (u8) (divider >> 8);
-       st->buf[5] = (u8) (divider & 0xff);
-       divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
-       st->buf[6] = (u8) (divider >> 8);
-       st->buf[7] = (u8) (divider & 0xff);
-
-       deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
-               (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
-               st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
-
-       ret = dib0700_ctrl_wr(d, st->buf, 8);
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-
-int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
-{
-       switch (clk_MHz) {
-               case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
-               default: return -EINVAL;
-       }
-       return 0;
-}
-
-static int dib0700_jumpram(struct usb_device *udev, u32 address)
-{
-       int ret = 0, actlen;
-       u8 *buf;
-
-       buf = kmalloc(8, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-       buf[0] = REQUEST_JUMPRAM;
-       buf[1] = 0;
-       buf[2] = 0;
-       buf[3] = 0;
-       buf[4] = (address >> 24) & 0xff;
-       buf[5] = (address >> 16) & 0xff;
-       buf[6] = (address >> 8)  & 0xff;
-       buf[7] =  address        & 0xff;
-
-       if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
-               deb_fw("jumpram to 0x%x failed\n",address);
-               goto out;
-       }
-       if (actlen != 8) {
-               deb_fw("jumpram to 0x%x failed\n",address);
-               ret = -EIO;
-               goto out;
-       }
-out:
-       kfree(buf);
-       return ret;
-}
-
-int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
-{
-       struct hexline hx;
-       int pos = 0, ret, act_len, i, adap_num;
-       u8 *buf;
-       u32 fw_version;
-
-       buf = kmalloc(260, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
-               deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
-                               hx.addr, hx.len, hx.chk);
-
-               buf[0] = hx.len;
-               buf[1] = (hx.addr >> 8) & 0xff;
-               buf[2] =  hx.addr       & 0xff;
-               buf[3] = hx.type;
-               memcpy(&buf[4],hx.data,hx.len);
-               buf[4+hx.len] = hx.chk;
-
-               ret = usb_bulk_msg(udev,
-                       usb_sndbulkpipe(udev, 0x01),
-                       buf,
-                       hx.len + 5,
-                       &act_len,
-                       1000);
-
-               if (ret < 0) {
-                       err("firmware download failed at %d with %d",pos,ret);
-                       goto out;
-               }
-       }
-
-       if (ret == 0) {
-               /* start the firmware */
-               if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
-                       info("firmware started successfully.");
-                       msleep(500);
-               }
-       } else
-               ret = -EIO;
-
-       /* the number of ts packet has to be at least 1 */
-       if (nb_packet_buffer_size < 1)
-               nb_packet_buffer_size = 1;
-
-       /* get the fimware version */
-       usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                                 REQUEST_GET_VERSION,
-                                 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-                                 buf, 16, USB_CTRL_GET_TIMEOUT);
-       fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
-
-       /* set the buffer size - DVB-USB is allocating URB buffers
-        * only after the firwmare download was successful */
-       for (i = 0; i < dib0700_device_count; i++) {
-               for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
-                               adap_num++) {
-                       if (fw_version >= 0x10201) {
-                               dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
-                       } else {
-                               /* for fw version older than 1.20.1,
-                                * the buffersize has to be n times 512 */
-                               dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
-                               if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512)
-                                       dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512;
-                       }
-               }
-       }
-out:
-       kfree(buf);
-       return ret;
-}
-
-int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct dib0700_state *st = adap->dev->priv;
-       int ret;
-
-       if ((onoff != 0) && (st->fw_version >= 0x10201)) {
-               /* for firmware later than 1.20.1,
-                * the USB xfer length can be set  */
-               ret = dib0700_set_usb_xfer_len(adap->dev,
-                       st->nb_packet_buffer_size);
-               if (ret < 0) {
-                       deb_info("can not set the USB xfer len\n");
-                       return ret;
-               }
-       }
-
-       if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       st->buf[0] = REQUEST_ENABLE_VIDEO;
-       /* this bit gives a kind of command,
-        * rather than enabling something or not */
-       st->buf[1] = (onoff << 4) | 0x00;
-
-       if (st->disable_streaming_master_mode == 1)
-               st->buf[2] = 0x00;
-       else
-               st->buf[2] = 0x01 << 4; /* Master mode */
-
-       st->buf[3] = 0x00;
-
-       deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
-
-       st->channel_state &= ~0x3;
-       if ((adap->fe_adap[0].stream.props.endpoint != 2)
-                       && (adap->fe_adap[0].stream.props.endpoint != 3)) {
-               deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
-               if (onoff)
-                       st->channel_state |=    1 << (adap->id);
-               else
-                       st->channel_state |=    1 << ~(adap->id);
-       } else {
-               if (onoff)
-                       st->channel_state |=    1 << (adap->fe_adap[0].stream.props.endpoint-2);
-               else
-                       st->channel_state |=    1 << (3-adap->fe_adap[0].stream.props.endpoint);
-       }
-
-       st->buf[2] |= st->channel_state;
-
-       deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
-
-       ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
-       mutex_unlock(&adap->dev->usb_mutex);
-
-       return ret;
-}
-
-int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
-{
-       struct dvb_usb_device *d = rc->priv;
-       struct dib0700_state *st = d->priv;
-       int new_proto, ret;
-
-       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
-               err("could not acquire lock");
-               return -EINTR;
-       }
-
-       st->buf[0] = REQUEST_SET_RC;
-       st->buf[1] = 0;
-       st->buf[2] = 0;
-
-       /* Set the IR mode */
-       if (rc_type == RC_TYPE_RC5)
-               new_proto = 1;
-       else if (rc_type == RC_TYPE_NEC)
-               new_proto = 0;
-       else if (rc_type == RC_TYPE_RC6) {
-               if (st->fw_version < 0x10200) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-
-               new_proto = 2;
-       } else {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       st->buf[1] = new_proto;
-
-       ret = dib0700_ctrl_wr(d, st->buf, 3);
-       if (ret < 0) {
-               err("ir protocol setup failed");
-               goto out;
-       }
-
-       d->props.rc.core.protocol = rc_type;
-
-out:
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-
-/* Number of keypresses to ignore before start repeating */
-#define RC_REPEAT_DELAY_V1_20 10
-
-/* This is the structure of the RC response packet starting in firmware 1.20 */
-struct dib0700_rc_response {
-       u8 report_id;
-       u8 data_state;
-       union {
-               u16 system16;
-               struct {
-                       u8 not_system;
-                       u8 system;
-               };
-       };
-       u8 data;
-       u8 not_data;
-};
-#define RC_MSG_SIZE_V1_20 6
-
-static void dib0700_rc_urb_completion(struct urb *purb)
-{
-       struct dvb_usb_device *d = purb->context;
-       struct dib0700_rc_response *poll_reply;
-       u32 uninitialized_var(keycode);
-       u8 toggle;
-
-       deb_info("%s()\n", __func__);
-       if (d->rc_dev == NULL) {
-               /* This will occur if disable_rc_polling=1 */
-               kfree(purb->transfer_buffer);
-               usb_free_urb(purb);
-               return;
-       }
-
-       poll_reply = purb->transfer_buffer;
-
-       if (purb->status < 0) {
-               deb_info("discontinuing polling\n");
-               kfree(purb->transfer_buffer);
-               usb_free_urb(purb);
-               return;
-       }
-
-       if (purb->actual_length != RC_MSG_SIZE_V1_20) {
-               deb_info("malformed rc msg size=%d\n", purb->actual_length);
-               goto resubmit;
-       }
-
-       deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
-                poll_reply->report_id, poll_reply->data_state,
-                poll_reply->system, poll_reply->not_system,
-                poll_reply->data, poll_reply->not_data,
-                purb->actual_length);
-
-       switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
-               toggle = 0;
-
-               /* NEC protocol sends repeat code as 0 0 0 FF */
-               if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
-                   && (poll_reply->not_data == 0xff)) {
-                       poll_reply->data_state = 2;
-                       break;
-               }
-
-               if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
-                       deb_data("NEC extended protocol\n");
-                       /* NEC extended code - 24 bits */
-                       keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
-               } else {
-                       deb_data("NEC normal protocol\n");
-                       /* normal NEC code - 16 bits */
-                       keycode = poll_reply->system << 8 | poll_reply->data;
-               }
-
-               break;
-       default:
-               deb_data("RC5 protocol\n");
-               /* RC5 Protocol */
-               toggle = poll_reply->report_id;
-               keycode = poll_reply->system << 8 | poll_reply->data;
-
-               break;
-       }
-
-       if ((poll_reply->data + poll_reply->not_data) != 0xff) {
-               /* Key failed integrity check */
-               err("key failed integrity check: %04x %02x %02x",
-                   poll_reply->system,
-                   poll_reply->data, poll_reply->not_data);
-               goto resubmit;
-       }
-
-       rc_keydown(d->rc_dev, keycode, toggle);
-
-resubmit:
-       /* Clean the buffer before we requeue */
-       memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
-
-       /* Requeue URB */
-       usb_submit_urb(purb, GFP_ATOMIC);
-}
-
-int dib0700_rc_setup(struct dvb_usb_device *d)
-{
-       struct dib0700_state *st = d->priv;
-       struct urb *purb;
-       int ret;
-
-       /* Poll-based. Don't initialize bulk mode */
-       if (st->fw_version < 0x10200)
-               return 0;
-
-       /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
-       purb = usb_alloc_urb(0, GFP_KERNEL);
-       if (purb == NULL) {
-               err("rc usb alloc urb failed");
-               return -ENOMEM;
-       }
-
-       purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
-       if (purb->transfer_buffer == NULL) {
-               err("rc kzalloc failed");
-               usb_free_urb(purb);
-               return -ENOMEM;
-       }
-
-       purb->status = -EINPROGRESS;
-       usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
-                         purb->transfer_buffer, RC_MSG_SIZE_V1_20,
-                         dib0700_rc_urb_completion, d);
-
-       ret = usb_submit_urb(purb, GFP_ATOMIC);
-       if (ret) {
-               err("rc submit urb failed");
-               kfree(purb->transfer_buffer);
-               usb_free_urb(purb);
-       }
-
-       return ret;
-}
-
-static int dib0700_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       int i;
-       struct dvb_usb_device *dev;
-
-       for (i = 0; i < dib0700_device_count; i++)
-               if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
-                   &dev, adapter_nr) == 0) {
-                       struct dib0700_state *st = dev->priv;
-                       u32 hwversion, romversion, fw_version, fwtype;
-
-                       dib0700_get_version(dev, &hwversion, &romversion,
-                               &fw_version, &fwtype);
-
-                       deb_info("Firmware version: %x, %d, 0x%x, %d\n",
-                               hwversion, romversion, fw_version, fwtype);
-
-                       st->fw_version = fw_version;
-                       st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
-
-                       /* Disable polling mode on newer firmwares */
-                       if (st->fw_version >= 0x10200)
-                               dev->props.rc.core.bulk_mode = true;
-                       else
-                               dev->props.rc.core.bulk_mode = false;
-
-                       dib0700_rc_setup(dev);
-
-                       return 0;
-               }
-
-       return -ENODEV;
-}
-
-static struct usb_driver dib0700_driver = {
-       .name       = "dvb_usb_dib0700",
-       .probe      = dib0700_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table   = dib0700_usb_id_table,
-};
-
-module_usb_driver(dib0700_driver);
-
-MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
deleted file mode 100644 (file)
index 510001d..0000000
+++ /dev/null
@@ -1,4813 +0,0 @@
-/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
- *
- *     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, version 2.
- *
- *  Copyright (C) 2005-9 DiBcom, SA et al
- */
-#include "dib0700.h"
-
-#include "dib3000mc.h"
-#include "dib7000m.h"
-#include "dib7000p.h"
-#include "dib8000.h"
-#include "dib9000.h"
-#include "mt2060.h"
-#include "mt2266.h"
-#include "tuner-xc2028.h"
-#include "xc5000.h"
-#include "xc4000.h"
-#include "s5h1411.h"
-#include "dib0070.h"
-#include "dib0090.h"
-#include "lgdt3305.h"
-#include "mxl5007t.h"
-
-static int force_lna_activation;
-module_param(force_lna_activation, int, 0644);
-MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
-               "if applicable for the device (default: 0=automatic/off).");
-
-struct dib0700_adapter_state {
-       int (*set_param_save) (struct dvb_frontend *);
-       const struct firmware *frontend_firmware;
-};
-
-/* Hauppauge Nova-T 500 (aka Bristol)
- *  has a LNA on GPIO0 which is enabled by setting 1 */
-static struct mt2060_config bristol_mt2060_config[2] = {
-       {
-               .i2c_address = 0x60,
-               .clock_out   = 3,
-       }, {
-               .i2c_address = 0x61,
-       }
-};
-
-
-static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
-       .band_caps = BAND_VHF | BAND_UHF,
-       .setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
-
-       .agc1_max = 42598,
-       .agc1_min = 17694,
-       .agc2_max = 45875,
-       .agc2_min = 0,
-
-       .agc1_pt1 = 0,
-       .agc1_pt2 = 59,
-
-       .agc1_slope1 = 0,
-       .agc1_slope2 = 69,
-
-       .agc2_pt1 = 0,
-       .agc2_pt2 = 59,
-
-       .agc2_slope1 = 111,
-       .agc2_slope2 = 28,
-};
-
-static struct dib3000mc_config bristol_dib3000mc_config[2] = {
-       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
-               .max_time     = 0x196,
-               .ln_adc_level = 0x1cc7,
-               .output_mpeg2_in_188_bytes = 1,
-       },
-       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
-               .max_time     = 0x196,
-               .ln_adc_level = 0x1cc7,
-               .output_mpeg2_in_188_bytes = 1,
-       }
-};
-
-static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-       if (adap->id == 0) {
-               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
-
-               if (force_lna_activation)
-                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-               else
-                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
-
-               if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
-                       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
-                       return -ENODEV;
-               }
-       }
-       st->mt2060_if1[adap->id] = 1220;
-       return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
-               (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
-}
-
-static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = 0x50, .flags = 0,        .buf = &adrs, .len = 1 },
-               { .addr = 0x50, .flags = I2C_M_RD, .buf = pval,  .len = 1 },
-       };
-       if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
-       return 0;
-}
-
-static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
-       struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
-       s8 a;
-       int if1=1220;
-       if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
-               adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
-               if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
-       }
-       return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c,
-                         &bristol_mt2060_config[adap->id], if1) == NULL ?
-                         -ENODEV : 0;
-}
-
-/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
-
-/* MT226x */
-static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
-       {
-               BAND_UHF,
-
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
-               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
-           | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-               1130,
-               21,
-
-               0,
-               118,
-
-               0,
-               3530,
-               1,
-               0,
-
-               65535,
-               33770,
-               65535,
-               23592,
-
-               0,
-               62,
-               255,
-               64,
-               64,
-               132,
-               192,
-               80,
-               80,
-
-               17,
-               27,
-               23,
-               51,
-
-               1,
-       }, {
-               BAND_VHF | BAND_LBAND,
-
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
-               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
-           | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
-
-               2372,
-               21,
-
-               0,
-               118,
-
-               0,
-               3530,
-               1,
-               0,
-
-               65535,
-               0,
-               65535,
-               23592,
-
-               0,
-               128,
-               128,
-               128,
-               0,
-               128,
-               253,
-               81,
-               0,
-
-               17,
-               27,
-               23,
-               51,
-
-               1,
-       }
-};
-
-static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
-       60000, 30000,
-       1, 8, 3, 1, 0,
-       0, 0, 1, 1, 2,
-       (3 << 14) | (1 << 12) | (524 << 0),
-       0,
-       20452225,
-};
-
-static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
-       {       .output_mpeg2_in_188_bytes = 1,
-               .hostbus_diversity = 1,
-               .tuner_is_baseband = 1,
-
-               .agc_config_count = 2,
-               .agc = stk7700d_7000p_mt2266_agc_config,
-               .bw  = &stk7700d_mt2266_pll_config,
-
-               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-       },
-       {       .output_mpeg2_in_188_bytes = 1,
-               .hostbus_diversity = 1,
-               .tuner_is_baseband = 1,
-
-               .agc_config_count = 2,
-               .agc = stk7700d_7000p_mt2266_agc_config,
-               .bw  = &stk7700d_mt2266_pll_config,
-
-               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-       }
-};
-
-static struct mt2266_config stk7700d_mt2266_config[2] = {
-       {       .i2c_address = 0x60
-       },
-       {       .i2c_address = 0x60
-       }
-};
-
-static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (adap->id == 0) {
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-               msleep(10);
-               if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                                            stk7700d_dib7000p_mt2266_config)
-                   != 0) {
-                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
-                       return -ENODEV;
-               }
-       }
-
-       adap->fe_adap[0].fe =
-               dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
-                          0x80 + (adap->id << 1),
-                          &stk7700d_dib7000p_mt2266_config[adap->id]);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (adap->id == 0) {
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-               if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
-                                            stk7700d_dib7000p_mt2266_config)
-                   != 0) {
-                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
-                       return -ENODEV;
-               }
-       }
-
-       adap->fe_adap[0].fe =
-               dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
-                          0x80 + (adap->id << 1),
-                          &stk7700d_dib7000p_mt2266_config[adap->id]);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *tun_i2c;
-       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-       return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
-               &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
-}
-
-/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
-static struct dibx000_agc_config xc3028_agc_config = {
-       BAND_VHF | BAND_UHF,       /* band_caps */
-
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
-        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
-       (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
-
-       712,    /* inv_gain */
-       21,     /* time_stabiliz */
-
-       0,      /* alpha_level */
-       118,    /* thlock */
-
-       0,      /* wbd_inv */
-       2867,   /* wbd_ref */
-       0,      /* wbd_sel */
-       2,      /* wbd_alpha */
-
-       0,      /* agc1_max */
-       0,      /* agc1_min */
-       39718,  /* agc2_max */
-       9930,   /* agc2_min */
-       0,      /* agc1_pt1 */
-       0,      /* agc1_pt2 */
-       0,      /* agc1_pt3 */
-       0,      /* agc1_slope1 */
-       0,      /* agc1_slope2 */
-       0,      /* agc2_pt1 */
-       128,    /* agc2_pt2 */
-       29,     /* agc2_slope1 */
-       29,     /* agc2_slope2 */
-
-       17,     /* alpha_mant */
-       27,     /* alpha_exp */
-       23,     /* beta_mant */
-       51,     /* beta_exp */
-
-       1,      /* perform_agc_softsplit */
-};
-
-/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
-static struct dibx000_bandwidth_config xc3028_bw_config = {
-       60000, 30000, /* internal, sampling */
-       1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
-       0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
-                         modulo */
-       (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
-       (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
-       20452225, /* timf */
-       30000000, /* xtal_hz */
-};
-
-static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
-       .output_mpeg2_in_188_bytes = 1,
-       .tuner_is_baseband = 1,
-
-       .agc_config_count = 1,
-       .agc = &xc3028_agc_config,
-       .bw  = &xc3028_bw_config,
-
-       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-};
-
-static int stk7700ph_xc3028_callback(void *ptr, int component,
-                                    int command, int arg)
-{
-       struct dvb_usb_adapter *adap = ptr;
-
-       switch (command) {
-       case XC2028_TUNER_RESET:
-               /* Send the tuner in then out of reset */
-               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
-               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-               break;
-       case XC2028_RESET_CLK:
-               break;
-       default:
-               err("%s: unknown command %d, arg %d\n", __func__,
-                       command, arg);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
-       .fname = XC2028_DEFAULT_FIRMWARE,
-       .max_len = 64,
-       .demod = XC3028_FE_DIBCOM52,
-};
-
-static struct xc2028_config stk7700ph_xc3028_config = {
-       .i2c_addr = 0x61,
-       .ctrl = &stk7700ph_xc3028_ctrl,
-};
-
-static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
-
-       if (desc->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
-           desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       else
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-       msleep(10);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                                    &stk7700ph_dib7700_xc3028_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                   __func__);
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
-               &stk7700ph_dib7700_xc3028_config);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *tun_i2c;
-
-       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
-               DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       stk7700ph_xc3028_config.i2c_adap = tun_i2c;
-
-       /* FIXME: generalize & move to common area */
-       adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;
-
-       return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
-               == NULL ? -ENODEV : 0;
-}
-
-#define DEFAULT_RC_INTERVAL 50
-
-static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
-
-/* Number of keypresses to ignore before start repeating */
-#define RC_REPEAT_DELAY 6
-
-/*
- * This function is used only when firmware is < 1.20 version. Newer
- * firmwares use bulk mode, with functions implemented at dib0700_core,
- * at dib0700_rc_urb_completion()
- */
-static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
-{
-       u8 key[4];
-       u32 keycode;
-       u8 toggle;
-       int i;
-       struct dib0700_state *st = d->priv;
-
-       if (st->fw_version >= 0x10200) {
-               /* For 1.20 firmware , We need to keep the RC polling
-                  callback so we can reuse the input device setup in
-                  dvb-usb-remote.c.  However, the actual work is being done
-                  in the bulk URB completion handler. */
-               return 0;
-       }
-
-       i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
-       if (i <= 0) {
-               err("RC Query Failed");
-               return -1;
-       }
-
-       /* losing half of KEY_0 events from Philipps rc5 remotes.. */
-       if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
-               return 0;
-
-       /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */
-
-       dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
-
-       d->last_event = 0;
-       switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
-               /* NEC protocol sends repeat code as 0 0 0 FF */
-               if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
-                   (key[3] == 0xff))
-                       keycode = d->last_event;
-               else {
-                       keycode = key[3-2] << 8 | key[3-3];
-                       d->last_event = keycode;
-               }
-
-               rc_keydown(d->rc_dev, keycode, 0);
-               break;
-       default:
-               /* RC-5 protocol changes toggle bit on new keypress */
-               keycode = key[3-2] << 8 | key[3-3];
-               toggle = key[3-1];
-               rc_keydown(d->rc_dev, keycode, toggle);
-
-               break;
-       }
-       return 0;
-}
-
-/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
-static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
-       BAND_UHF | BAND_VHF,
-
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
-        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
-       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
-
-       712,
-       41,
-
-       0,
-       118,
-
-       0,
-       4095,
-       0,
-       0,
-
-       42598,
-       17694,
-       45875,
-       2621,
-       0,
-       76,
-       139,
-       52,
-       59,
-       107,
-       172,
-       57,
-       70,
-
-       21,
-       25,
-       28,
-       48,
-
-       1,
-       {  0,
-          107,
-          51800,
-          24700
-       },
-};
-
-static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
-       BAND_UHF | BAND_VHF,
-
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
-        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
-       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
-
-       712,
-       41,
-
-       0,
-       118,
-
-       0,
-       4095,
-       0,
-       0,
-
-       42598,
-       16384,
-       42598,
-           0,
-
-         0,
-       137,
-       255,
-
-         0,
-       255,
-
-       0,
-       0,
-
-        0,
-       41,
-
-       15,
-       25,
-
-       28,
-       48,
-
-       0,
-};
-
-static struct dibx000_bandwidth_config stk7700p_pll_config = {
-       60000, 30000,
-       1, 8, 3, 1, 0,
-       0, 0, 1, 1, 0,
-       (3 << 14) | (1 << 12) | (524 << 0),
-       60258167,
-       20452225,
-       30000000,
-};
-
-static struct dib7000m_config stk7700p_dib7000m_config = {
-       .dvbt_mode = 1,
-       .output_mpeg2_in_188_bytes = 1,
-       .quartz_direct = 1,
-
-       .agc_config_count = 1,
-       .agc = &stk7700p_7000m_mt2060_agc_config,
-       .bw  = &stk7700p_pll_config,
-
-       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
-};
-
-static struct dib7000p_config stk7700p_dib7000p_config = {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 1,
-       .agc = &stk7700p_7000p_mt2060_agc_config,
-       .bw  = &stk7700p_pll_config,
-
-       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
-};
-
-static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-       /* unless there is no real power management in DVB - we leave the device on GPIO6 */
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);
-
-       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
-
-       dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);
-
-       st->mt2060_if1[0] = 1220;
-
-       if (dib7000pc_detection(&adap->dev->i2c_adap)) {
-               adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
-               st->is_dib7000pc = 1;
-       } else
-               adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static struct mt2060_config stk7700p_mt2060_config = {
-       0x60
-};
-
-static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
-       struct dib0700_state *st = adap->dev->priv;
-       struct i2c_adapter *tun_i2c;
-       s8 a;
-       int if1=1220;
-       if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
-               adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
-               if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
-       }
-       if (st->is_dib7000pc)
-               tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-       else
-               tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
-               if1) == NULL ? -ENODEV : 0;
-}
-
-/* DIB7070 generic */
-static struct dibx000_agc_config dib7070_agc_config = {
-       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
-        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
-       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-       600,
-       10,
-
-       0,
-       118,
-
-       0,
-       3530,
-       1,
-       5,
-
-       65535,
-               0,
-
-       65535,
-       0,
-
-       0,
-       40,
-       183,
-       206,
-       255,
-       72,
-       152,
-       88,
-       90,
-
-       17,
-       27,
-       23,
-       51,
-
-       0,
-};
-
-static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("reset: %d", onoff);
-       return dib7000p_set_gpio(fe, 8, 0, !onoff);
-}
-
-static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("sleep: %d", onoff);
-       return dib7000p_set_gpio(fe, 9, 0, onoff);
-}
-
-static struct dib0070_config dib7070p_dib0070_config[2] = {
-       {
-               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib7070_tuner_reset,
-               .sleep = dib7070_tuner_sleep,
-               .clock_khz = 12000,
-               .clock_pad_drive = 4,
-               .charge_pump = 2,
-       }, {
-               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib7070_tuner_reset,
-               .sleep = dib7070_tuner_sleep,
-               .clock_khz = 12000,
-               .charge_pump = 2,
-       }
-};
-
-static struct dib0070_config dib7770p_dib0070_config = {
-        .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-        .reset = dib7070_tuner_reset,
-        .sleep = dib7070_tuner_sleep,
-        .clock_khz = 12000,
-        .clock_pad_drive = 0,
-        .flip_chip = 1,
-        .charge_pump = 2,
-};
-
-static int dib7070_set_param_override(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-
-       u16 offset;
-       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
-       switch (band) {
-               case BAND_VHF: offset = 950; break;
-               case BAND_UHF:
-               default: offset = 550; break;
-       }
-       deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
-       dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
-       return state->set_param_save(fe);
-}
-
-static int dib7770_set_param_override(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-
-        u16 offset;
-        u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
-        switch (band) {
-        case BAND_VHF:
-                 dib7000p_set_gpio(fe, 0, 0, 1);
-                 offset = 850;
-                 break;
-        case BAND_UHF:
-        default:
-                 dib7000p_set_gpio(fe, 0, 0, 0);
-                 offset = 250;
-                 break;
-        }
-        deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
-        dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
-        return state->set_param_save(fe);
-}
-
-static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
-{
-        struct dib0700_adapter_state *st = adap->priv;
-        struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
-                        DIBX000_I2C_INTERFACE_TUNER, 1);
-
-        if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
-                       &dib7770p_dib0070_config) == NULL)
-                return -ENODEV;
-
-        st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-        adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
-        return 0;
-}
-
-static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       if (adap->id == 0) {
-               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
-                       return -ENODEV;
-       } else {
-               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
-                       return -ENODEV;
-       }
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
-       return 0;
-}
-
-static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
-               u16 pid, int onoff)
-{
-       struct dib0700_state *st = adapter->dev->priv;
-       if (st->is_dib7000pc)
-               return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
-       return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
-}
-
-static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
-{
-       struct dib0700_state *st = adapter->dev->priv;
-       if (st->is_dib7000pc)
-               return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
-       return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
-}
-
-static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
-{
-       return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
-}
-
-static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
-{
-       return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
-}
-
-static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
-       60000, 15000,
-       1, 20, 3, 1, 0,
-       0, 0, 1, 1, 2,
-       (3 << 14) | (1 << 12) | (524 << 0),
-       (0 << 25) | 0,
-       20452225,
-       12000000,
-};
-
-static struct dib7000p_config dib7070p_dib7000p_config = {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 1,
-       .agc = &dib7070_agc_config,
-       .bw  = &dib7070_bw_config_12_mhz,
-       .tuner_is_baseband = 1,
-       .spur_protect = 1,
-
-       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .hostbus_diversity = 1,
-};
-
-/* STK7070P */
-static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
-       if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
-           p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       else
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                                    &dib7070p_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                   __func__);
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
-               &dib7070p_dib7000p_config);
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-/* STK7770P */
-static struct dib7000p_config dib7770p_dib7000p_config = {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 1,
-       .agc = &dib7070_agc_config,
-       .bw  = &dib7070_bw_config_12_mhz,
-       .tuner_is_baseband = 1,
-       .spur_protect = 1,
-
-       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .hostbus_diversity = 1,
-       .enable_current_mirror = 1,
-       .disable_sample_and_hold = 0,
-};
-
-static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
-       if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
-           p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       else
-               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                                    &dib7770p_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                   __func__);
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
-               &dib7770p_dib7000p_config);
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-/* DIB807x generic */
-static struct dibx000_agc_config dib807x_agc_config[2] = {
-       {
-               BAND_VHF,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
-                * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
-                * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
-                * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
-                * P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
-                       (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
-                       (0 << 0), /* setup*/
-
-               600, /* inv_gain*/
-               10,  /* time_stabiliz*/
-
-               0,  /* alpha_level*/
-               118,  /* thlock*/
-
-               0,     /* wbd_inv*/
-               3530,  /* wbd_ref*/
-               1,     /* wbd_sel*/
-               5,     /* wbd_alpha*/
-
-               65535,  /* agc1_max*/
-               0,  /* agc1_min*/
-
-               65535,  /* agc2_max*/
-               0,      /* agc2_min*/
-
-               0,      /* agc1_pt1*/
-               40,     /* agc1_pt2*/
-               183,    /* agc1_pt3*/
-               206,    /* agc1_slope1*/
-               255,    /* agc1_slope2*/
-               72,     /* agc2_pt1*/
-               152,    /* agc2_pt2*/
-               88,     /* agc2_slope1*/
-               90,     /* agc2_slope2*/
-
-               17,  /* alpha_mant*/
-               27,  /* alpha_exp*/
-               23,  /* beta_mant*/
-               51,  /* beta_exp*/
-
-               0,  /* perform_agc_softsplit*/
-       }, {
-               BAND_UHF,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
-                * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
-                * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-                * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
-                * P_agc_write=0 */
-               (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
-                       (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
-                       (0 << 0), /* setup */
-
-               600, /* inv_gain*/
-               10,  /* time_stabiliz*/
-
-               0,  /* alpha_level*/
-               118,  /* thlock*/
-
-               0,     /* wbd_inv*/
-               3530,  /* wbd_ref*/
-               1,     /* wbd_sel*/
-               5,     /* wbd_alpha*/
-
-               65535,  /* agc1_max*/
-               0,  /* agc1_min*/
-
-               65535,  /* agc2_max*/
-               0,      /* agc2_min*/
-
-               0,      /* agc1_pt1*/
-               40,     /* agc1_pt2*/
-               183,    /* agc1_pt3*/
-               206,    /* agc1_slope1*/
-               255,    /* agc1_slope2*/
-               72,     /* agc2_pt1*/
-               152,    /* agc2_pt2*/
-               88,     /* agc2_slope1*/
-               90,     /* agc2_slope2*/
-
-               17,  /* alpha_mant*/
-               27,  /* alpha_exp*/
-               23,  /* beta_mant*/
-               51,  /* beta_exp*/
-
-               0,  /* perform_agc_softsplit*/
-       }
-};
-
-static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
-       60000, 15000, /* internal, sampling*/
-       1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
-       0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
-                         ADClkSrc, modulo */
-       (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
-       (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
-       18179755, /* timf*/
-       12000000, /* xtal_hz*/
-};
-
-static struct dib8000_config dib807x_dib8000_config[2] = {
-       {
-               .output_mpeg2_in_188_bytes = 1,
-
-               .agc_config_count = 2,
-               .agc = dib807x_agc_config,
-               .pll = &dib807x_bw_config_12_mhz,
-               .tuner_is_baseband = 1,
-
-               .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
-
-               .hostbus_diversity = 1,
-               .div_cfg = 1,
-               .agc_control = &dib0070_ctrl_agc_filter,
-               .output_mode = OUTMODE_MPEG2_FIFO,
-               .drives = 0x2d98,
-       }, {
-               .output_mpeg2_in_188_bytes = 1,
-
-               .agc_config_count = 2,
-               .agc = dib807x_agc_config,
-               .pll = &dib807x_bw_config_12_mhz,
-               .tuner_is_baseband = 1,
-
-               .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
-
-               .hostbus_diversity = 1,
-               .agc_control = &dib0070_ctrl_agc_filter,
-               .output_mode = OUTMODE_MPEG2_FIFO,
-               .drives = 0x2d98,
-       }
-};
-
-static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
-{
-       return dib8000_set_gpio(fe, 5, 0, !onoff);
-}
-
-static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       return dib8000_set_gpio(fe, 0, 0, onoff);
-}
-
-static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
-    { 240,      7},
-    { 0xffff,   6},
-};
-
-static struct dib0070_config dib807x_dib0070_config[2] = {
-       {
-               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib80xx_tuner_reset,
-               .sleep = dib80xx_tuner_sleep,
-               .clock_khz = 12000,
-               .clock_pad_drive = 4,
-               .vga_filter = 1,
-               .force_crystal_mode = 1,
-               .enable_third_order_filter = 1,
-               .charge_pump = 0,
-               .wbd_gain = dib8070_wbd_gain_cfg,
-               .osc_buffer_state = 0,
-               .freq_offset_khz_uhf = -100,
-               .freq_offset_khz_vhf = -100,
-       }, {
-               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-               .reset = dib80xx_tuner_reset,
-               .sleep = dib80xx_tuner_sleep,
-               .clock_khz = 12000,
-               .clock_pad_drive = 2,
-               .vga_filter = 1,
-               .force_crystal_mode = 1,
-               .enable_third_order_filter = 1,
-               .charge_pump = 0,
-               .wbd_gain = dib8070_wbd_gain_cfg,
-               .osc_buffer_state = 0,
-               .freq_offset_khz_uhf = -25,
-               .freq_offset_khz_vhf = -25,
-       }
-};
-
-static int dib807x_set_param_override(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-
-       u16 offset = dib0070_wbd_offset(fe);
-       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
-       switch (band) {
-       case BAND_VHF:
-               offset += 750;
-               break;
-       case BAND_UHF:  /* fall-thru wanted */
-       default:
-               offset += 250; break;
-       }
-       deb_info("WBD for DiB8000: %d\n", offset);
-       dib8000_set_wbd_ref(fe, offset);
-
-       return state->set_param_save(fe);
-}
-
-static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
-                       DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       if (adap->id == 0) {
-               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
-                               &dib807x_dib0070_config[0]) == NULL)
-                       return -ENODEV;
-       } else {
-               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
-                               &dib807x_dib0070_config[1]) == NULL)
-                       return -ENODEV;
-       }
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override;
-       return 0;
-}
-
-static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
-       u16 pid, int onoff)
-{
-       return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
-}
-
-static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
-               int onoff)
-{
-       return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
-}
-
-/* STK807x */
-static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-                               0x80, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
-                             &dib807x_dib8000_config[0]);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-/* STK807xPVR */
-static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       msleep(30);
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(500);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       /* initialize IC 0 */
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
-                             &dib807x_dib8000_config[0]);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
-{
-       /* initialize IC 1 */
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
-                             &dib807x_dib8000_config[1]);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-/* STK8096GP */
-static struct dibx000_agc_config dib8090_agc_config[2] = {
-       {
-       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
-        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
-       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-       787,
-       10,
-
-       0,
-       118,
-
-       0,
-       3530,
-       1,
-       5,
-
-       65535,
-       0,
-
-       65535,
-       0,
-
-       0,
-       32,
-       114,
-       143,
-       144,
-       114,
-       227,
-       116,
-       117,
-
-       28,
-       26,
-       31,
-       51,
-
-       0,
-       },
-       {
-       BAND_CBAND,
-       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
-        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
-       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-       787,
-       10,
-
-       0,
-       118,
-
-       0,
-       3530,
-       1,
-       5,
-
-       0,
-       0,
-
-       65535,
-       0,
-
-       0,
-       32,
-       114,
-       143,
-       144,
-       114,
-       227,
-       116,
-       117,
-
-       28,
-       26,
-       31,
-       51,
-
-       0,
-       }
-};
-
-static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
-       54000, 13500,
-       1, 18, 3, 1, 0,
-       0, 0, 1, 1, 2,
-       (3 << 14) | (1 << 12) | (599 << 0),
-       (0 << 25) | 0,
-       20199727,
-       12000000,
-};
-
-static int dib8090_get_adc_power(struct dvb_frontend *fe)
-{
-       return dib8000_get_adc_power(fe, 1);
-}
-
-static struct dib8000_config dib809x_dib8000_config[2] = {
-       {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 2,
-       .agc = dib8090_agc_config,
-       .agc_control = dib0090_dcc_freq,
-       .pll = &dib8090_pll_config_12mhz,
-       .tuner_is_baseband = 1,
-
-       .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
-
-       .hostbus_diversity = 1,
-       .div_cfg = 0x31,
-       .output_mode = OUTMODE_MPEG2_FIFO,
-       .drives = 0x2d98,
-       .diversity_delay = 48,
-       .refclksel = 3,
-       }, {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 2,
-       .agc = dib8090_agc_config,
-       .agc_control = dib0090_dcc_freq,
-       .pll = &dib8090_pll_config_12mhz,
-       .tuner_is_baseband = 1,
-
-       .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
-
-       .hostbus_diversity = 1,
-       .div_cfg = 0x31,
-       .output_mode = OUTMODE_DIVERSITY,
-       .drives = 0x2d08,
-       .diversity_delay = 1,
-       .refclksel = 3,
-       }
-};
-
-static struct dib0090_wbd_slope dib8090_wbd_table[] = {
-       /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
-       { 120,     0, 500,  0,   500, 4 }, /* CBAND */
-       { 170,     0, 450,  0,   450, 4 }, /* CBAND */
-       { 380,    48, 373, 28,   259, 6 }, /* VHF */
-       { 860,    34, 700, 36,   616, 6 }, /* high UHF */
-       { 0xFFFF, 34, 700, 36,   616, 6 }, /* default */
-};
-
-static struct dib0090_config dib809x_dib0090_config = {
-       .io.pll_bypass = 1,
-       .io.pll_range = 1,
-       .io.pll_prediv = 1,
-       .io.pll_loopdiv = 20,
-       .io.adc_clock_ratio = 8,
-       .io.pll_int_loop_filt = 0,
-       .io.clock_khz = 12000,
-       .reset = dib80xx_tuner_reset,
-       .sleep = dib80xx_tuner_sleep,
-       .clkouttobamse = 1,
-       .analog_output = 1,
-       .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
-       .use_pwm_agc = 1,
-       .clkoutdrive = 1,
-       .get_adc_power = dib8090_get_adc_power,
-       .freq_offset_khz_uhf = -63,
-       .freq_offset_khz_vhf = -143,
-       .wbd = dib8090_wbd_table,
-       .fref_clock_ratio = 6,
-};
-
-static int dib8096_set_param_override(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
-       u16 target;
-       int ret = 0;
-       enum frontend_tune_state tune_state = CT_SHUTDOWN;
-       u16 ltgain, rf_gain_limit;
-
-       ret = state->set_param_save(fe);
-       if (ret < 0)
-               return ret;
-
-       target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
-       dib8000_set_wbd_ref(fe, target);
-
-
-       if (band == BAND_CBAND) {
-               deb_info("tuning in CBAND - soft-AGC startup\n");
-               dib0090_set_tune_state(fe, CT_AGC_START);
-               do {
-                       ret = dib0090_gain_control(fe);
-                       msleep(ret);
-                       tune_state = dib0090_get_tune_state(fe);
-                       if (tune_state == CT_AGC_STEP_0)
-                               dib8000_set_gpio(fe, 6, 0, 1);
-                       else if (tune_state == CT_AGC_STEP_1) {
-                               dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
-                               if (rf_gain_limit == 0)
-                                       dib8000_set_gpio(fe, 6, 0, 0);
-                       }
-               } while (tune_state < CT_AGC_STOP);
-               dib0090_pwm_gain_reset(fe);
-               dib8000_pwm_agc_reset(fe);
-               dib8000_set_tune_state(fe, CT_DEMOD_START);
-       } else {
-               deb_info("not tuning in CBAND - standard AGC startup\n");
-               dib0090_pwm_gain_reset(fe);
-       }
-
-       return 0;
-}
-
-static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
-               return -ENODEV;
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
-       return 0;
-}
-
-static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c;
-       struct dvb_frontend *fe_slave  = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);
-
-       if (fe_slave) {
-               tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
-               if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
-                       return -ENODEV;
-               fe_slave->dvb = adap->fe_adap[0].fe->dvb;
-               fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
-       }
-       tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
-               return -ENODEV;
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
-
-       return 0;
-}
-
-static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_frontend *fe_slave;
-
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(1000);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
-       if (adap->fe_adap[0].fe == NULL)
-               return -ENODEV;
-
-       fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
-       dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
-
-       return fe_slave == NULL ?  -ENODEV : 0;
-}
-
-/* TFE8096P */
-static struct dibx000_agc_config dib8096p_agc_config[2] = {
-       {
-               .band_caps              = BAND_UHF,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
-                  P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
-                  P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-                  P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
-                  P_agc_write=0 */
-               .setup                  = (0 << 15) | (0 << 14) | (5 << 11)
-                       | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
-                       | (0 << 4) | (5 << 1) | (0 << 0),
-
-               .inv_gain               = 684,
-               .time_stabiliz  = 10,
-
-               .alpha_level    = 0,
-               .thlock                 = 118,
-
-               .wbd_inv                = 0,
-               .wbd_ref                = 1200,
-               .wbd_sel                = 3,
-               .wbd_alpha              = 5,
-
-               .agc1_max               = 65535,
-               .agc1_min               = 0,
-
-               .agc2_max               = 32767,
-               .agc2_min               = 0,
-
-               .agc1_pt1               = 0,
-               .agc1_pt2               = 0,
-               .agc1_pt3               = 105,
-               .agc1_slope1    = 0,
-               .agc1_slope2    = 156,
-               .agc2_pt1               = 105,
-               .agc2_pt2               = 255,
-               .agc2_slope1    = 54,
-               .agc2_slope2    = 0,
-
-               .alpha_mant             = 28,
-               .alpha_exp              = 26,
-               .beta_mant              = 31,
-               .beta_exp               = 51,
-
-               .perform_agc_softsplit = 0,
-       } , {
-               .band_caps              = BAND_FM | BAND_VHF | BAND_CBAND,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
-                  P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
-                  P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
-                  P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
-                  P_agc_write=0 */
-               .setup                  = (0 << 15) | (0 << 14) | (5 << 11)
-                       | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
-                       | (0 << 4) | (5 << 1) | (0 << 0),
-
-               .inv_gain               = 732,
-               .time_stabiliz  = 10,
-
-               .alpha_level    = 0,
-               .thlock                 = 118,
-
-               .wbd_inv                = 0,
-               .wbd_ref                = 1200,
-               .wbd_sel                = 3,
-               .wbd_alpha              = 5,
-
-               .agc1_max               = 65535,
-               .agc1_min               = 0,
-
-               .agc2_max               = 32767,
-               .agc2_min               = 0,
-
-               .agc1_pt1               = 0,
-               .agc1_pt2               = 0,
-               .agc1_pt3               = 98,
-               .agc1_slope1    = 0,
-               .agc1_slope2    = 167,
-               .agc2_pt1               = 98,
-               .agc2_pt2               = 255,
-               .agc2_slope1    = 52,
-               .agc2_slope2    = 0,
-
-               .alpha_mant             = 28,
-               .alpha_exp              = 26,
-               .beta_mant              = 31,
-               .beta_exp               = 51,
-
-               .perform_agc_softsplit = 0,
-       }
-};
-
-static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
-       108000, 13500,
-       1, 9, 1, 0, 0,
-       0, 0, 0, 0, 2,
-       (3 << 14) | (1 << 12) | (524 << 0),
-       (0 << 25) | 0,
-       20199729,
-       12000000,
-};
-
-static struct dib8000_config tfe8096p_dib8000_config = {
-       .output_mpeg2_in_188_bytes      = 1,
-       .hostbus_diversity                      = 1,
-       .update_lna                                     = NULL,
-
-       .agc_config_count                       = 2,
-       .agc                                            = dib8096p_agc_config,
-       .pll                                            = &dib8096p_clock_config_12_mhz,
-
-       .gpio_dir                                       = DIB8000_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val                                       = DIB8000_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos                           = DIB8000_GPIO_DEFAULT_PWM_POS,
-
-       .agc_control                            = NULL,
-       .diversity_delay                        = 48,
-       .output_mode                            = OUTMODE_MPEG2_FIFO,
-       .enMpegOutput                           = 1,
-};
-
-static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
-       { 380, 81, 850, 64, 540, 4},
-       { 860, 51, 866, 21, 375, 4},
-       {1700, 0, 250, 0, 100, 6},
-       {2600, 0, 250, 0, 100, 6},
-       { 0xFFFF, 0, 0, 0, 0, 0},
-};
-
-static const struct dib0090_config tfe8096p_dib0090_config = {
-       .io.clock_khz                   = 12000,
-       .io.pll_bypass                  = 0,
-       .io.pll_range                   = 0,
-       .io.pll_prediv                  = 3,
-       .io.pll_loopdiv                 = 6,
-       .io.adc_clock_ratio             = 0,
-       .io.pll_int_loop_filt   = 0,
-       .reset                                  = dib8096p_tuner_sleep,
-       .sleep                                  = dib8096p_tuner_sleep,
-
-       .freq_offset_khz_uhf    = -143,
-       .freq_offset_khz_vhf    = -143,
-
-       .get_adc_power                  = dib8090_get_adc_power,
-
-       .clkouttobamse                  = 1,
-       .analog_output                  = 0,
-
-       .wbd_vhf_offset                 = 0,
-       .wbd_cband_offset               = 0,
-       .use_pwm_agc                    = 1,
-       .clkoutdrive                    = 0,
-
-       .fref_clock_ratio               = 1,
-
-       .wbd                                    = dib8096p_wbd_table,
-
-       .ls_cfg_pad_drv                 = 0,
-       .data_tx_drv                    = 0,
-       .low_if                                 = NULL,
-       .in_soc                                 = 1,
-       .force_cband_input              = 0,
-};
-
-struct dibx090p_adc {
-       u32 freq;                       /* RF freq MHz */
-       u32 timf;                       /* New Timf */
-       u32 pll_loopdiv;        /* New prediv */
-       u32 pll_prediv;         /* New loopdiv */
-};
-
-struct dibx090p_adc dib8090p_adc_tab[] = {
-       { 50000, 17043521, 16, 3}, /* 64 MHz */
-       {878000, 20199729, 9, 1}, /* 60 MHz */
-       {0xffffffff, 0, 0, 0}, /* 60 MHz */
-};
-
-static int dib8096p_agc_startup(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-       struct dibx000_bandwidth_config pll;
-       u16 target;
-       int better_sampling_freq = 0, ret;
-       struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
-
-       ret = state->set_param_save(fe);
-       if (ret < 0)
-               return ret;
-       memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
-
-       dib0090_pwm_gain_reset(fe);
-       /* dib0090_get_wbd_target is returning any possible
-          temperature compensated wbd-target */
-       target = (dib0090_get_wbd_target(fe) * 8  + 1) / 2;
-       dib8000_set_wbd_ref(fe, target);
-
-
-       while (p->frequency / 1000 > adc_table->freq) {
-               better_sampling_freq = 1;
-               adc_table++;
-       }
-
-       if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
-               pll.pll_ratio  = adc_table->pll_loopdiv;
-               pll.pll_prediv = adc_table->pll_prediv;
-               dib8000_update_pll(fe, &pll);
-               dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf);
-       }
-       return 0;
-}
-
-static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
-
-       adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
-                       &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
-                               &tfe8096p_dib0090_config) == NULL)
-               return -ENODEV;
-
-       dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
-       return 0;
-}
-
-/* STK9090M */
-static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
-{
-       return dib9000_fw_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
-}
-
-static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
-{
-       return dib9000_fw_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
-}
-
-static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
-{
-       return dib9000_set_gpio(fe, 5, 0, !onoff);
-}
-
-static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       return dib9000_set_gpio(fe, 0, 0, onoff);
-}
-
-static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
-{
-       u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
-       u8 rb[2];
-       struct i2c_msg msg[2] = {
-               {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
-               {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
-       };
-       u8 index_data;
-
-       dibx000_i2c_set_speed(i2c, 250);
-
-       if (i2c_transfer(i2c, msg, 2) != 2)
-               return -EIO;
-
-       switch (rb[0] << 8 | rb[1]) {
-       case 0:
-                       deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
-                       return -EIO;
-       case 1:
-                       deb_info("Found DiB0170 rev2");
-                       break;
-       case 2:
-                       deb_info("Found DiB0190 rev2");
-                       break;
-       default:
-                       deb_info("DiB01x0 not found");
-                       return -EIO;
-       }
-
-       for (index_data = 0; index_data < len; index_data += 2) {
-               wb[2] = (data[index_data + 1] >> 8) & 0xff;
-               wb[3] = (data[index_data + 1]) & 0xff;
-
-               if (data[index_data] == 0) {
-                       wb[0] = (data[index_data] >> 8) & 0xff;
-                       wb[1] = (data[index_data]) & 0xff;
-                       msg[0].len = 2;
-                       if (i2c_transfer(i2c, msg, 2) != 2)
-                               return -EIO;
-                       wb[2] |= rb[0];
-                       wb[3] |= rb[1] & ~(3 << 4);
-               }
-
-               wb[0] = (data[index_data] >> 8)&0xff;
-               wb[1] = (data[index_data])&0xff;
-               msg[0].len = 4;
-               if (i2c_transfer(i2c, &msg[0], 1) != 1)
-                       return -EIO;
-       }
-       return 0;
-}
-
-static struct dib9000_config stk9090m_config = {
-       .output_mpeg2_in_188_bytes = 1,
-       .output_mode = OUTMODE_MPEG2_FIFO,
-       .vcxo_timer = 279620,
-       .timing_frequency = 20452225,
-       .demod_clock_khz = 60000,
-       .xtal_clock_khz = 30000,
-       .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
-       .subband = {
-               2,
-               {
-                       { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
-                       { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
-                       { 0 },
-               },
-       },
-       .gpio_function = {
-               { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
-               { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
-       },
-};
-
-static struct dib9000_config nim9090md_config[2] = {
-       {
-               .output_mpeg2_in_188_bytes = 1,
-               .output_mode = OUTMODE_MPEG2_FIFO,
-               .vcxo_timer = 279620,
-               .timing_frequency = 20452225,
-               .demod_clock_khz = 60000,
-               .xtal_clock_khz = 30000,
-               .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
-       }, {
-               .output_mpeg2_in_188_bytes = 1,
-               .output_mode = OUTMODE_DIVERSITY,
-               .vcxo_timer = 279620,
-               .timing_frequency = 20452225,
-               .demod_clock_khz = 60000,
-               .xtal_clock_khz = 30000,
-               .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
-               .subband = {
-                       2,
-                       {
-                               { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
-                               { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
-                               { 0 },
-                       },
-               },
-               .gpio_function = {
-                       { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
-                       { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
-               },
-       }
-};
-
-static struct dib0090_config dib9090_dib0090_config = {
-       .io.pll_bypass = 0,
-       .io.pll_range = 1,
-       .io.pll_prediv = 1,
-       .io.pll_loopdiv = 8,
-       .io.adc_clock_ratio = 8,
-       .io.pll_int_loop_filt = 0,
-       .io.clock_khz = 30000,
-       .reset = dib90x0_tuner_reset,
-       .sleep = dib90x0_tuner_sleep,
-       .clkouttobamse = 0,
-       .analog_output = 0,
-       .use_pwm_agc = 0,
-       .clkoutdrive = 0,
-       .freq_offset_khz_uhf = 0,
-       .freq_offset_khz_vhf = 0,
-};
-
-static struct dib0090_config nim9090md_dib0090_config[2] = {
-       {
-               .io.pll_bypass = 0,
-               .io.pll_range = 1,
-               .io.pll_prediv = 1,
-               .io.pll_loopdiv = 8,
-               .io.adc_clock_ratio = 8,
-               .io.pll_int_loop_filt = 0,
-               .io.clock_khz = 30000,
-               .reset = dib90x0_tuner_reset,
-               .sleep = dib90x0_tuner_sleep,
-               .clkouttobamse = 1,
-               .analog_output = 0,
-               .use_pwm_agc = 0,
-               .clkoutdrive = 0,
-               .freq_offset_khz_uhf = 0,
-               .freq_offset_khz_vhf = 0,
-       }, {
-               .io.pll_bypass = 0,
-               .io.pll_range = 1,
-               .io.pll_prediv = 1,
-               .io.pll_loopdiv = 8,
-               .io.adc_clock_ratio = 8,
-               .io.pll_int_loop_filt = 0,
-               .io.clock_khz = 30000,
-               .reset = dib90x0_tuner_reset,
-               .sleep = dib90x0_tuner_sleep,
-               .clkouttobamse = 0,
-               .analog_output = 0,
-               .use_pwm_agc = 0,
-               .clkoutdrive = 0,
-               .freq_offset_khz_uhf = 0,
-               .freq_offset_khz_vhf = 0,
-       }
-};
-
-
-static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *state = adap->priv;
-       struct dib0700_state *st = adap->dev->priv;
-       u32 fw_version;
-
-       /* Make use of the new i2c functions from FW 1.20 */
-       dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
-       if (fw_version >= 0x10200)
-               st->fw_use_new_i2c_api = 1;
-       dib0700_set_i2c_speed(adap->dev, 340);
-
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
-
-       if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
-               deb_info("%s: Upload failed. (file not found?)\n", __func__);
-               return -ENODEV;
-       } else {
-               deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
-       }
-       stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
-       stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
-
-       adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *state = adap->priv;
-       struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
-       u16 data_dib190[10] = {
-               1, 0x1374,
-               2, 0x01a2,
-               7, 0x0020,
-               0, 0x00ef,
-               8, 0x0486,
-       };
-
-       if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
-               return -ENODEV;
-       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
-       if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
-               return -ENODEV;
-       dib0700_set_i2c_speed(adap->dev, 1500);
-       if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
-               return -ENODEV;
-       release_firmware(state->frontend_firmware);
-       return 0;
-}
-
-static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *state = adap->priv;
-       struct dib0700_state *st = adap->dev->priv;
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe_slave;
-       u32 fw_version;
-
-       /* Make use of the new i2c functions from FW 1.20 */
-       dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
-       if (fw_version >= 0x10200)
-               st->fw_use_new_i2c_api = 1;
-       dib0700_set_i2c_speed(adap->dev, 340);
-
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
-               deb_info("%s: Upload failed. (file not found?)\n", __func__);
-               return -EIO;
-       } else {
-               deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
-       }
-       nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
-       nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
-       nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
-       nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
-
-       dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
-       adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
-
-       if (adap->fe_adap[0].fe == NULL)
-               return -ENODEV;
-
-       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
-       dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
-
-       fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
-       dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
-
-       return fe_slave == NULL ?  -ENODEV : 0;
-}
-
-static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *state = adap->priv;
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe_slave;
-       u16 data_dib190[10] = {
-               1, 0x5374,
-               2, 0x01ae,
-               7, 0x0020,
-               0, 0x00ef,
-               8, 0x0406,
-       };
-       i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
-       if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
-               return -ENODEV;
-       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
-       if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
-               return -ENODEV;
-
-       dib0700_set_i2c_speed(adap->dev, 1500);
-       if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
-               return -ENODEV;
-
-       fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1);
-       if (fe_slave != NULL) {
-               i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].fe);
-               dib9000_set_i2c_adapter(fe_slave, i2c);
-
-               i2c = dib9000_get_tuner_interface(fe_slave);
-               if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
-                       return -ENODEV;
-               fe_slave->dvb = adap->fe_adap[0].fe->dvb;
-               dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
-               if (dib9000_firmware_post_pll_init(fe_slave) < 0)
-                       return -ENODEV;
-       }
-       release_firmware(state->frontend_firmware);
-
-       return 0;
-}
-
-/* NIM7090 */
-struct dib7090p_best_adc {
-       u32 timf;
-       u32 pll_loopdiv;
-       u32 pll_prediv;
-};
-
-static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
-{
-       u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
-
-       u16 xtal = 12000;
-       u32 fcp_min = 1900;  /* PLL Minimum Frequency comparator KHz */
-       u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
-       u32 fdem_max = 76000;
-       u32 fdem_min = 69500;
-       u32 fcp = 0, fs = 0, fdem = 0;
-       u32 harmonic_id = 0;
-
-       adc->pll_loopdiv = loopdiv;
-       adc->pll_prediv = prediv;
-       adc->timf = 0;
-
-       deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
-
-       /* Find Min and Max prediv */
-       while ((xtal/max_prediv) >= fcp_min)
-               max_prediv++;
-
-       max_prediv--;
-       min_prediv = max_prediv;
-       while ((xtal/min_prediv) <= fcp_max) {
-               min_prediv--;
-               if (min_prediv == 1)
-                       break;
-       }
-       deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
-
-       min_prediv = 2;
-
-       for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
-               fcp = xtal / prediv;
-               if (fcp > fcp_min && fcp < fcp_max) {
-                       for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
-                               fdem = ((xtal/prediv) * loopdiv);
-                               fs   = fdem / 4;
-                               /* test min/max system restrictions */
-
-                               if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
-                                       spur = 0;
-                                       /* test fs harmonics positions */
-                                       for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ;  harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
-                                               if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) &&  ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
-                                                       spur = 1;
-                                                       break;
-                                               }
-                                       }
-
-                                       if (!spur) {
-                                               adc->pll_loopdiv = loopdiv;
-                                               adc->pll_prediv = prediv;
-                                               adc->timf = 2396745143UL/fdem*(1 << 9);
-                                               adc->timf += ((2396745143UL%fdem) << 9)/fdem;
-                                               deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               if (!spur)
-                       break;
-       }
-
-
-       if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
-               return -EINVAL;
-       else
-               return 0;
-}
-
-static int dib7090_agc_startup(struct dvb_frontend *fe)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dib0700_adapter_state *state = adap->priv;
-       struct dibx000_bandwidth_config pll;
-       u16 target;
-       struct dib7090p_best_adc adc;
-       int ret;
-
-       ret = state->set_param_save(fe);
-       if (ret < 0)
-               return ret;
-
-       memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
-       dib0090_pwm_gain_reset(fe);
-       target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
-       dib7000p_set_wbd_ref(fe, target);
-
-       if (dib7090p_get_best_sampling(fe, &adc) == 0) {
-               pll.pll_ratio  = adc.pll_loopdiv;
-               pll.pll_prediv = adc.pll_prediv;
-
-               dib7000p_update_pll(fe, &pll);
-               dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
-       }
-       return 0;
-}
-
-static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
-{
-       deb_info("AGC restart callback: %d", restart);
-       if (restart == 0) /* before AGC startup */
-               dib0090_set_dc_servo(fe, 1);
-       return 0;
-}
-
-static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global)
-{
-       u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1;
-       s16 wbd_delta;
-
-       if ((fe->dtv_property_cache.frequency) < 400000000)
-               threshold_agc1 = 25000;
-       else
-               threshold_agc1 = 30000;
-
-       wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2;
-       wbd_offset = dib0090_get_wbd_offset(fe);
-       dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd);
-       wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ;
-
-       deb_info("update lna, agc_global=%d agc1=%d agc2=%d",
-                       agc_global, agc1, agc2);
-       deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d",
-                       wbd, wbd_target, wbd_offset, wbd_delta);
-
-       if ((agc1 < threshold_agc1) && (wbd_delta > 0)) {
-               dib0090_set_switch(fe, 1, 1, 1);
-               dib0090_set_vga(fe, 0);
-               dib0090_update_rframp_7090(fe, 0);
-               dib0090_update_tuning_table_7090(fe, 0);
-       } else {
-               dib0090_set_vga(fe, 1);
-               dib0090_update_rframp_7090(fe, 1);
-               dib0090_update_tuning_table_7090(fe, 1);
-               dib0090_set_switch(fe, 0, 0, 0);
-       }
-
-       return 0;
-}
-
-static struct dib0090_wbd_slope dib7090_wbd_table[] = {
-       { 380,   81, 850, 64, 540,  4},
-       { 860,   51, 866, 21,  375, 4},
-       {1700,    0, 250, 0,   100, 6},
-       {2600,    0, 250, 0,   100, 6},
-       { 0xFFFF, 0,   0, 0,   0,   0},
-};
-
-static struct dib0090_wbd_slope dib7090e_wbd_table[] = {
-       { 380,   81, 850, 64, 540,      4},
-       { 700,   51, 866, 21,  320,     4},
-       { 860,   48, 666, 18,  330,     6},
-       {1700,    0, 250, 0,   100, 6},
-       {2600,    0, 250, 0,   100, 6},
-       { 0xFFFF, 0,   0, 0,   0,       0},
-};
-
-static struct dibx000_agc_config dib7090_agc_config[2] = {
-       {
-               .band_caps      = BAND_UHF,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
-               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-               .setup          = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-               .inv_gain       = 687,
-               .time_stabiliz  = 10,
-
-               .alpha_level    = 0,
-               .thlock         = 118,
-
-               .wbd_inv        = 0,
-               .wbd_ref        = 1200,
-               .wbd_sel        = 3,
-               .wbd_alpha      = 5,
-
-               .agc1_max       = 65535,
-               .agc1_min       = 0,
-
-               .agc2_max       = 65535,
-               .agc2_min       = 0,
-
-               .agc1_pt1       = 0,
-               .agc1_pt2       = 32,
-               .agc1_pt3       = 114,
-               .agc1_slope1    = 143,
-               .agc1_slope2    = 144,
-               .agc2_pt1       = 114,
-               .agc2_pt2       = 227,
-               .agc2_slope1    = 116,
-               .agc2_slope2    = 117,
-
-               .alpha_mant     = 18,
-               .alpha_exp      = 0,
-               .beta_mant      = 20,
-               .beta_exp       = 59,
-
-               .perform_agc_softsplit = 0,
-       } , {
-               .band_caps      = BAND_FM | BAND_VHF | BAND_CBAND,
-               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
-               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-               .setup          = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
-
-               .inv_gain       = 732,
-               .time_stabiliz  = 10,
-
-               .alpha_level    = 0,
-               .thlock         = 118,
-
-               .wbd_inv        = 0,
-               .wbd_ref        = 1200,
-               .wbd_sel        = 3,
-               .wbd_alpha      = 5,
-
-               .agc1_max       = 65535,
-               .agc1_min       = 0,
-
-               .agc2_max       = 65535,
-               .agc2_min       = 0,
-
-               .agc1_pt1       = 0,
-               .agc1_pt2       = 0,
-               .agc1_pt3       = 98,
-               .agc1_slope1    = 0,
-               .agc1_slope2    = 167,
-               .agc2_pt1       = 98,
-               .agc2_pt2       = 255,
-               .agc2_slope1    = 104,
-               .agc2_slope2    = 0,
-
-               .alpha_mant     = 18,
-               .alpha_exp      = 0,
-               .beta_mant      = 20,
-               .beta_exp       = 59,
-
-               .perform_agc_softsplit = 0,
-       }
-};
-
-static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
-       60000, 15000,
-       1, 5, 0, 0, 0,
-       0, 0, 1, 1, 2,
-       (3 << 14) | (1 << 12) | (524 << 0),
-       (0 << 25) | 0,
-       20452225,
-       15000000,
-};
-
-static struct dib7000p_config nim7090_dib7000p_config = {
-       .output_mpeg2_in_188_bytes  = 1,
-       .hostbus_diversity                      = 1,
-       .tuner_is_baseband                      = 1,
-       .update_lna                                     = NULL,
-
-       .agc_config_count                       = 2,
-       .agc                                            = dib7090_agc_config,
-
-       .bw                                                     = &dib7090_clock_config_12_mhz,
-
-       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .pwm_freq_div                           = 0,
-
-       .agc_control                            = dib7090_agc_restart,
-
-       .spur_protect                           = 0,
-       .disable_sample_and_hold        = 0,
-       .enable_current_mirror          = 0,
-       .diversity_delay                        = 0,
-
-       .output_mode                            = OUTMODE_MPEG2_FIFO,
-       .enMpegOutput                           = 1,
-};
-
-static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
-       {
-               .output_mpeg2_in_188_bytes  = 1,
-               .hostbus_diversity                      = 1,
-               .tuner_is_baseband                      = 1,
-               .update_lna                                     = NULL,
-
-               .agc_config_count                       = 2,
-               .agc                                            = dib7090_agc_config,
-
-               .bw                                                     = &dib7090_clock_config_12_mhz,
-
-               .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-               .pwm_freq_div                           = 0,
-
-               .agc_control                            = dib7090_agc_restart,
-
-               .spur_protect                           = 0,
-               .disable_sample_and_hold        = 0,
-               .enable_current_mirror          = 0,
-               .diversity_delay                        = 0,
-
-               .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
-               .default_i2c_addr                       = 0x90,
-               .enMpegOutput                           = 1,
-       }, {
-               .output_mpeg2_in_188_bytes  = 1,
-               .hostbus_diversity                      = 1,
-               .tuner_is_baseband                      = 1,
-               .update_lna                                     = NULL,
-
-               .agc_config_count                       = 2,
-               .agc                                            = dib7090_agc_config,
-
-               .bw                                                     = &dib7090_clock_config_12_mhz,
-
-               .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-               .pwm_freq_div                           = 0,
-
-               .agc_control                            = dib7090_agc_restart,
-
-               .spur_protect                           = 0,
-               .disable_sample_and_hold        = 0,
-               .enable_current_mirror          = 0,
-               .diversity_delay                        = 0,
-
-               .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
-               .default_i2c_addr                       = 0x92,
-               .enMpegOutput                           = 0,
-       }
-};
-
-static struct dib7000p_config tfe7090e_dib7000p_config = {
-       .output_mpeg2_in_188_bytes  = 1,
-       .hostbus_diversity                      = 1,
-       .tuner_is_baseband                      = 1,
-       .update_lna                                     = dib7090e_update_lna,
-
-       .agc_config_count                       = 2,
-       .agc                                            = dib7090_agc_config,
-
-       .bw                                                     = &dib7090_clock_config_12_mhz,
-
-       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .pwm_freq_div                           = 0,
-
-       .agc_control                            = dib7090_agc_restart,
-
-       .spur_protect                           = 0,
-       .disable_sample_and_hold        = 0,
-       .enable_current_mirror          = 0,
-       .diversity_delay                        = 0,
-
-       .output_mode                            = OUTMODE_MPEG2_FIFO,
-       .enMpegOutput                           = 1,
-};
-
-static const struct dib0090_config nim7090_dib0090_config = {
-       .io.clock_khz = 12000,
-       .io.pll_bypass = 0,
-       .io.pll_range = 0,
-       .io.pll_prediv = 3,
-       .io.pll_loopdiv = 6,
-       .io.adc_clock_ratio = 0,
-       .io.pll_int_loop_filt = 0,
-       .reset = dib7090_tuner_sleep,
-       .sleep = dib7090_tuner_sleep,
-
-       .freq_offset_khz_uhf = 0,
-       .freq_offset_khz_vhf = 0,
-
-       .get_adc_power = dib7090_get_adc_power,
-
-       .clkouttobamse = 1,
-       .analog_output = 0,
-
-       .wbd_vhf_offset = 0,
-       .wbd_cband_offset = 0,
-       .use_pwm_agc = 1,
-       .clkoutdrive = 0,
-
-       .fref_clock_ratio = 0,
-
-       .wbd = dib7090_wbd_table,
-
-       .ls_cfg_pad_drv = 0,
-       .data_tx_drv = 0,
-       .low_if = NULL,
-       .in_soc = 1,
-};
-
-static const struct dib0090_config tfe7090e_dib0090_config = {
-       .io.clock_khz = 12000,
-       .io.pll_bypass = 0,
-       .io.pll_range = 0,
-       .io.pll_prediv = 3,
-       .io.pll_loopdiv = 6,
-       .io.adc_clock_ratio = 0,
-       .io.pll_int_loop_filt = 0,
-       .reset = dib7090_tuner_sleep,
-       .sleep = dib7090_tuner_sleep,
-
-       .freq_offset_khz_uhf = 0,
-       .freq_offset_khz_vhf = 0,
-
-       .get_adc_power = dib7090_get_adc_power,
-
-       .clkouttobamse = 1,
-       .analog_output = 0,
-
-       .wbd_vhf_offset = 0,
-       .wbd_cband_offset = 0,
-       .use_pwm_agc = 1,
-       .clkoutdrive = 0,
-
-       .fref_clock_ratio = 0,
-
-       .wbd = dib7090e_wbd_table,
-
-       .ls_cfg_pad_drv = 0,
-       .data_tx_drv = 0,
-       .low_if = NULL,
-       .in_soc = 1,
-       .force_cband_input = 1,
-       .is_dib7090e = 1,
-};
-
-static struct dib7000p_config tfe7790e_dib7000p_config = {
-       .output_mpeg2_in_188_bytes  = 1,
-       .hostbus_diversity                      = 1,
-       .tuner_is_baseband                      = 1,
-       .update_lna                                     = dib7090e_update_lna,
-
-       .agc_config_count                       = 2,
-       .agc                                            = dib7090_agc_config,
-
-       .bw                                                     = &dib7090_clock_config_12_mhz,
-
-       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-       .pwm_freq_div                           = 0,
-
-       .agc_control                            = dib7090_agc_restart,
-
-       .spur_protect                           = 0,
-       .disable_sample_and_hold        = 0,
-       .enable_current_mirror          = 0,
-       .diversity_delay                        = 0,
-
-       .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
-       .enMpegOutput                           = 1,
-};
-
-static const struct dib0090_config tfe7790e_dib0090_config = {
-       .io.clock_khz = 12000,
-       .io.pll_bypass = 0,
-       .io.pll_range = 0,
-       .io.pll_prediv = 3,
-       .io.pll_loopdiv = 6,
-       .io.adc_clock_ratio = 0,
-       .io.pll_int_loop_filt = 0,
-       .reset = dib7090_tuner_sleep,
-       .sleep = dib7090_tuner_sleep,
-
-       .freq_offset_khz_uhf = 0,
-       .freq_offset_khz_vhf = 0,
-
-       .get_adc_power = dib7090_get_adc_power,
-
-       .clkouttobamse = 1,
-       .analog_output = 0,
-
-       .wbd_vhf_offset = 0,
-       .wbd_cband_offset = 0,
-       .use_pwm_agc = 1,
-       .clkoutdrive = 0,
-
-       .fref_clock_ratio = 0,
-
-       .wbd = dib7090e_wbd_table,
-
-       .ls_cfg_pad_drv = 0,
-       .data_tx_drv = 0,
-       .low_if = NULL,
-       .in_soc = 1,
-       .force_cband_input = 1,
-       .is_dib7090e = 1,
-       .force_crystal_mode = 1,
-};
-
-static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
-       {
-               .io.clock_khz = 12000,
-               .io.pll_bypass = 0,
-               .io.pll_range = 0,
-               .io.pll_prediv = 3,
-               .io.pll_loopdiv = 6,
-               .io.adc_clock_ratio = 0,
-               .io.pll_int_loop_filt = 0,
-               .reset = dib7090_tuner_sleep,
-               .sleep = dib7090_tuner_sleep,
-
-               .freq_offset_khz_uhf = 50,
-               .freq_offset_khz_vhf = 70,
-
-               .get_adc_power = dib7090_get_adc_power,
-
-               .clkouttobamse = 1,
-               .analog_output = 0,
-
-               .wbd_vhf_offset = 0,
-               .wbd_cband_offset = 0,
-               .use_pwm_agc = 1,
-               .clkoutdrive = 0,
-
-               .fref_clock_ratio = 0,
-
-               .wbd = dib7090_wbd_table,
-
-               .ls_cfg_pad_drv = 0,
-               .data_tx_drv = 0,
-               .low_if = NULL,
-               .in_soc = 1,
-       }, {
-               .io.clock_khz = 12000,
-               .io.pll_bypass = 0,
-               .io.pll_range = 0,
-               .io.pll_prediv = 3,
-               .io.pll_loopdiv = 6,
-               .io.adc_clock_ratio = 0,
-               .io.pll_int_loop_filt = 0,
-               .reset = dib7090_tuner_sleep,
-               .sleep = dib7090_tuner_sleep,
-
-               .freq_offset_khz_uhf = -50,
-               .freq_offset_khz_vhf = -70,
-
-               .get_adc_power = dib7090_get_adc_power,
-
-               .clkouttobamse = 1,
-               .analog_output = 0,
-
-               .wbd_vhf_offset = 0,
-               .wbd_cband_offset = 0,
-               .use_pwm_agc = 1,
-               .clkoutdrive = 0,
-
-               .fref_clock_ratio = 0,
-
-               .wbd = dib7090_wbd_table,
-
-               .ls_cfg_pad_drv = 0,
-               .data_tx_drv = 0,
-               .low_if = NULL,
-               .in_soc = 1,
-       }
-};
-
-static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
-               return -ENODEV;
-       }
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
-               return -ENODEV;
-
-       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
-       return 0;
-}
-
-static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-
-       /* The TFE7090 requires the dib0700 to not be in master mode */
-       st->disable_streaming_master_mode = 1;
-
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       /* initialize IC 0 */
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
-               return -ENODEV;
-       }
-
-       dib0700_set_i2c_speed(adap->dev, 340);
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
-       if (adap->fe_adap[0].fe == NULL)
-               return -ENODEV;
-
-       dib7090_slave_reset(adap->fe_adap[0].fe);
-
-       return 0;
-}
-
-static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *i2c;
-
-       if (adap->dev->adapter[0].fe_adap[0].fe == NULL) {
-               err("the master dib7090 has to be initialized first");
-               return -ENODEV; /* the master device has not been initialized */
-       }
-
-       i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
-       if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
-       dib0700_set_i2c_speed(adap->dev, 200);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
-               return -ENODEV;
-
-       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
-       return 0;
-}
-
-static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
-               return -ENODEV;
-
-       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
-       return 0;
-}
-
-static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
-                               1, 0x10, &tfe7090e_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                               __func__);
-               return -ENODEV;
-       }
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
-                       0x80, &tfe7090e_dib7000p_config);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-
-       /* The TFE7790E requires the dib0700 to not be in master mode */
-       st->disable_streaming_master_mode = 1;
-
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-       msleep(20);
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(20);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
-                               1, 0x10, &tfe7790e_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                               __func__);
-               return -ENODEV;
-       }
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
-                       0x80, &tfe7790e_dib7000p_config);
-
-       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
-}
-
-static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c =
-               dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
-                               &tfe7790e_dib0090_config) == NULL)
-               return -ENODEV;
-
-       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
-       return 0;
-}
-
-static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_adapter_state *st = adap->priv;
-       struct i2c_adapter *tun_i2c =
-               dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
-
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
-                               &tfe7090e_dib0090_config) == NULL)
-               return -ENODEV;
-
-       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-
-       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
-       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
-       return 0;
-}
-
-/* STK7070PD */
-static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
-       {
-               .output_mpeg2_in_188_bytes = 1,
-
-               .agc_config_count = 1,
-               .agc = &dib7070_agc_config,
-               .bw  = &dib7070_bw_config_12_mhz,
-               .tuner_is_baseband = 1,
-               .spur_protect = 1,
-
-               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-               .hostbus_diversity = 1,
-       }, {
-               .output_mpeg2_in_188_bytes = 1,
-
-               .agc_config_count = 1,
-               .agc = &dib7070_agc_config,
-               .bw  = &dib7070_bw_config_12_mhz,
-               .tuner_is_baseband = 1,
-               .spur_protect = 1,
-
-               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
-               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
-               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
-
-               .hostbus_diversity = 1,
-       }
-};
-
-static void stk7070pd_init(struct dvb_usb_device *dev)
-{
-       dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
-       msleep(10);
-       dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
-
-       dib0700_ctrl_clock(dev, 72, 1);
-
-       msleep(10);
-       dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
-}
-
-static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
-{
-       stk7070pd_init(adap->dev);
-
-       msleep(10);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-
-       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
-                                    stk7070pd_dib7000p_config) != 0) {
-               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                   __func__);
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
-{
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int novatd_read_status_override(struct dvb_frontend *fe,
-               fe_status_t *stat)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *dev = adap->dev;
-       struct dib0700_state *state = dev->priv;
-       int ret;
-
-       ret = state->read_status(fe, stat);
-
-       if (!ret)
-               dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
-                               !!(*stat & FE_HAS_LOCK));
-
-       return ret;
-}
-
-static int novatd_sleep_override(struct dvb_frontend* fe)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *dev = adap->dev;
-       struct dib0700_state *state = dev->priv;
-
-       /* turn off LED */
-       dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
-
-       return state->sleep(fe);
-}
-
-/**
- * novatd_frontend_attach - Nova-TD specific attach
- *
- * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
- * information purposes.
- */
-static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *dev = adap->dev;
-       struct dib0700_state *st = dev->priv;
-
-       if (adap->id == 0) {
-               stk7070pd_init(dev);
-
-               /* turn the power LED on, the other two off (just in case) */
-               dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
-               dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
-               dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
-
-               if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
-                                            stk7070pd_dib7000p_config) != 0) {
-                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
-                           __func__);
-                       return -ENODEV;
-               }
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
-                       adap->id == 0 ? 0x80 : 0x82,
-                       &stk7070pd_dib7000p_config[adap->id]);
-
-       if (adap->fe_adap[0].fe == NULL)
-               return -ENODEV;
-
-       st->read_status = adap->fe_adap[0].fe->ops.read_status;
-       adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
-       st->sleep = adap->fe_adap[0].fe->ops.sleep;
-       adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
-
-       return 0;
-}
-
-/* S5H1411 */
-static struct s5h1411_config pinnacle_801e_config = {
-       .output_mode   = S5H1411_PARALLEL_OUTPUT,
-       .gpio          = S5H1411_GPIO_OFF,
-       .mpeg_timing   = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
-       .qam_if        = S5H1411_IF_44000,
-       .vsb_if        = S5H1411_IF_44000,
-       .inversion     = S5H1411_INVERSION_OFF,
-       .status_mode   = S5H1411_DEMODLOCKING
-};
-
-/* Pinnacle PCTV HD Pro 801e GPIOs map:
-   GPIO0  - currently unknown
-   GPIO1  - xc5000 tuner reset
-   GPIO2  - CX25843 sleep
-   GPIO3  - currently unknown
-   GPIO4  - currently unknown
-   GPIO6  - currently unknown
-   GPIO7  - currently unknown
-   GPIO9  - currently unknown
-   GPIO10 - CX25843 reset
- */
-static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-
-       /* Make use of the new i2c functions from FW 1.20 */
-       st->fw_use_new_i2c_api = 1;
-
-       /* The s5h1411 requires the dib0700 to not be in master mode */
-       st->disable_streaming_master_mode = 1;
-
-       /* All msleep values taken from Windows USB trace */
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
-       dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(400);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-       msleep(60);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(30);
-       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
-       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
-       msleep(30);
-
-       /* Put the CX25843 to sleep for now since we're in digital mode */
-       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
-
-       /* GPIOs are initialized, do the attach */
-       adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
-                             &adap->dev->i2c_adap);
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int dib0700_xc5000_tuner_callback(void *priv, int component,
-                                        int command, int arg)
-{
-       struct dvb_usb_adapter *adap = priv;
-
-       if (command == XC5000_TUNER_RESET) {
-               /* Reset the tuner */
-               dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
-               msleep(10);
-               dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
-               msleep(10);
-       } else {
-               err("xc5000: unknown tuner callback command: %d\n", command);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct xc5000_config s5h1411_xc5000_tunerconfig = {
-       .i2c_address      = 0x64,
-       .if_khz           = 5380,
-};
-
-static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       /* FIXME: generalize & move to common area */
-       adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback;
-
-       return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
-                         &s5h1411_xc5000_tunerconfig)
-               == NULL ? -ENODEV : 0;
-}
-
-static int dib0700_xc4000_tuner_callback(void *priv, int component,
-                                        int command, int arg)
-{
-       struct dvb_usb_adapter *adap = priv;
-
-       if (command == XC4000_TUNER_RESET) {
-               /* Reset the tuner */
-               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
-               msleep(10);
-               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
-       } else {
-               err("xc4000: unknown tuner callback command: %d\n", command);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
-       .band_caps = BAND_UHF | BAND_VHF,
-       .setup = 0x64,
-       .inv_gain = 0x02c8,
-       .time_stabiliz = 0x15,
-       .alpha_level = 0x00,
-       .thlock = 0x76,
-       .wbd_inv = 0x01,
-       .wbd_ref = 0x0b33,
-       .wbd_sel = 0x00,
-       .wbd_alpha = 0x02,
-       .agc1_max = 0x00,
-       .agc1_min = 0x00,
-       .agc2_max = 0x9b26,
-       .agc2_min = 0x26ca,
-       .agc1_pt1 = 0x00,
-       .agc1_pt2 = 0x00,
-       .agc1_pt3 = 0x00,
-       .agc1_slope1 = 0x00,
-       .agc1_slope2 = 0x00,
-       .agc2_pt1 = 0x00,
-       .agc2_pt2 = 0x80,
-       .agc2_slope1 = 0x1d,
-       .agc2_slope2 = 0x1d,
-       .alpha_mant = 0x11,
-       .alpha_exp = 0x1b,
-       .beta_mant = 0x17,
-       .beta_exp = 0x33,
-       .perform_agc_softsplit = 0x00,
-};
-
-static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
-       60000, 30000,   /* internal, sampling */
-       1, 8, 3, 1, 0,  /* pll_cfg: prediv, ratio, range, reset, bypass */
-       0, 0, 1, 1, 0,  /* misc: refdiv, bypclk_div, IO_CLK_en_core, */
-                       /* ADClkSrc, modulo */
-       (3 << 14) | (1 << 12) | 524,    /* sad_cfg: refsel, sel, freq_15k */
-       39370534,       /* ifreq */
-       20452225,       /* timf */
-       30000000        /* xtal */
-};
-
-/* FIXME: none of these inputs are validated yet */
-static struct dib7000p_config pctv_340e_config = {
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_config_count = 1,
-       .agc = &stk7700p_7000p_xc4000_agc_config,
-       .bw  = &stk7700p_xc4000_pll_config,
-
-       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
-       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
-       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
-};
-
-/* PCTV 340e GPIOs map:
-   dib0700:
-   GPIO2  - CX25843 sleep
-   GPIO3  - CS5340 reset
-   GPIO5  - IRD
-   GPIO6  - Power Supply
-   GPIO8  - LNA (1=off 0=on)
-   GPIO10 - CX25843 reset
-   dib7000:
-   GPIO8  - xc4000 reset
- */
-static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-
-       /* Power Supply on */
-       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0);
-       msleep(50);
-       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1);
-       msleep(100); /* Allow power supply to settle before probing */
-
-       /* cx25843 reset */
-       dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 0);
-       msleep(1); /* cx25843 datasheet say 350us required */
-       dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 1);
-
-       /* LNA off for now */
-       dib0700_set_gpio(adap->dev, GPIO8,  GPIO_OUT, 1);
-
-       /* Put the CX25843 to sleep for now since we're in digital mode */
-       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
-
-       /* FIXME: not verified yet */
-       dib0700_ctrl_clock(adap->dev, 72, 1);
-
-       msleep(500);
-
-       if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
-               /* Demodulator not found for some reason? */
-               return -ENODEV;
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
-                             &pctv_340e_config);
-       st->is_dib7000pc = 1;
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static struct xc4000_config dib7000p_xc4000_tunerconfig = {
-       .i2c_address      = 0x61,
-       .default_pm       = 1,
-       .dvb_amplitude    = 0,
-       .set_smoothedcvbs = 0,
-       .if_khz           = 5400
-};
-
-static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct i2c_adapter *tun_i2c;
-
-       /* The xc4000 is not on the main i2c bus */
-       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
-                                         DIBX000_I2C_INTERFACE_TUNER, 1);
-       if (tun_i2c == NULL) {
-               printk(KERN_ERR "Could not reach tuner i2c bus\n");
-               return 0;
-       }
-
-       /* Setup the reset callback */
-       adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback;
-
-       return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c,
-                         &dib7000p_xc4000_tunerconfig)
-               == NULL ? -ENODEV : 0;
-}
-
-static struct lgdt3305_config hcw_lgdt3305_config = {
-       .i2c_addr           = 0x0e,
-       .mpeg_mode          = LGDT3305_MPEG_PARALLEL,
-       .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
-       .tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
-       .deny_i2c_rptr      = 0,
-       .spectral_inversion = 1,
-       .qam_if_khz         = 6000,
-       .vsb_if_khz         = 6000,
-       .usref_8vsb         = 0x0500,
-};
-
-static struct mxl5007t_config hcw_mxl5007t_config = {
-       .xtal_freq_hz = MxL_XTAL_25_MHZ,
-       .if_freq_hz = MxL_IF_6_MHZ,
-       .invert_if = 1,
-};
-
-/* TIGER-ATSC map:
-   GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
-   GPIO1  - ANT_SEL  (H: VPA, L: MCX)
-   GPIO4  - SCL2
-   GPIO6  - EN_TUNER
-   GPIO7  - SDA2
-   GPIO10 - DEM_RST
-
-   MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
- */
-static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib0700_state *st = adap->dev->priv;
-
-       /* Make use of the new i2c functions from FW 1.20 */
-       st->fw_use_new_i2c_api = 1;
-
-       st->disable_streaming_master_mode = 1;
-
-       /* fe power enable */
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
-       msleep(30);
-       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
-       msleep(30);
-
-       /* demod reset */
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(30);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
-       msleep(30);
-       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
-       msleep(30);
-
-       adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach,
-                             &hcw_lgdt3305_config,
-                             &adap->dev->i2c_adap);
-
-       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
-                         &adap->dev->i2c_adap, 0x60,
-                         &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
-}
-
-
-/* DVB-USB and USB stuff follows */
-struct usb_device_id dib0700_usb_id_table[] = {
-/* 0 */        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
-/* 5 */        { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
-       { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
-       { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
-       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
-/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
-       { USB_DEVICE(USB_VID_TERRATEC,
-                       USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
-/* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
-       { USB_DEVICE(USB_VID_PINNACLE,
-                       USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
-       { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
-/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
-       { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
-       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
-       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
-       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
-/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_EXPRESSCARD_320CX) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV72E) },
-/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
-       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_EC372S) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS) },
-       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
-/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
-       { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U8000) },
-       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700PH) },
-       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000H) },
-/* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
-       { USB_DEVICE(USB_VID_TERRATEC,
-                       USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
-       { USB_DEVICE(USB_VID_SONY,      USB_PID_SONY_PLAYTV) },
-/* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
-       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
-       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_MC770) },
-       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT) },
-/* 50 */{ USB_DEVICE(USB_VID_ELGATO,   USB_PID_ELGATO_EYETV_DTT_Dlx) },
-       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T3) },
-       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T5) },
-       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
-/* 55 */{ USB_DEVICE(USB_VID_YUAN,     USB_PID_YUAN_STK7700D_2) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73A) },
-       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV73ESE) },
-       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV282E) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
-/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
-       { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
-       { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
-/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096GP) },
-       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DIVERSITY) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM9090M) },
-/* 70 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM8096MD) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM9090MD) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM7090) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090PVR) },
-       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
-/* 75 */{ USB_DEVICE(USB_VID_MEDION,    USB_PID_CREATIX_CTX1921) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E) },
-       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E_SE) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090E) },
-       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7790E) },
-/* 80 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE8096P) },
-       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT_2) },
-       { 0 }           /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
-
-#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
-       .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
-       .usb_ctrl          = DEVICE_SPECIFIC, \
-       .firmware          = "dvb-usb-dib0700-1.20.fw", \
-       .download_firmware = dib0700_download_firmware, \
-       .no_reconnect      = 1, \
-       .size_of_priv      = sizeof(struct dib0700_state), \
-       .i2c_algo          = &dib0700_i2c_algo, \
-       .identify_state    = dib0700_identify_state
-
-#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
-       .streaming_ctrl   = dib0700_streaming_ctrl, \
-       .stream = { \
-               .type = USB_BULK, \
-               .count = 4, \
-               .endpoint = ep, \
-               .u = { \
-                       .bulk = { \
-                               .buffersize = 39480, \
-                       } \
-               } \
-       }
-
-struct dvb_usb_device_properties dib0700_devices[] = {
-       {
-               DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk7700p_pid_filter,
-                               .pid_filter_ctrl  = stk7700p_pid_filter_ctrl,
-                               .frontend_attach  = stk7700p_frontend_attach,
-                               .tuner_attach     = stk7700p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                       },
-               },
-
-               .num_device_descs = 8,
-               .devices = {
-                       {   "DiBcom STK7700P reference design",
-                               { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
-                               { NULL },
-                       },
-                       {   "Hauppauge Nova-T Stick",
-                               { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
-                               { NULL },
-                       },
-                       {   "AVerMedia AVerTV DVB-T Volar",
-                               { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
-                               { NULL },
-                       },
-                       {   "Compro Videomate U500",
-                               { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
-                               { NULL },
-                       },
-                       {   "Uniwill STK7700P based (Hama and others)",
-                               { &dib0700_usb_id_table[7], NULL },
-                               { NULL },
-                       },
-                       {   "Leadtek Winfast DTV Dongle (STK7700P based)",
-                               { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
-                               { NULL },
-                       },
-                       {   "AVerMedia AVerTV DVB-T Express",
-                               { &dib0700_usb_id_table[20] },
-                               { NULL },
-                       },
-                       {   "Gigabyte U7000",
-                               { &dib0700_usb_id_table[21], NULL },
-                               { NULL },
-                       }
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .frontend_attach  = bristol_frontend_attach,
-                               .tuner_attach     = bristol_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                       }, {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .frontend_attach  = bristol_frontend_attach,
-                               .tuner_attach     = bristol_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                       }
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "Hauppauge Nova-T 500 Dual DVB-T",
-                               { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7700d_frontend_attach,
-                               .tuner_attach     = stk7700d_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                       }, {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7700d_frontend_attach,
-                               .tuner_attach     = stk7700d_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                       }
-               },
-
-               .num_device_descs = 5,
-               .devices = {
-                       {   "Pinnacle PCTV 2000e",
-                               { &dib0700_usb_id_table[11], NULL },
-                               { NULL },
-                       },
-                       {   "Terratec Cinergy DT XS Diversity",
-                               { &dib0700_usb_id_table[12], NULL },
-                               { NULL },
-                       },
-                       {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
-                               { &dib0700_usb_id_table[13], NULL },
-                               { NULL },
-                       },
-                       {   "DiBcom STK7700D reference design",
-                               { &dib0700_usb_id_table[14], NULL },
-                               { NULL },
-                       },
-                       {   "YUAN High-Tech DiBcom STK7700D",
-                               { &dib0700_usb_id_table[55], NULL },
-                               { NULL },
-                       },
-
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7700P2_frontend_attach,
-                               .tuner_attach     = stk7700d_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                       },
-               },
-
-               .num_device_descs = 3,
-               .devices = {
-                       {   "ASUS My Cinema U3000 Mini DVBT Tuner",
-                               { &dib0700_usb_id_table[23], NULL },
-                               { NULL },
-                       },
-                       {   "Yuan EC372S",
-                               { &dib0700_usb_id_table[31], NULL },
-                               { NULL },
-                       },
-                       {   "Terratec Cinergy T Express",
-                               { &dib0700_usb_id_table[42], NULL },
-                               { NULL },
-                       }
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070p_frontend_attach,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 12,
-               .devices = {
-                       {   "DiBcom STK7070P reference design",
-                               { &dib0700_usb_id_table[15], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV DVB-T Flash Stick",
-                               { &dib0700_usb_id_table[16], NULL },
-                               { NULL },
-                       },
-                       {   "Artec T14BR DVB-T",
-                               { &dib0700_usb_id_table[22], NULL },
-                               { NULL },
-                       },
-                       {   "ASUS My Cinema U3100 Mini DVBT Tuner",
-                               { &dib0700_usb_id_table[24], NULL },
-                               { NULL },
-                       },
-                       {   "Hauppauge Nova-T Stick",
-                               { &dib0700_usb_id_table[25], NULL },
-                               { NULL },
-                       },
-                       {   "Hauppauge Nova-T MyTV.t",
-                               { &dib0700_usb_id_table[26], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV 72e",
-                               { &dib0700_usb_id_table[29], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV 73e",
-                               { &dib0700_usb_id_table[30], NULL },
-                               { NULL },
-                       },
-                       {   "Elgato EyeTV DTT",
-                               { &dib0700_usb_id_table[49], NULL },
-                               { NULL },
-                       },
-                       {   "Yuan PD378S",
-                               { &dib0700_usb_id_table[45], NULL },
-                               { NULL },
-                       },
-                       {   "Elgato EyeTV Dtt Dlx PD378S",
-                               { &dib0700_usb_id_table[50], NULL },
-                               { NULL },
-                       },
-                       {   "Elgato EyeTV DTT rev. 2",
-                               { &dib0700_usb_id_table[81], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070p_frontend_attach,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 3,
-               .devices = {
-                       {   "Pinnacle PCTV 73A",
-                               { &dib0700_usb_id_table[56], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV 73e SE",
-                               { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV 282e",
-                               { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = novatd_frontend_attach,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }, {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = novatd_frontend_attach,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "Hauppauge Nova-TD Stick (52009)",
-                               { &dib0700_usb_id_table[35], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070pd_frontend_attach0,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }, {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070pd_frontend_attach1,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }
-               },
-
-               .num_device_descs = 5,
-               .devices = {
-                       {   "DiBcom STK7070PD reference design",
-                               { &dib0700_usb_id_table[17], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
-                               { &dib0700_usb_id_table[18], NULL },
-                               { NULL },
-                       },
-                       {   "Hauppauge Nova-TD-500 (84xxx)",
-                               { &dib0700_usb_id_table[36], NULL },
-                               { NULL },
-                       },
-                       {  "Terratec Cinergy DT USB XS Diversity/ T5",
-                               { &dib0700_usb_id_table[43],
-                                       &dib0700_usb_id_table[53], NULL},
-                               { NULL },
-                       },
-                       {  "Sony PlayTV",
-                               { &dib0700_usb_id_table[44], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070pd_frontend_attach0,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }, {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7070pd_frontend_attach1,
-                               .tuner_attach     = dib7070p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
-                       }
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "Elgato EyeTV Diversity",
-                               { &dib0700_usb_id_table[68], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7700ph_frontend_attach,
-                               .tuner_attach     = stk7700ph_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv = sizeof(struct
-                                               dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 9,
-               .devices = {
-                       {   "Terratec Cinergy HT USB XE",
-                               { &dib0700_usb_id_table[27], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle Expresscard 320cx",
-                               { &dib0700_usb_id_table[28], NULL },
-                               { NULL },
-                       },
-                       {   "Terratec Cinergy HT Express",
-                               { &dib0700_usb_id_table[32], NULL },
-                               { NULL },
-                       },
-                       {   "Gigabyte U8000-RH",
-                               { &dib0700_usb_id_table[37], NULL },
-                               { NULL },
-                       },
-                       {   "YUAN High-Tech STK7700PH",
-                               { &dib0700_usb_id_table[38], NULL },
-                               { NULL },
-                       },
-                       {   "Asus My Cinema-U3000Hybrid",
-                               { &dib0700_usb_id_table[39], NULL },
-                               { NULL },
-                       },
-                       {   "YUAN High-Tech MC770",
-                               { &dib0700_usb_id_table[48], NULL },
-                               { NULL },
-                       },
-                       {   "Leadtek WinFast DTV Dongle H",
-                               { &dib0700_usb_id_table[51], NULL },
-                               { NULL },
-                       },
-                       {   "YUAN High-Tech STK7700D",
-                               { &dib0700_usb_id_table[54], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .frontend_attach  = s5h1411_frontend_attach,
-                               .tuner_attach     = xc5000_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv = sizeof(struct
-                                               dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 2,
-               .devices = {
-                       {   "Pinnacle PCTV HD Pro USB Stick",
-                               { &dib0700_usb_id_table[40], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV HD USB Stick",
-                               { &dib0700_usb_id_table[41], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .frontend_attach  = lgdt3305_frontend_attach,
-                               .tuner_attach     = mxl5007t_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv = sizeof(struct
-                                               dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 2,
-               .devices = {
-                       {   "Hauppauge ATSC MiniCard (B200)",
-                               { &dib0700_usb_id_table[46], NULL },
-                               { NULL },
-                       },
-                       {   "Hauppauge ATSC MiniCard (B210)",
-                               { &dib0700_usb_id_table[47], NULL },
-                               { NULL },
-                       },
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter       = stk70x0p_pid_filter,
-                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = stk7770p_frontend_attach,
-                               .tuner_attach     = dib7770p_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 4,
-               .devices = {
-                       {   "DiBcom STK7770P reference design",
-                               { &dib0700_usb_id_table[59], NULL },
-                               { NULL },
-                       },
-                       {   "Terratec Cinergy T USB XXS (HD)/ T3",
-                               { &dib0700_usb_id_table[33],
-                                       &dib0700_usb_id_table[52],
-                                       &dib0700_usb_id_table[60], NULL},
-                               { NULL },
-                       },
-                       {   "TechniSat AirStar TeleStick 2",
-                               { &dib0700_usb_id_table[74], NULL },
-                               { NULL },
-                       },
-                       {   "Medion CTX1921 DVB-T USB",
-                               { &dib0700_usb_id_table[75], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk80xx_pid_filter,
-                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                               .frontend_attach  = stk807x_frontend_attach,
-                               .tuner_attach     = dib807x_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 3,
-               .devices = {
-                       {   "DiBcom STK807xP reference design",
-                               { &dib0700_usb_id_table[62], NULL },
-                               { NULL },
-                       },
-                       {   "Prolink Pixelview SBTVD",
-                               { &dib0700_usb_id_table[63], NULL },
-                               { NULL },
-                       },
-                       {   "EvolutePC TVWay+",
-                               { &dib0700_usb_id_table[64], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk80xx_pid_filter,
-                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                               .frontend_attach  = stk807xpvr_frontend_attach0,
-                               .tuner_attach     = dib807x_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk80xx_pid_filter,
-                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                               .frontend_attach  = stk807xpvr_frontend_attach1,
-                               .tuner_attach     = dib807x_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom STK807xPVR reference design",
-                               { &dib0700_usb_id_table[61], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk80xx_pid_filter,
-                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                               .frontend_attach  = stk809x_frontend_attach,
-                               .tuner_attach     = dib809x_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom STK8096GP reference design",
-                               { &dib0700_usb_id_table[67], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = dib90x0_pid_filter,
-                               .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
-                               .frontend_attach  = stk9090m_frontend_attach,
-                               .tuner_attach     = dib9090_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom STK9090M reference design",
-                               { &dib0700_usb_id_table[69], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk80xx_pid_filter,
-                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                               .frontend_attach  = nim8096md_frontend_attach,
-                               .tuner_attach     = nim8096md_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom NIM8096MD reference design",
-                               { &dib0700_usb_id_table[70], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = dib90x0_pid_filter,
-                               .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
-                               .frontend_attach  = nim9090md_frontend_attach,
-                               .tuner_attach     = nim9090md_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom NIM9090MD reference design",
-                               { &dib0700_usb_id_table[71], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk70x0p_pid_filter,
-                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = nim7090_frontend_attach,
-                               .tuner_attach     = nim7090_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom NIM7090 reference design",
-                               { &dib0700_usb_id_table[72], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 2,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk70x0p_pid_filter,
-                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = tfe7090pvr_frontend0_attach,
-                               .tuner_attach     = tfe7090pvr_tuner0_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                               .pid_filter_count = 32,
-                               .pid_filter = stk70x0p_pid_filter,
-                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
-                               .frontend_attach  = tfe7090pvr_frontend1_attach,
-                               .tuner_attach     = tfe7090pvr_tuner1_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom TFE7090PVR reference design",
-                               { &dib0700_usb_id_table[73], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                       .num_frontends = 1,
-                       .fe = {{
-                               .frontend_attach  = pctv340e_frontend_attach,
-                               .tuner_attach     = xc4000_tuner_attach,
-
-                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                       }},
-                               .size_of_priv = sizeof(struct
-                                               dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 2,
-               .devices = {
-                       {   "Pinnacle PCTV 340e HD Pro USB Stick",
-                               { &dib0700_usb_id_table[76], NULL },
-                               { NULL },
-                       },
-                       {   "Pinnacle PCTV Hybrid Stick Solo",
-                               { &dib0700_usb_id_table[77], NULL },
-                               { NULL },
-                       },
-               },
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                               .num_frontends = 1,
-                               .fe = {{
-                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                                       .pid_filter_count = 32,
-                                       .pid_filter = stk70x0p_pid_filter,
-                                       .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
-                                       .frontend_attach  = tfe7090e_frontend_attach,
-                                       .tuner_attach     = tfe7090e_tuner_attach,
-
-                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-                               } },
-
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom TFE7090E reference design",
-                               { &dib0700_usb_id_table[78], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                               .num_frontends = 1,
-                               .fe = {{
-                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                                       .pid_filter_count = 32,
-                                       .pid_filter = stk70x0p_pid_filter,
-                                       .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
-                                       .frontend_attach  = tfe7790e_frontend_attach,
-                                       .tuner_attach     = tfe7790e_tuner_attach,
-
-                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
-                               } },
-
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom TFE7790E reference design",
-                               { &dib0700_usb_id_table[79], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
-               .num_adapters = 1,
-               .adapter = {
-                       {
-                               .num_frontends = 1,
-                               .fe = {{
-                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
-                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                                       .pid_filter_count = 32,
-                                       .pid_filter = stk80xx_pid_filter,
-                                       .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
-                                       .frontend_attach  = tfe8096p_frontend_attach,
-                                       .tuner_attach     = tfe8096p_tuner_attach,
-
-                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
-
-                               } },
-
-                               .size_of_priv =
-                                       sizeof(struct dib0700_adapter_state),
-                       },
-               },
-
-               .num_device_descs = 1,
-               .devices = {
-                       {   "DiBcom TFE8096P reference design",
-                               { &dib0700_usb_id_table[80], NULL },
-                               { NULL },
-                       },
-               },
-
-               .rc.core = {
-                       .rc_interval      = DEFAULT_RC_INTERVAL,
-                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
-                       .module_name      = "dib0700",
-                       .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
-                       .change_protocol  = dib0700_change_protocol,
-               },
-       },
-};
-
-int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/dvb/dvb-usb/dib07x0.h
deleted file mode 100644 (file)
index 7e62c10..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _DIB07X0_H_
-#define _DIB07X0_H_
-
-enum dib07x0_gpios {
-       GPIO0  =  0,
-       GPIO1  =  2,
-       GPIO2  =  3,
-       GPIO3  =  4,
-       GPIO4  =  5,
-       GPIO5  =  6,
-       GPIO6  =  8,
-       GPIO7  = 10,
-       GPIO8  = 11,
-       GPIO9  = 14,
-       GPIO10 = 15,
-};
-
-#define GPIO_IN  0
-#define GPIO_OUT 1
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
deleted file mode 100644 (file)
index a76bbb2..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/* Common methods for dibusb-based-receivers.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
-MODULE_LICENSE("GPL");
-
-#define deb_info(args...) dprintk(debug,0x01,args)
-
-/* common stuff used by the different dibusb modules */
-int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       if (adap->priv != NULL) {
-               struct dibusb_state *st = adap->priv;
-               if (st->ops.fifo_ctrl != NULL)
-                       if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) {
-                               err("error while controlling the fifo of the demod.");
-                               return -ENODEV;
-                       }
-       }
-       return 0;
-}
-EXPORT_SYMBOL(dibusb_streaming_ctrl);
-
-int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
-{
-       if (adap->priv != NULL) {
-               struct dibusb_state *st = adap->priv;
-               if (st->ops.pid_ctrl != NULL)
-                       st->ops.pid_ctrl(adap->fe_adap[0].fe,
-                                        index, pid, onoff);
-       }
-       return 0;
-}
-EXPORT_SYMBOL(dibusb_pid_filter);
-
-int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       if (adap->priv != NULL) {
-               struct dibusb_state *st = adap->priv;
-               if (st->ops.pid_parse != NULL)
-                       if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0)
-                               err("could not handle pid_parser");
-       }
-       return 0;
-}
-EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
-
-int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 b[3];
-       int ret;
-       b[0] = DIBUSB_REQ_SET_IOCTL;
-       b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
-       b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
-       ret = dvb_usb_generic_write(d,b,3);
-       msleep(10);
-       return ret;
-}
-EXPORT_SYMBOL(dibusb_power_ctrl);
-
-int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       u8 b[3] = { 0 };
-       int ret;
-
-       if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
-               return ret;
-
-       if (onoff) {
-               b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
-               b[1] = 0x00;
-               if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
-                       return ret;
-       }
-
-       b[0] = DIBUSB_REQ_SET_IOCTL;
-       b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
-       return dvb_usb_generic_write(adap->dev,b,3);
-}
-EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
-
-int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       if (onoff) {
-               u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
-               return dvb_usb_generic_write(d,b,3);
-       } else
-               return 0;
-}
-EXPORT_SYMBOL(dibusb2_0_power_ctrl);
-
-static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
-       /* write only ? */
-       int wo = (rbuf == NULL || rlen == 0),
-               len = 2 + wlen + (wo ? 0 : 2);
-
-       sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
-       sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
-
-       memcpy(&sndbuf[2],wbuf,wlen);
-
-       if (!wo) {
-               sndbuf[wlen+2] = (rlen >> 8) & 0xff;
-               sndbuf[wlen+3] = rlen & 0xff;
-       }
-
-       return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
-}
-
-/*
- * I2C master xfer function
- */
-static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
-                                         && (msg[i+1].flags & I2C_M_RD)) {
-                       if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
-                                               msg[i+1].buf,msg[i+1].len) < 0)
-                               break;
-                       i++;
-               } else if ((msg[i].flags & I2C_M_RD) == 0) {
-                       if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
-                               break;
-               } else if (msg[i].addr != 0x50) {
-                       /* 0x50 is the address of the eeprom - we need to protect it
-                        * from dibusb's bad i2c implementation: reads without
-                        * writing the offset before are forbidden */
-                       if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
-                               break;
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-struct i2c_algorithm dibusb_i2c_algo = {
-       .master_xfer   = dibusb_i2c_xfer,
-       .functionality = dibusb_i2c_func,
-};
-EXPORT_SYMBOL(dibusb_i2c_algo);
-
-int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
-{
-       u8 wbuf[1] = { offs };
-       return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
-}
-EXPORT_SYMBOL(dibusb_read_eeprom_byte);
-
-/* 3000MC/P stuff */
-// Config Adjacent channels  Perf -cal22
-static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
-       .band_caps = BAND_VHF | BAND_UHF,
-       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
-
-       .agc1_max = 48497,
-       .agc1_min = 23593,
-       .agc2_max = 46531,
-       .agc2_min = 24904,
-
-       .agc1_pt1 = 0x65,
-       .agc1_pt2 = 0x69,
-
-       .agc1_slope1 = 0x51,
-       .agc1_slope2 = 0x27,
-
-       .agc2_pt1 = 0,
-       .agc2_pt2 = 0x33,
-
-       .agc2_slope1 = 0x35,
-       .agc2_slope2 = 0x37,
-};
-
-static struct dib3000mc_config stk3000p_dib3000p_config = {
-       &dib3000p_mt2060_agc_config,
-
-       .max_time     = 0x196,
-       .ln_adc_level = 0x1cc7,
-
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_command1 = 1,
-       .agc_command2 = 1,
-};
-
-static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
-       .band_caps = BAND_VHF | BAND_UHF,
-       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
-
-       .agc1_max = 56361,
-       .agc1_min = 22282,
-       .agc2_max = 47841,
-       .agc2_min = 36045,
-
-       .agc1_pt1 = 0x3b,
-       .agc1_pt2 = 0x6b,
-
-       .agc1_slope1 = 0x55,
-       .agc1_slope2 = 0x1d,
-
-       .agc2_pt1 = 0,
-       .agc2_pt2 = 0x0a,
-
-       .agc2_slope1 = 0x95,
-       .agc2_slope2 = 0x1e,
-};
-
-#if defined(CONFIG_DVB_DIB3000MC) ||                                   \
-       (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
-
-static struct dib3000mc_config mod3000p_dib3000p_config = {
-       &dib3000p_panasonic_agc_config,
-
-       .max_time     = 0x51,
-       .ln_adc_level = 0x1cc7,
-
-       .output_mpeg2_in_188_bytes = 1,
-
-       .agc_command1 = 1,
-       .agc_command2 = 1,
-};
-
-int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
-                       adap->dev->udev->descriptor.idProduct ==
-                       USB_PID_LITEON_DVB_T_WARM) {
-               msleep(1000);
-       }
-
-       adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
-                                        &adap->dev->i2c_adap,
-                                        DEFAULT_DIB3000P_I2C_ADDRESS,
-                                        &mod3000p_dib3000p_config);
-       if ((adap->fe_adap[0].fe) == NULL)
-               adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
-                                                &adap->dev->i2c_adap,
-                                                DEFAULT_DIB3000MC_I2C_ADDRESS,
-                                                &mod3000p_dib3000p_config);
-       if ((adap->fe_adap[0].fe) != NULL) {
-               if (adap->priv != NULL) {
-                       struct dibusb_state *st = adap->priv;
-                       st->ops.pid_parse = dib3000mc_pid_parse;
-                       st->ops.pid_ctrl  = dib3000mc_pid_control;
-               }
-               return 0;
-       }
-       return -ENODEV;
-}
-EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
-
-static struct mt2060_config stk3000p_mt2060_config = {
-       0x60
-};
-
-int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dibusb_state *st = adap->priv;
-       u8 a,b;
-       u16 if1 = 1220;
-       struct i2c_adapter *tun_i2c;
-
-       // First IF calibration for Liteon Sticks
-       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
-               adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
-
-               dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
-               dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
-
-               if (a == 0x00)
-                       if1 += b;
-               else if (a == 0x80)
-                       if1 -= b;
-               else
-                       warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
-
-       } else if (adap->dev->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
-                  adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
-               u8 desc;
-               dibusb_read_eeprom_byte(adap->dev, 7, &desc);
-               if (desc == 2) {
-                       a = 127;
-                       do {
-                               dibusb_read_eeprom_byte(adap->dev, a, &desc);
-                               a--;
-                       } while (a > 7 && (desc == 0xff || desc == 0x00));
-                       if (desc & 0x80)
-                               if1 -= (0xff - desc);
-                       else
-                               if1 += desc;
-               }
-       }
-
-       tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
-       if (dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
-               /* not found - use panasonic pll parameters */
-               if (dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL)
-                       return -ENOMEM;
-       } else {
-               st->mt2060_present = 1;
-               /* set the correct parameters for the dib3000p */
-               dib3000mc_set_config(adap->fe_adap[0].fe, &stk3000p_dib3000p_config);
-       }
-       return 0;
-}
-EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
-#endif
-
-/*
- * common remote control stuff
- */
-struct rc_map_table rc_map_dibusb_table[] = {
-       /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
-       { 0x0016, KEY_POWER },
-       { 0x0010, KEY_MUTE },
-       { 0x0003, KEY_1 },
-       { 0x0001, KEY_2 },
-       { 0x0006, KEY_3 },
-       { 0x0009, KEY_4 },
-       { 0x001d, KEY_5 },
-       { 0x001f, KEY_6 },
-       { 0x000d, KEY_7 },
-       { 0x0019, KEY_8 },
-       { 0x001b, KEY_9 },
-       { 0x0015, KEY_0 },
-       { 0x0005, KEY_CHANNELUP },
-       { 0x0002, KEY_CHANNELDOWN },
-       { 0x001e, KEY_VOLUMEUP },
-       { 0x000a, KEY_VOLUMEDOWN },
-       { 0x0011, KEY_RECORD },
-       { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
-       { 0x0014, KEY_PLAY },
-       { 0x001a, KEY_STOP },
-       { 0x0040, KEY_REWIND },
-       { 0x0012, KEY_FASTFORWARD },
-       { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
-       { 0x004c, KEY_PAUSE },
-       { 0x004d, KEY_SCREEN }, /* Full screen mode. */
-       { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
-       /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
-       { 0x000c, KEY_CANCEL }, /* Cancel */
-       { 0x001c, KEY_EPG }, /* EPG */
-       { 0x0000, KEY_TAB }, /* Tab */
-       { 0x0048, KEY_INFO }, /* Preview */
-       { 0x0004, KEY_LIST }, /* RecordList */
-       { 0x000f, KEY_TEXT }, /* Teletext */
-       /* Key codes for the KWorld/ADSTech/JetWay remote. */
-       { 0x8612, KEY_POWER },
-       { 0x860f, KEY_SELECT }, /* source */
-       { 0x860c, KEY_UNKNOWN }, /* scan */
-       { 0x860b, KEY_EPG },
-       { 0x8610, KEY_MUTE },
-       { 0x8601, KEY_1 },
-       { 0x8602, KEY_2 },
-       { 0x8603, KEY_3 },
-       { 0x8604, KEY_4 },
-       { 0x8605, KEY_5 },
-       { 0x8606, KEY_6 },
-       { 0x8607, KEY_7 },
-       { 0x8608, KEY_8 },
-       { 0x8609, KEY_9 },
-       { 0x860a, KEY_0 },
-       { 0x8618, KEY_ZOOM },
-       { 0x861c, KEY_UNKNOWN }, /* preview */
-       { 0x8613, KEY_UNKNOWN }, /* snap */
-       { 0x8600, KEY_UNDO },
-       { 0x861d, KEY_RECORD },
-       { 0x860d, KEY_STOP },
-       { 0x860e, KEY_PAUSE },
-       { 0x8616, KEY_PLAY },
-       { 0x8611, KEY_BACK },
-       { 0x8619, KEY_FORWARD },
-       { 0x8614, KEY_UNKNOWN }, /* pip */
-       { 0x8615, KEY_ESC },
-       { 0x861a, KEY_UP },
-       { 0x861e, KEY_DOWN },
-       { 0x861f, KEY_LEFT },
-       { 0x861b, KEY_RIGHT },
-
-       /* Key codes for the DiBcom MOD3000 remote. */
-       { 0x8000, KEY_MUTE },
-       { 0x8001, KEY_TEXT },
-       { 0x8002, KEY_HOME },
-       { 0x8003, KEY_POWER },
-
-       { 0x8004, KEY_RED },
-       { 0x8005, KEY_GREEN },
-       { 0x8006, KEY_YELLOW },
-       { 0x8007, KEY_BLUE },
-
-       { 0x8008, KEY_DVD },
-       { 0x8009, KEY_AUDIO },
-       { 0x800a, KEY_IMAGES },      /* Pictures */
-       { 0x800b, KEY_VIDEO },
-
-       { 0x800c, KEY_BACK },
-       { 0x800d, KEY_UP },
-       { 0x800e, KEY_RADIO },
-       { 0x800f, KEY_EPG },
-
-       { 0x8010, KEY_LEFT },
-       { 0x8011, KEY_OK },
-       { 0x8012, KEY_RIGHT },
-       { 0x8013, KEY_UNKNOWN },    /* SAP */
-
-       { 0x8014, KEY_TV },
-       { 0x8015, KEY_DOWN },
-       { 0x8016, KEY_MENU },       /* DVD Menu */
-       { 0x8017, KEY_LAST },
-
-       { 0x8018, KEY_RECORD },
-       { 0x8019, KEY_STOP },
-       { 0x801a, KEY_PAUSE },
-       { 0x801b, KEY_PLAY },
-
-       { 0x801c, KEY_PREVIOUS },
-       { 0x801d, KEY_REWIND },
-       { 0x801e, KEY_FASTFORWARD },
-       { 0x801f, KEY_NEXT},
-
-       { 0x8040, KEY_1 },
-       { 0x8041, KEY_2 },
-       { 0x8042, KEY_3 },
-       { 0x8043, KEY_CHANNELUP },
-
-       { 0x8044, KEY_4 },
-       { 0x8045, KEY_5 },
-       { 0x8046, KEY_6 },
-       { 0x8047, KEY_CHANNELDOWN },
-
-       { 0x8048, KEY_7 },
-       { 0x8049, KEY_8 },
-       { 0x804a, KEY_9 },
-       { 0x804b, KEY_VOLUMEUP },
-
-       { 0x804c, KEY_CLEAR },
-       { 0x804d, KEY_0 },
-       { 0x804e, KEY_ENTER },
-       { 0x804f, KEY_VOLUMEDOWN },
-};
-EXPORT_SYMBOL(rc_map_dibusb_table);
-
-int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
-       dvb_usb_generic_rw(d,&cmd,1,key,5,0);
-       dvb_usb_nec_rc_key_to_event(d,key,event,state);
-       if (key[0] != 0)
-               deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
-       return 0;
-}
-EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
deleted file mode 100644 (file)
index a4ac37e..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
- * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dibusb_state *st = adap->priv;
-
-       return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
-}
-
-static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dib3000_config demod_cfg;
-       struct dibusb_state *st = adap->priv;
-
-       demod_cfg.demod_address = 0x8;
-
-       adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
-                                        &adap->dev->i2c_adap, &st->ops);
-       if ((adap->fe_adap[0].fe) == NULL)
-               return -ENODEV;
-
-       adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
-
-       return 0;
-}
-
-static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dibusb_state *st = adap->priv;
-
-       st->tuner_addr = 0x61;
-
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
-                  DVB_PLL_TUA6010XS);
-       return 0;
-}
-
-static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct dibusb_state *st = adap->priv;
-
-       st->tuner_addr = 0x60;
-
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
-                  DVB_PLL_TDA665X);
-       return 0;
-}
-
-/* Some of the Artec 1.1 device aren't equipped with the default tuner
- * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
- * this out. */
-static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
-{
-       u8 b[2] = { 0,0 }, b2[1];
-       int ret = 0;
-       struct i2c_msg msg[2] = {
-               { .flags = 0,        .buf = b,  .len = 2 },
-               { .flags = I2C_M_RD, .buf = b2, .len = 1 },
-       };
-       struct dibusb_state *st = adap->priv;
-
-       /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
-       msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
-
-       if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
-               adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
-
-       if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
-               err("tuner i2c write failed.");
-               ret = -EREMOTEIO;
-       }
-
-       if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
-               adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
-
-       if (b2[0] == 0xfe) {
-               info("This device has the Thomson Cable onboard. Which is default.");
-               ret = dibusb_thomson_tuner_attach(adap);
-       } else {
-               info("This device has the Panasonic ENV77H11D5 onboard.");
-               ret = dibusb_panasonic_tuner_attach(adap);
-       }
-
-       return ret;
-}
-
-/* USB Driver stuff */
-static struct dvb_usb_device_properties dibusb1_1_properties;
-static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
-static struct dvb_usb_device_properties dibusb2_0b_properties;
-static struct dvb_usb_device_properties artec_t1_usb2_properties;
-
-static int dibusb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-
-       return -EINVAL;
-}
-
-/* do not change the order of the ID table */
-static struct usb_device_id dibusb_dib3000mb_table [] = {
-/* 00 */       { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_COLD) },
-/* 01 */       { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_WARM) },
-/* 02 */       { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_COLD) },
-/* 03 */       { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_WARM) },
-/* 04 */       { USB_DEVICE(USB_VID_COMPRO_UNK,        USB_PID_COMPRO_DVBU2000_UNK_COLD) },
-/* 05 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_COLD) },
-/* 06 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_WARM) },
-/* 07 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_COLD) },
-/* 08 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_WARM) },
-/* 09 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_COLD) },
-/* 10 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_WARM) },
-/* 11 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_COLD) },
-/* 12 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_WARM) },
-/* 13 */       { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_COLD) },
-/* 14 */       { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_WARM) },
-/* 15 */       { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_COLD) },
-/* 16 */       { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_WARM) },
-/* 17 */       { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_COLD) },
-/* 18 */       { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_WARM) },
-/* 19 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-/* 20 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-/* 21 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-/* 22 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
-/* 23 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_COLD) },
-
-/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
-/* 24 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_WARM) },
-/* 25 */       { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_COLD) },
-/* 26 */       { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_WARM) },
-
-/* 27 */       { USB_DEVICE(USB_VID_KWORLD,            USB_PID_KWORLD_VSTREAM_COLD) },
-
-/* 28 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
-/* 29 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
-
-/*
- * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
- *      we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
- *      have been left on the device. If you don't have such a device but an Artec
- *      device that's supposed to work with this driver but is not detected by it,
- *      free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
- */
-
-#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
-/* 30 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-#endif
-
-                       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
-
-static struct dvb_usb_device_properties dibusb1_1_properties = {
-       .caps =  DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_AN2135,
-
-       .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 16,
-
-                       .streaming_ctrl   = dibusb_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
-                       .tuner_attach     = dibusb_tuner_probe_and_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-
-       .power_ctrl       = dibusb_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_dibusb_table,
-               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-               .rc_query         = dibusb_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 9,
-       .devices = {
-               {       "AVerMedia AverTV DVBT USB1.1",
-                       { &dibusb_dib3000mb_table[0],  NULL },
-                       { &dibusb_dib3000mb_table[1],  NULL },
-               },
-               {       "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
-                       { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
-                       { &dibusb_dib3000mb_table[3], NULL },
-               },
-               {       "DiBcom USB1.1 DVB-T reference design (MOD3000)",
-                       { &dibusb_dib3000mb_table[5],  NULL },
-                       { &dibusb_dib3000mb_table[6],  NULL },
-               },
-               {       "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
-                       { &dibusb_dib3000mb_table[7], NULL },
-                       { &dibusb_dib3000mb_table[8], NULL },
-               },
-               {       "Grandtec USB1.1 DVB-T",
-                       { &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
-                       { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
-               },
-               {       "Unknown USB1.1 DVB-T device ???? please report the name to the author",
-                       { &dibusb_dib3000mb_table[13], NULL },
-                       { &dibusb_dib3000mb_table[14], NULL },
-               },
-               {       "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
-                       { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
-                       { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
-               },
-               {       "Artec T1 USB1.1 TVBOX with AN2135",
-                       { &dibusb_dib3000mb_table[19], NULL },
-                       { &dibusb_dib3000mb_table[20], NULL },
-               },
-               {       "VideoWalker DVB-T USB",
-                       { &dibusb_dib3000mb_table[25], NULL },
-                       { &dibusb_dib3000mb_table[26], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = CYPRESS_AN2235,
-
-       .firmware = "dvb-usb-dibusb-an2235-01.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
-                       .pid_filter_count = 16,
-
-                       .streaming_ctrl   = dibusb_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
-                       .tuner_attach     = dibusb_tuner_probe_and_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               },
-       },
-       .power_ctrl       = dibusb_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_dibusb_table,
-               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-               .rc_query         = dibusb_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
-       .num_device_descs = 2,
-#else
-       .num_device_descs = 1,
-#endif
-       .devices = {
-               {       "Artec T1 USB1.1 TVBOX with AN2235",
-                       { &dibusb_dib3000mb_table[21], NULL },
-                       { &dibusb_dib3000mb_table[22], NULL },
-               },
-#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
-               {       "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
-                       { &dibusb_dib3000mb_table[30], NULL },
-                       { NULL },
-               },
-               { NULL },
-#endif
-       }
-};
-
-static struct dvb_usb_device_properties dibusb2_0b_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-
-       .firmware = "dvb-usb-adstech-usb2-02.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 16,
-
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
-                       .tuner_attach     = dibusb_thomson_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-       .power_ctrl       = dibusb2_0_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_dibusb_table,
-               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-               .rc_query         = dibusb_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 2,
-       .devices = {
-               {       "KWorld/ADSTech Instant DVB-T USB2.0",
-                       { &dibusb_dib3000mb_table[23], NULL },
-                       { &dibusb_dib3000mb_table[24], NULL },
-               },
-               {       "KWorld Xpert DVB-T USB2.0",
-                       { &dibusb_dib3000mb_table[27], NULL },
-                       { NULL }
-               },
-               { NULL },
-       }
-};
-
-static struct dvb_usb_device_properties artec_t1_usb2_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-
-       .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 16,
-
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
-                       .tuner_attach     = dibusb_tuner_probe_and_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-       .power_ctrl       = dibusb2_0_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_dibusb_table,
-               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-               .rc_query         = dibusb_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {       "Artec T1 USB2.0",
-                       { &dibusb_dib3000mb_table[28], NULL },
-                       { &dibusb_dib3000mb_table[29], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct usb_driver dibusb_driver = {
-       .name           = "dvb_usb_dibusb_mb",
-       .probe          = dibusb_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = dibusb_dib3000mb_table,
-};
-
-module_usb_driver(dibusb_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
deleted file mode 100644 (file)
index 9d1a59d..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
- * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/* USB Driver stuff */
-static struct dvb_usb_device_properties dibusb_mc_properties;
-
-static int dibusb_mc_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE,
-                                  NULL, adapter_nr);
-}
-
-/* do not change the order of the ID table */
-static struct usb_device_id dibusb_dib3000mc_table [] = {
-/* 00 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3001_COLD) },
-/* 01 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3001_WARM) },
-/* 02 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
-/* 03 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
-/* 04 */       { USB_DEVICE(USB_VID_LITEON,            USB_PID_LITEON_DVB_T_COLD) },
-/* 05 */       { USB_DEVICE(USB_VID_LITEON,            USB_PID_LITEON_DVB_T_WARM) },
-/* 06 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_DIGIVOX_MINI_SL_COLD) },
-/* 07 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_DIGIVOX_MINI_SL_WARM) },
-/* 08 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB2_COLD) },
-/* 09 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB2_WARM) },
-/* 10 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
-/* 11 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
-/* 12 */       { USB_DEVICE(USB_VID_LEADTEK,           USB_PID_WINFAST_DTV_DONGLE_COLD) },
-/* 13 */       { USB_DEVICE(USB_VID_LEADTEK,           USB_PID_WINFAST_DTV_DONGLE_WARM) },
-/* 14 */       { USB_DEVICE(USB_VID_HUMAX_COEX,        USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
-/* 15 */       { USB_DEVICE(USB_VID_HUMAX_COEX,        USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
-                       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
-
-static struct dvb_usb_device_properties dibusb_mc_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
-                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
-
-       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-       .power_ctrl       = dibusb2_0_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval      = DEFAULT_RC_INTERVAL,
-               .rc_map_table     = rc_map_dibusb_table,
-               .rc_map_size      = 111, /* FIXME */
-               .rc_query         = dibusb_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 8,
-       .devices = {
-               {   "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
-                       { &dibusb_dib3000mc_table[0], NULL },
-                       { &dibusb_dib3000mc_table[1], NULL },
-               },
-               {   "Artec T1 USB2.0 TVBOX (please check the warm ID)",
-                       { &dibusb_dib3000mc_table[2], NULL },
-                       { &dibusb_dib3000mc_table[3], NULL },
-               },
-               {   "LITE-ON USB2.0 DVB-T Tuner",
-                   /* Also rebranded as Intuix S800, Toshiba */
-                       { &dibusb_dib3000mc_table[4], NULL },
-                       { &dibusb_dib3000mc_table[5], NULL },
-               },
-               {   "MSI Digivox Mini SL",
-                       { &dibusb_dib3000mc_table[6], NULL },
-                       { &dibusb_dib3000mc_table[7], NULL },
-               },
-               {   "GRAND - USB2.0 DVB-T adapter",
-                       { &dibusb_dib3000mc_table[8], NULL },
-                       { &dibusb_dib3000mc_table[9], NULL },
-               },
-               {   "Artec T14 - USB2.0 DVB-T",
-                       { &dibusb_dib3000mc_table[10], NULL },
-                       { &dibusb_dib3000mc_table[11], NULL },
-               },
-               {   "Leadtek - USB2.0 Winfast DTV dongle",
-                       { &dibusb_dib3000mc_table[12], NULL },
-                       { &dibusb_dib3000mc_table[13], NULL },
-               },
-               {   "Humax/Coex DVB-T USB Stick 2.0 High Speed",
-                       { &dibusb_dib3000mc_table[14], NULL },
-                       { &dibusb_dib3000mc_table[15], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct usb_driver dibusb_mc_driver = {
-       .name           = "dvb_usb_dibusb_mc",
-       .probe          = dibusb_mc_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = dibusb_dib3000mc_table,
-};
-
-module_usb_driver(dibusb_mc_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
deleted file mode 100644 (file)
index e47c321..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Header file for all dibusb-based-receivers.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_DIBUSB_H_
-#define _DVB_USB_DIBUSB_H_
-
-#ifndef DVB_USB_LOG_PREFIX
- #define DVB_USB_LOG_PREFIX "dibusb"
-#endif
-#include "dvb-usb.h"
-
-#include "dib3000.h"
-#include "dib3000mc.h"
-#include "mt2060.h"
-
-/*
- * protocol of all dibusb related devices
- */
-
-/*
- * bulk msg to/from endpoint 0x01
- *
- * general structure:
- * request_byte parameter_bytes
- */
-
-#define DIBUSB_REQ_START_READ                  0x00
-#define DIBUSB_REQ_START_DEMOD                 0x01
-
-/*
- * i2c read
- * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
- * bulk read:  byte_buffer (length_word bytes)
- */
-#define DIBUSB_REQ_I2C_READ                    0x02
-
-/*
- * i2c write
- * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
- */
-#define DIBUSB_REQ_I2C_WRITE                   0x03
-
-/*
- * polling the value of the remote control
- * bulk write: 0x04
- * bulk read:  byte_buffer (5 bytes)
- */
-#define DIBUSB_REQ_POLL_REMOTE       0x04
-
-/* additional status values for Hauppauge Remote Control Protocol */
-#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED        0x01
-#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY  0x03
-
-/* streaming mode:
- * bulk write: 0x05 mode_byte
- *
- * mode_byte is mostly 0x00
- */
-#define DIBUSB_REQ_SET_STREAMING_MODE  0x05
-
-/* interrupt the internal read loop, when blocking */
-#define DIBUSB_REQ_INTR_READ                   0x06
-
-/* io control
- * 0x07 cmd_byte param_bytes
- *
- * param_bytes can be up to 32 bytes
- *
- * cmd_byte function    parameter name
- * 0x00     power mode
- *                      0x00      sleep
- *                      0x01      wakeup
- *
- * 0x01     enable streaming
- * 0x02     disable streaming
- *
- *
- */
-#define DIBUSB_REQ_SET_IOCTL                   0x07
-
-/* IOCTL commands */
-
-/* change the power mode in firmware */
-#define DIBUSB_IOCTL_CMD_POWER_MODE            0x00
-#define DIBUSB_IOCTL_POWER_SLEEP                       0x00
-#define DIBUSB_IOCTL_POWER_WAKEUP                      0x01
-
-/* modify streaming of the FX2 */
-#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
-#define DIBUSB_IOCTL_CMD_DISABLE_STREAM        0x02
-
-struct dibusb_state {
-       struct dib_fe_xfer_ops ops;
-       int mt2060_present;
-       u8 tuner_addr;
-};
-
-struct dibusb_device_state {
-       /* for RC5 remote control */
-       int old_toggle;
-       int last_repeat_count;
-};
-
-extern struct i2c_algorithm dibusb_i2c_algo;
-
-extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
-extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
-
-extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
-extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
-extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
-extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
-
-extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
-extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
-
-#define DEFAULT_RC_INTERVAL 150
-//#define DEFAULT_RC_INTERVAL 100000
-
-extern struct rc_map_table rc_map_dibusb_table[];
-extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
-extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
deleted file mode 100644 (file)
index ff34419..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
- * receiver
- *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * partly based on the SDK published by Nebula Electronics
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "digitv.h"
-
-#include "mt352.h"
-#include "nxt6000.h"
-
-/* debug */
-static int dvb_usb_digitv_debug;
-module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_rc(args...)   dprintk(dvb_usb_digitv_debug,0x01,args)
-
-static int digitv_ctrl_msg(struct dvb_usb_device *d,
-               u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       int wo = (rbuf == NULL || rlen == 0); /* write-only */
-       u8 sndbuf[7],rcvbuf[7];
-       memset(sndbuf,0,7); memset(rcvbuf,0,7);
-
-       sndbuf[0] = cmd;
-       sndbuf[1] = vv;
-       sndbuf[2] = wo ? wlen : rlen;
-
-       if (wo) {
-               memcpy(&sndbuf[3],wbuf,wlen);
-               dvb_usb_generic_write(d,sndbuf,7);
-       } else {
-               dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
-               memcpy(rbuf,&rcvbuf[3],rlen);
-       }
-       return 0;
-}
-
-/* I2C */
-static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       if (num > 2)
-               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
-                                               msg[i+1].buf,msg[i+1].len) < 0)
-                               break;
-                       i++;
-               } else
-                       if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
-                                               &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 digitv_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm digitv_i2c_algo = {
-       .master_xfer   = digitv_i2c_xfer,
-       .functionality = digitv_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static int digitv_identify_state (struct usb_device *udev, struct
-               dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
-               int *cold)
-{
-       *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
-       return 0;
-}
-
-static int digitv_mt352_demod_init(struct dvb_frontend *fe)
-{
-       static u8 reset_buf[] = { 0x89, 0x38,  0x8a, 0x2d, 0x50, 0x80 };
-       static u8 init_buf[] = { 0x68, 0xa0,  0x8e, 0x40,  0x53, 0x50,
-                       0x67, 0x20,  0x7d, 0x01,  0x7c, 0x00,  0x7a, 0x00,
-                       0x79, 0x20,  0x57, 0x05,  0x56, 0x31,  0x88, 0x0f,
-                       0x75, 0x32 };
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
-               mt352_write(fe, &reset_buf[i], 2);
-
-       msleep(1);
-
-       for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
-               mt352_write(fe, &init_buf[i], 2);
-
-       return 0;
-}
-
-static struct mt352_config digitv_mt352_config = {
-       .demod_init = digitv_mt352_demod_init,
-};
-
-static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       u8 b[5];
-
-       fe->ops.tuner_ops.calc_regs(fe, b, sizeof(b));
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
-}
-
-static struct nxt6000_config digitv_nxt6000_config = {
-       .clock_inversion = 1,
-};
-
-static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct digitv_state *st = adap->dev->priv;
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &digitv_mt352_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL) {
-               st->is_nxt6000 = 0;
-               return 0;
-       }
-       adap->fe_adap[0].fe = dvb_attach(nxt6000_attach,
-                                        &digitv_nxt6000_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) != NULL) {
-               st->is_nxt6000 = 1;
-               return 0;
-       }
-       return -EIO;
-}
-
-static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct digitv_state *st = adap->dev->priv;
-
-       if (!dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_TDED4))
-               return -ENODEV;
-
-       if (st->is_nxt6000)
-               adap->fe_adap[0].fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
-
-       return 0;
-}
-
-static struct rc_map_table rc_map_digitv_table[] = {
-       { 0x5f55, KEY_0 },
-       { 0x6f55, KEY_1 },
-       { 0x9f55, KEY_2 },
-       { 0xaf55, KEY_3 },
-       { 0x5f56, KEY_4 },
-       { 0x6f56, KEY_5 },
-       { 0x9f56, KEY_6 },
-       { 0xaf56, KEY_7 },
-       { 0x5f59, KEY_8 },
-       { 0x6f59, KEY_9 },
-       { 0x9f59, KEY_TV },
-       { 0xaf59, KEY_AUX },
-       { 0x5f5a, KEY_DVD },
-       { 0x6f5a, KEY_POWER },
-       { 0x9f5a, KEY_CAMERA },     /* labelled 'Picture' */
-       { 0xaf5a, KEY_AUDIO },
-       { 0x5f65, KEY_INFO },
-       { 0x6f65, KEY_F13 },     /* 16:9 */
-       { 0x9f65, KEY_F14 },     /* 14:9 */
-       { 0xaf65, KEY_EPG },
-       { 0x5f66, KEY_EXIT },
-       { 0x6f66, KEY_MENU },
-       { 0x9f66, KEY_UP },
-       { 0xaf66, KEY_DOWN },
-       { 0x5f69, KEY_LEFT },
-       { 0x6f69, KEY_RIGHT },
-       { 0x9f69, KEY_ENTER },
-       { 0xaf69, KEY_CHANNELUP },
-       { 0x5f6a, KEY_CHANNELDOWN },
-       { 0x6f6a, KEY_VOLUMEUP },
-       { 0x9f6a, KEY_VOLUMEDOWN },
-       { 0xaf6a, KEY_RED },
-       { 0x5f95, KEY_GREEN },
-       { 0x6f95, KEY_YELLOW },
-       { 0x9f95, KEY_BLUE },
-       { 0xaf95, KEY_SUBTITLE },
-       { 0x5f96, KEY_F15 },     /* AD */
-       { 0x6f96, KEY_TEXT },
-       { 0x9f96, KEY_MUTE },
-       { 0xaf96, KEY_REWIND },
-       { 0x5f99, KEY_STOP },
-       { 0x6f99, KEY_PLAY },
-       { 0x9f99, KEY_FASTFORWARD },
-       { 0xaf99, KEY_F16 },     /* chapter */
-       { 0x5f9a, KEY_PAUSE },
-       { 0x6f9a, KEY_PLAY },
-       { 0x9f9a, KEY_RECORD },
-       { 0xaf9a, KEY_F17 },     /* picture in picture */
-       { 0x5fa5, KEY_KPPLUS },  /* zoom in */
-       { 0x6fa5, KEY_KPMINUS }, /* zoom out */
-       { 0x9fa5, KEY_F18 },     /* capture */
-       { 0xafa5, KEY_F19 },     /* web */
-       { 0x5fa6, KEY_EMAIL },
-       { 0x6fa6, KEY_PHONE },
-       { 0x9fa6, KEY_PC },
-};
-
-static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       int i;
-       u8 key[5];
-       u8 b[4] = { 0 };
-
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
-
-       /* Tell the device we've read the remote. Not sure how necessary
-          this is, but the Nebula SDK does it. */
-       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
-
-       /* if something is inside the buffer, simulate key press */
-       if (key[1] != 0)
-       {
-                 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-                       if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
-                           rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
-                               *event = d->props.rc.legacy.rc_map_table[i].keycode;
-                               *state = REMOTE_KEY_PRESSED;
-                               return 0;
-                       }
-               }
-       }
-
-       if (key[0] != 0)
-               deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
-       return 0;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties digitv_properties;
-
-static int digitv_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct dvb_usb_device *d;
-       int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
-                                     adapter_nr);
-       if (ret == 0) {
-               u8 b[4] = { 0 };
-
-               if (d != NULL) { /* do that only when the firmware is loaded */
-                       b[0] = 1;
-                       digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
-
-                       b[0] = 0;
-                       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
-               }
-       }
-       return ret;
-}
-
-static struct usb_device_id digitv_table [] = {
-               { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
-               { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, digitv_table);
-
-static struct dvb_usb_device_properties digitv_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-digitv-02.fw",
-
-       .size_of_priv = sizeof(struct digitv_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach  = digitv_frontend_attach,
-                       .tuner_attach     = digitv_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .identify_state   = digitv_identify_state,
-
-       .rc.legacy = {
-               .rc_interval      = 1000,
-               .rc_map_table     = rc_map_digitv_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_digitv_table),
-               .rc_query         = digitv_rc_query,
-       },
-
-       .i2c_algo         = &digitv_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Nebula Electronics uDigiTV DVB-T USB2.0)",
-                       { &digitv_table[0], NULL },
-                       { NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct usb_driver digitv_driver = {
-       .name           = "dvb_usb_digitv",
-       .probe          = digitv_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = digitv_table,
-};
-
-module_usb_driver(digitv_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
-MODULE_VERSION("1.0-alpha");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
deleted file mode 100644 (file)
index 908c09f..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _DVB_USB_DIGITV_H_
-#define _DVB_USB_DIGITV_H_
-
-#define DVB_USB_LOG_PREFIX "digitv"
-#include "dvb-usb.h"
-
-struct digitv_state {
-    int is_nxt6000;
-};
-
-/* protocol (from usblogging and the SDK:
- *
- * Always 7 bytes bulk message(s) for controlling
- *
- * First byte describes the command. Reads are 2 consecutive transfer (as always).
- *
- * General structure:
- *
- * write or first message of a read:
- * <cmdbyte> VV <len> B0 B1 B2 B3
- *
- * second message of a read
- * <cmdbyte> VV <len> R0 R1 R2 R3
- *
- * whereas 0 < len <= 4
- *
- * I2C address is stored somewhere inside the device.
- *
- * 0x01 read from EEPROM
- *  VV = offset; B* = 0; R* = value(s)
- *
- * 0x02 read register of the COFDM
- *  VV = register; B* = 0; R* = value(s)
- *
- * 0x05 write register of the COFDM
- *  VV = register; B* = value(s);
- *
- * 0x06 write to the tuner (only for NXT6000)
- *  VV = 0; B* = PLL data; len = 4;
- *
- * 0x03 read remote control
- *  VV = 0; B* = 0; len = 4; R* = key
- *
- * 0x07 write to the remote (don't know why one should this, resetting ?)
- *  VV = 0; B* = key; len = 4;
- *
- * 0x08 write remote type
- *  VV = 0; B[0] = 0x01, len = 4
- *
- * 0x09 write device init
- *  TODO
- */
-#define USB_READ_EEPROM         1
-
-#define USB_READ_COFDM          2
-#define USB_WRITE_COFDM         5
-
-#define USB_WRITE_TUNER         6
-
-#define USB_READ_REMOTE         3
-#define USB_WRITE_REMOTE        7
-#define USB_WRITE_REMOTE_TYPE   8
-
-#define USB_DEV_INIT            9
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
deleted file mode 100644 (file)
index 3d81daa..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
- * Typhoon/ Yuan DVB-T USB2.0 receiver.
- *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dtt200u.h"
-
-struct dtt200u_fe_state {
-       struct dvb_usb_device *d;
-
-       fe_status_t stat;
-
-       struct dtv_frontend_properties fep;
-       struct dvb_frontend frontend;
-};
-
-static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 st = GET_TUNE_STATUS, b[3];
-
-       dvb_usb_generic_rw(state->d,&st,1,b,3,0);
-
-       switch (b[0]) {
-               case 0x01:
-                       *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-                       break;
-               case 0x00: /* pending */
-                       *stat = FE_TIMEDOUT; /* during set_frontend */
-                       break;
-               default:
-               case 0x02: /* failed */
-                       *stat = 0;
-                       break;
-       }
-       return 0;
-}
-
-static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_VIT_ERR_CNT,b[3];
-       dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
-       *ber = (b[0] << 16) | (b[1] << 8) | b[2];
-       return 0;
-}
-
-static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
-
-       dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
-       *unc = (b[0] << 8) | b[1];
-       return 0;
-}
-
-static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_AGC, b;
-       dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
-       *strength = (b << 8) | b;
-       return 0;
-}
-
-static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 bw = GET_SNR,br;
-       dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
-       *snr = ~((br << 8) | br);
-       return 0;
-}
-
-static int dtt200u_fe_init(struct dvb_frontend* fe)
-{
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       u8 b = SET_INIT;
-       return dvb_usb_generic_write(state->d,&b,1);
-}
-
-static int dtt200u_fe_sleep(struct dvb_frontend* fe)
-{
-       return dtt200u_fe_init(fe);
-}
-
-static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1500;
-       tune->step_size = 0;
-       tune->max_drift = 0;
-       return 0;
-}
-
-static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       int i;
-       fe_status_t st;
-       u16 freq = fep->frequency / 250000;
-       u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
-
-       switch (fep->bandwidth_hz) {
-       case 8000000:
-               bwbuf[1] = 8;
-               break;
-       case 7000000:
-               bwbuf[1] = 7;
-               break;
-       case 6000000:
-               bwbuf[1] = 6;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       dvb_usb_generic_write(state->d,bwbuf,2);
-
-       freqbuf[1] = freq & 0xff;
-       freqbuf[2] = (freq >> 8) & 0xff;
-       dvb_usb_generic_write(state->d,freqbuf,3);
-
-       for (i = 0; i < 30; i++) {
-               msleep(20);
-               dtt200u_fe_read_status(fe, &st);
-               if (st & FE_TIMEDOUT)
-                       continue;
-       }
-
-       return 0;
-}
-
-static int dtt200u_fe_get_frontend(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dtt200u_fe_state *state = fe->demodulator_priv;
-       memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties));
-       return 0;
-}
-
-static void dtt200u_fe_release(struct dvb_frontend* fe)
-{
-       struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops dtt200u_fe_ops;
-
-struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
-{
-       struct dtt200u_fe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       deb_info("attaching frontend dtt200u\n");
-
-       state->d = d;
-
-       memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-error:
-       return NULL;
-}
-
-static struct dvb_frontend_ops dtt200u_fe_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "WideView USB DVB-T",
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 250000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                               FE_CAN_TRANSMISSION_MODE_AUTO |
-                               FE_CAN_GUARD_INTERVAL_AUTO |
-                               FE_CAN_RECOVER |
-                               FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = dtt200u_fe_release,
-
-       .init = dtt200u_fe_init,
-       .sleep = dtt200u_fe_sleep,
-
-       .set_frontend = dtt200u_fe_set_frontend,
-       .get_frontend = dtt200u_fe_get_frontend,
-       .get_tune_settings = dtt200u_fe_get_tune_settings,
-
-       .read_status = dtt200u_fe_read_status,
-       .read_ber = dtt200u_fe_read_ber,
-       .read_signal_strength = dtt200u_fe_read_signal_strength,
-       .read_snr = dtt200u_fe_read_snr,
-       .read_ucblocks = dtt200u_fe_read_unc_blocks,
-};
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
deleted file mode 100644 (file)
index 66f205c..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
- * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * Thanks to Steve Chang from WideView for providing support for the WT-220U.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dtt200u.h"
-
-/* debug */
-int dvb_usb_dtt200u_debug;
-module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 b = SET_INIT;
-
-       if (onoff)
-               dvb_usb_generic_write(d,&b,2);
-
-       return 0;
-}
-
-static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       u8 b_streaming[2] = { SET_STREAMING, onoff };
-       u8 b_rst_pid = RESET_PID_FILTER;
-
-       dvb_usb_generic_write(adap->dev, b_streaming, 2);
-
-       if (onoff == 0)
-               dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
-       return 0;
-}
-
-static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
-{
-       u8 b_pid[4];
-       pid = onoff ? pid : 0;
-
-       b_pid[0] = SET_PID_FILTER;
-       b_pid[1] = index;
-       b_pid[2] = pid & 0xff;
-       b_pid[3] = (pid >> 8) & 0x1f;
-
-       return dvb_usb_generic_write(adap->dev, b_pid, 4);
-}
-
-/* remote control */
-/* key list for the tiny remote control (Yakumo, don't know about the others) */
-static struct rc_map_table rc_map_dtt200u_table[] = {
-       { 0x8001, KEY_MUTE },
-       { 0x8002, KEY_CHANNELDOWN },
-       { 0x8003, KEY_VOLUMEDOWN },
-       { 0x8004, KEY_1 },
-       { 0x8005, KEY_2 },
-       { 0x8006, KEY_3 },
-       { 0x8007, KEY_4 },
-       { 0x8008, KEY_5 },
-       { 0x8009, KEY_6 },
-       { 0x800a, KEY_7 },
-       { 0x800c, KEY_ZOOM },
-       { 0x800d, KEY_0 },
-       { 0x800e, KEY_SELECT },
-       { 0x8012, KEY_POWER },
-       { 0x801a, KEY_CHANNELUP },
-       { 0x801b, KEY_8 },
-       { 0x801e, KEY_VOLUMEUP },
-       { 0x801f, KEY_9 },
-};
-
-static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       u8 key[5],cmd = GET_RC_CODE;
-       dvb_usb_generic_rw(d,&cmd,1,key,5,0);
-       dvb_usb_nec_rc_key_to_event(d,key,event,state);
-       if (key[0] != 0)
-               deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
-       return 0;
-}
-
-static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev);
-       return 0;
-}
-
-static struct dvb_usb_device_properties dtt200u_properties;
-static struct dvb_usb_device_properties wt220u_fc_properties;
-static struct dvb_usb_device_properties wt220u_properties;
-static struct dvb_usb_device_properties wt220u_zl0353_properties;
-static struct dvb_usb_device_properties wt220u_miglia_properties;
-
-static int dtt200u_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &wt220u_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-
-       return -ENODEV;
-}
-
-static struct usb_device_id dtt200u_usb_table [] = {
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM)  },
-       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD)  },
-       { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD)  },
-       { 0 },
-};
-MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
-
-static struct dvb_usb_device_properties dtt200u_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-dtt200u-01.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
-                       .pid_filter_count = 15,
-
-       .streaming_ctrl  = dtt200u_streaming_ctrl,
-       .pid_filter      = dtt200u_pid_filter,
-       .frontend_attach = dtt200u_frontend_attach,
-       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-               .count = 7,
-               .endpoint = 0x02,
-               .u = {
-                       .bulk = {
-                               .buffersize = 4096,
-                       }
-               }
-       },
-               }},
-               }
-       },
-       .power_ctrl      = dtt200u_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval     = 300,
-               .rc_map_table    = rc_map_dtt200u_table,
-               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
-               .rc_query        = dtt200u_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
-                 .cold_ids = { &dtt200u_usb_table[0], NULL },
-                 .warm_ids = { &dtt200u_usb_table[1], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct dvb_usb_device_properties wt220u_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-wt220u-02.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
-                       .pid_filter_count = 15,
-
-       .streaming_ctrl  = dtt200u_streaming_ctrl,
-       .pid_filter      = dtt200u_pid_filter,
-       .frontend_attach = dtt200u_frontend_attach,
-       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-               .count = 7,
-               .endpoint = 0x02,
-               .u = {
-                       .bulk = {
-                               .buffersize = 4096,
-                       }
-               }
-       },
-               }},
-               }
-       },
-       .power_ctrl      = dtt200u_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval     = 300,
-               .rc_map_table      = rc_map_dtt200u_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
-               .rc_query        = dtt200u_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
-                 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
-                 .warm_ids = { &dtt200u_usb_table[3], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct dvb_usb_device_properties wt220u_fc_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-wt220u-fc03.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
-                       .pid_filter_count = 15,
-
-       .streaming_ctrl  = dtt200u_streaming_ctrl,
-       .pid_filter      = dtt200u_pid_filter,
-       .frontend_attach = dtt200u_frontend_attach,
-       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-               .count = 7,
-                               .endpoint = 0x06,
-               .u = {
-                       .bulk = {
-                               .buffersize = 4096,
-                       }
-               }
-       },
-               }},
-               }
-       },
-       .power_ctrl      = dtt200u_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval     = 300,
-               .rc_map_table    = rc_map_dtt200u_table,
-               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
-               .rc_query        = dtt200u_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
-                 .cold_ids = { &dtt200u_usb_table[6], NULL },
-                 .warm_ids = { &dtt200u_usb_table[7], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct dvb_usb_device_properties wt220u_zl0353_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-wt220u-zl0353-01.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
-                       .pid_filter_count = 15,
-
-                       .streaming_ctrl  = dtt200u_streaming_ctrl,
-                       .pid_filter      = dtt200u_pid_filter,
-                       .frontend_attach = dtt200u_frontend_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .power_ctrl      = dtt200u_power_ctrl,
-
-       .rc.legacy = {
-               .rc_interval     = 300,
-               .rc_map_table    = rc_map_dtt200u_table,
-               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
-               .rc_query        = dtt200u_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
-                 .cold_ids = { &dtt200u_usb_table[4], NULL },
-                 .warm_ids = { &dtt200u_usb_table[5], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct dvb_usb_device_properties wt220u_miglia_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-wt220u-miglia-01.fw",
-
-       .num_adapters = 1,
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "WideView WT-220U PenType Receiver (Miglia)",
-                 .cold_ids = { &dtt200u_usb_table[9], NULL },
-                 /* This device turns into WT220U_ZL0353_WARM when fw
-                    has been uploaded */
-                 .warm_ids = { NULL },
-               },
-               { NULL },
-       }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver dtt200u_usb_driver = {
-       .name           = "dvb_usb_dtt200u",
-       .probe          = dtt200u_usb_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = dtt200u_usb_table,
-};
-
-module_usb_driver(dtt200u_usb_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
deleted file mode 100644 (file)
index 005b0a7..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
- * Typhoon/ Yuan DVB-T USB2.0 receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_DTT200U_H_
-#define _DVB_USB_DTT200U_H_
-
-#define DVB_USB_LOG_PREFIX "dtt200u"
-
-#include "dvb-usb.h"
-
-extern int dvb_usb_dtt200u_debug;
-#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
-
-/* guessed protocol description (reverse engineered):
- * read
- *  00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
- *  88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
- */
-
-#define GET_SPEED              0x00
-#define GET_TUNE_STATUS                0x81
-#define GET_RC_CODE            0x84
-#define GET_CONFIGURATION      0x88
-#define GET_AGC                        0x89
-#define GET_SNR                        0x8a
-#define GET_VIT_ERR_CNT                0x8c
-#define GET_RS_ERR_CNT         0x8d
-#define GET_RS_UNCOR_BLK_CNT   0x8e
-
-/* write
- *  01 - init
- *  02 - frequency (divided by 250000)
- *  03 - bandwidth
- *  04 - pid table (index pid(7:0) pid(12:8))
- *  05 - reset the pid table
- *  08 - transfer switch
- */
-
-#define SET_INIT               0x01
-#define SET_RF_FREQ            0x02
-#define SET_BANDWIDTH          0x03
-#define SET_PID_FILTER         0x04
-#define RESET_PID_FILTER       0x05
-#define SET_STREAMING          0x08
-
-extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c
deleted file mode 100644 (file)
index 3d11df4..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
- *
- * Copyright (C) 2008  Antoine Jacquet <royale@zerezo.com>
- * http://royale.zerezo.com/dtv5100/
- *
- * Inspired by gl861.c and au6610.c drivers
- *
- * 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
- */
-
-#include "dtv5100.h"
-#include "zl10353.h"
-#include "qt1010.h"
-
-/* debug */
-static int dvb_usb_dtv5100_debug;
-module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                          u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u8 request;
-       u8 type;
-       u16 value;
-       u16 index;
-
-       switch (wlen) {
-       case 1:
-               /* write { reg }, read { value } */
-               request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
-                                                       DTV5100_TUNER_READ);
-               type = USB_TYPE_VENDOR | USB_DIR_IN;
-               value = 0;
-               break;
-       case 2:
-               /* write { reg, value } */
-               request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
-                                                       DTV5100_TUNER_WRITE);
-               type = USB_TYPE_VENDOR | USB_DIR_OUT;
-               value = wbuf[1];
-               break;
-       default:
-               warn("wlen = %x, aborting.", wlen);
-               return -EINVAL;
-       }
-       index = (addr << 8) + wbuf[0];
-
-       msleep(1); /* avoid I2C errors */
-       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
-                              type, value, index, rbuf, rlen,
-                              DTV5100_USB_TIMEOUT);
-}
-
-/* I2C */
-static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                           int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                           msg[i].len, msg[i+1].buf,
-                                           msg[i+1].len) < 0)
-                               break;
-                       i++;
-               } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                          msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dtv5100_i2c_algo = {
-       .master_xfer   = dtv5100_i2c_xfer,
-       .functionality = dtv5100_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config dtv5100_zl10353_config = {
-       .demod_address = DTV5100_DEMOD_ADDR,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
-                             &adap->dev->i2c_adap);
-       if (adap->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       /* disable i2c gate, or it won't work... is this safe? */
-       adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
-
-       return 0;
-}
-
-static struct qt1010_config dtv5100_qt1010_config = {
-       .i2c_address = DTV5100_TUNER_ADDR
-};
-
-static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(qt1010_attach,
-                         adap->fe_adap[0].fe, &adap->dev->i2c_adap,
-                         &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties dtv5100_properties;
-
-static int dtv5100_probe(struct usb_interface *intf,
-                        const struct usb_device_id *id)
-{
-       int i, ret;
-       struct usb_device *udev = interface_to_usbdev(intf);
-
-       /* initialize non qt1010/zl10353 part? */
-       for (i = 0; dtv5100_init[i].request; i++) {
-               ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                                     dtv5100_init[i].request,
-                                     USB_TYPE_VENDOR | USB_DIR_OUT,
-                                     dtv5100_init[i].value,
-                                     dtv5100_init[i].index, NULL, 0,
-                                     DTV5100_USB_TIMEOUT);
-               if (ret)
-                       return ret;
-       }
-
-       ret = dvb_usb_device_init(intf, &dtv5100_properties,
-                                 THIS_MODULE, NULL, adapter_nr);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static struct usb_device_id dtv5100_table[] = {
-       { USB_DEVICE(0x06be, 0xa232) },
-       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, dtv5100_table);
-
-static struct dvb_usb_device_properties dtv5100_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-
-       .size_of_priv = 0,
-
-       .num_adapters = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-               .frontend_attach = dtv5100_frontend_attach,
-               .tuner_attach    = dtv5100_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x82,
-                       .u = {
-                               .bulk = {
-                                       .buffersize = 4096,
-                               }
-                       }
-               },
-               }},
-       } },
-
-       .i2c_algo = &dtv5100_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {
-                       .name = "AME DTV-5100 USB2.0 DVB-T",
-                       .cold_ids = { NULL },
-                       .warm_ids = { &dtv5100_table[0], NULL },
-               },
-       }
-};
-
-static struct usb_driver dtv5100_driver = {
-       .name           = "dvb_usb_dtv5100",
-       .probe          = dtv5100_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = dtv5100_table,
-};
-
-module_usb_driver(dtv5100_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/dvb/dvb-usb/dtv5100.h
deleted file mode 100644 (file)
index 93e96e0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
- *
- * Copyright (C) 2008  Antoine Jacquet <royale@zerezo.com>
- * http://royale.zerezo.com/dtv5100/
- *
- * 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
- */
-
-#ifndef _DVB_USB_DTV5100_H_
-#define _DVB_USB_DTV5100_H_
-
-#define DVB_USB_LOG_PREFIX "dtv5100"
-#include "dvb-usb.h"
-
-#define DTV5100_USB_TIMEOUT 500
-
-#define DTV5100_DEMOD_ADDR     0x00
-#define DTV5100_DEMOD_WRITE    0xc0
-#define DTV5100_DEMOD_READ     0xc1
-
-#define DTV5100_TUNER_ADDR     0xc4
-#define DTV5100_TUNER_WRITE    0xc7
-#define DTV5100_TUNER_READ     0xc8
-
-#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
-#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
-
-static struct {
-       u8 request;
-       u8 value;
-       u16 index;
-} dtv5100_init[] = {
-       { 0x000000c5, 0x00000000, 0x00000001 },
-       { 0x000000c5, 0x00000001, 0x00000001 },
-       { }             /* Terminating entry */
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
deleted file mode 100644 (file)
index 6b7b2a8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* dvb-usb-common.h is part of the DVB USB library.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * a header file containing prototypes and types for internal use of the dvb-usb-lib
- */
-#ifndef _DVB_USB_COMMON_H_
-#define _DVB_USB_COMMON_H_
-
-#define DVB_USB_LOG_PREFIX "dvb-usb"
-#include "dvb-usb.h"
-
-extern int dvb_usb_debug;
-extern int dvb_usb_disable_rc_polling;
-
-#define deb_info(args...)  dprintk(dvb_usb_debug,0x001,args)
-#define deb_xfer(args...)  dprintk(dvb_usb_debug,0x002,args)
-#define deb_pll(args...)   dprintk(dvb_usb_debug,0x004,args)
-#define deb_ts(args...)    dprintk(dvb_usb_debug,0x008,args)
-#define deb_err(args...)   dprintk(dvb_usb_debug,0x010,args)
-#define deb_rc(args...)    dprintk(dvb_usb_debug,0x020,args)
-#define deb_fw(args...)    dprintk(dvb_usb_debug,0x040,args)
-#define deb_mem(args...)   dprintk(dvb_usb_debug,0x080,args)
-#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
-
-/* commonly used  methods */
-extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
-
-extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
-
-extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
-extern int usb_urb_exit(struct usb_data_stream *stream);
-extern int usb_urb_submit(struct usb_data_stream *stream);
-extern int usb_urb_kill(struct usb_data_stream *stream);
-
-extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
-extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
-
-extern int dvb_usb_i2c_init(struct dvb_usb_device *);
-extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
-
-extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap,
-                                   short *adapter_nums);
-extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
-extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
-extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
-
-extern int dvb_usb_remote_init(struct dvb_usb_device *);
-extern int dvb_usb_remote_exit(struct dvb_usb_device *);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
deleted file mode 100644 (file)
index 719413b..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/* dvb-usb-dvb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for initializing and handling the
- * linux-dvb API.
- */
-#include "dvb-usb-common.h"
-
-/* does the complete input transfer handling */
-static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
-{
-       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
-       int newfeedcount, ret;
-
-       if (adap == NULL)
-               return -ENODEV;
-
-       if ((adap->active_fe < 0) ||
-           (adap->active_fe >= adap->num_frontends_initialized)) {
-               return -EINVAL;
-       }
-
-       newfeedcount = adap->feedcount + (onoff ? 1 : -1);
-
-       /* stop feed before setting a new pid if there will be no pid anymore */
-       if (newfeedcount == 0) {
-               deb_ts("stop feeding\n");
-               usb_urb_kill(&adap->fe_adap[adap->active_fe].stream);
-
-               if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
-                       ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 0);
-                       if (ret < 0) {
-                               err("error while stopping stream.");
-                               return ret;
-                       }
-               }
-       }
-
-       adap->feedcount = newfeedcount;
-
-       /* activate the pid on the device specific pid_filter */
-       deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",
-               adap->fe_adap[adap->active_fe].pid_filtering ?
-               "yes" : "no", dvbdmxfeed->pid, dvbdmxfeed->pid,
-               dvbdmxfeed->index, onoff ? "on" : "off");
-       if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-               adap->fe_adap[adap->active_fe].pid_filtering &&
-               adap->props.fe[adap->active_fe].pid_filter != NULL)
-               adap->props.fe[adap->active_fe].pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
-
-       /* start the feed if this was the first feed and there is still a feed
-        * for reception.
-        */
-       if (adap->feedcount == onoff && adap->feedcount > 0) {
-               deb_ts("submitting all URBs\n");
-               usb_urb_submit(&adap->fe_adap[adap->active_fe].stream);
-
-               deb_ts("controlling pid parser\n");
-               if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                       adap->props.fe[adap->active_fe].caps &
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
-                       adap->props.fe[adap->active_fe].pid_filter_ctrl != NULL) {
-                       ret = adap->props.fe[adap->active_fe].pid_filter_ctrl(adap,
-                               adap->fe_adap[adap->active_fe].pid_filtering);
-                       if (ret < 0) {
-                               err("could not handle pid_parser");
-                               return ret;
-                       }
-               }
-               deb_ts("start feeding\n");
-               if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
-                       ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 1);
-                       if (ret < 0) {
-                               err("error while enabling fifo.");
-                               return ret;
-                       }
-               }
-
-       }
-       return 0;
-}
-
-static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
-       return dvb_usb_ctrl_feed(dvbdmxfeed,1);
-}
-
-static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
-       return dvb_usb_ctrl_feed(dvbdmxfeed,0);
-}
-
-int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
-{
-       int i;
-       int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
-                                      adap->dev->owner, &adap->dev->udev->dev,
-                                      adapter_nums);
-
-       if (ret < 0) {
-               deb_info("dvb_register_adapter failed: error %d", ret);
-               goto err;
-       }
-       adap->dvb_adap.priv = adap;
-
-       if (adap->dev->props.read_mac_address) {
-               if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
-                       info("MAC address: %pM",adap->dvb_adap.proposed_mac);
-               else
-                       err("MAC address reading failed.");
-       }
-
-
-       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       adap->demux.priv             = adap;
-
-       adap->demux.filternum        = 0;
-       for (i = 0; i < adap->props.num_frontends; i++) {
-               if (adap->demux.filternum < adap->fe_adap[i].max_feed_count)
-                       adap->demux.filternum = adap->fe_adap[i].max_feed_count;
-       }
-       adap->demux.feednum          = adap->demux.filternum;
-       adap->demux.start_feed       = dvb_usb_start_feed;
-       adap->demux.stop_feed        = dvb_usb_stop_feed;
-       adap->demux.write_to_decoder = NULL;
-       if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
-               err("dvb_dmx_init failed: error %d",ret);
-               goto err_dmx;
-       }
-
-       adap->dmxdev.filternum       = adap->demux.filternum;
-       adap->dmxdev.demux           = &adap->demux.dmx;
-       adap->dmxdev.capabilities    = 0;
-       if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
-               err("dvb_dmxdev_init failed: error %d",ret);
-               goto err_dmx_dev;
-       }
-
-       if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net,
-                                               &adap->demux.dmx)) < 0) {
-               err("dvb_net_init failed: error %d",ret);
-               goto err_net_init;
-       }
-
-       adap->state |= DVB_USB_ADAP_STATE_DVB;
-       return 0;
-
-err_net_init:
-       dvb_dmxdev_release(&adap->dmxdev);
-err_dmx_dev:
-       dvb_dmx_release(&adap->demux);
-err_dmx:
-       dvb_unregister_adapter(&adap->dvb_adap);
-err:
-       return ret;
-}
-
-int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
-{
-       if (adap->state & DVB_USB_ADAP_STATE_DVB) {
-               deb_info("unregistering DVB part\n");
-               dvb_net_release(&adap->dvb_net);
-               adap->demux.dmx.close(&adap->demux.dmx);
-               dvb_dmxdev_release(&adap->dmxdev);
-               dvb_dmx_release(&adap->demux);
-               dvb_unregister_adapter(&adap->dvb_adap);
-               adap->state &= ~DVB_USB_ADAP_STATE_DVB;
-       }
-       return 0;
-}
-
-static int dvb_usb_set_active_fe(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-
-       int ret = (adap->props.frontend_ctrl) ?
-               adap->props.frontend_ctrl(fe, onoff) : 0;
-
-       if (ret < 0) {
-               err("frontend_ctrl request failed");
-               return ret;
-       }
-       if (onoff)
-               adap->active_fe = fe->id;
-
-       return 0;
-}
-
-static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-
-       dvb_usb_device_power_ctrl(adap->dev, 1);
-
-       dvb_usb_set_active_fe(fe, 1);
-
-       if (adap->fe_adap[fe->id].fe_init)
-               adap->fe_adap[fe->id].fe_init(fe);
-
-       return 0;
-}
-
-static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-
-       if (adap->fe_adap[fe->id].fe_sleep)
-               adap->fe_adap[fe->id].fe_sleep(fe);
-
-       dvb_usb_set_active_fe(fe, 0);
-
-       return dvb_usb_device_power_ctrl(adap->dev, 0);
-}
-
-int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
-{
-       int ret, i;
-
-       /* register all given adapter frontends */
-       for (i = 0; i < adap->props.num_frontends; i++) {
-
-               if (adap->props.fe[i].frontend_attach == NULL) {
-                       err("strange: '%s' #%d,%d "
-                           "doesn't want to attach a frontend.",
-                           adap->dev->desc->name, adap->id, i);
-
-                       return 0;
-               }
-
-               ret = adap->props.fe[i].frontend_attach(adap);
-               if (ret || adap->fe_adap[i].fe == NULL) {
-                       /* only print error when there is no FE at all */
-                       if (i == 0)
-                               err("no frontend was attached by '%s'",
-                                       adap->dev->desc->name);
-
-                       return 0;
-               }
-
-               adap->fe_adap[i].fe->id = i;
-
-               /* re-assign sleep and wakeup functions */
-               adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init;
-               adap->fe_adap[i].fe->ops.init  = dvb_usb_fe_wakeup;
-               adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
-               adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;
-
-               if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
-                       err("Frontend %d registration failed.", i);
-                       dvb_frontend_detach(adap->fe_adap[i].fe);
-                       adap->fe_adap[i].fe = NULL;
-                       /* In error case, do not try register more FEs,
-                        * still leaving already registered FEs alive. */
-                       if (i == 0)
-                               return -ENODEV;
-                       else
-                               return 0;
-               }
-
-               /* only attach the tuner if the demod is there */
-               if (adap->props.fe[i].tuner_attach != NULL)
-                       adap->props.fe[i].tuner_attach(adap);
-
-               adap->num_frontends_initialized++;
-       }
-
-       return 0;
-}
-
-int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
-{
-       int i = adap->num_frontends_initialized - 1;
-
-       /* unregister all given adapter frontends */
-       for (; i >= 0; i--) {
-               if (adap->fe_adap[i].fe != NULL) {
-                       dvb_unregister_frontend(adap->fe_adap[i].fe);
-                       dvb_frontend_detach(adap->fe_adap[i].fe);
-               }
-       }
-       adap->num_frontends_initialized = 0;
-
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
deleted file mode 100644 (file)
index 733a7ff..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* dvb-usb-firmware.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
- *
- * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
- */
-#include "dvb-usb-common.h"
-
-#include <linux/usb.h>
-
-struct usb_cypress_controller {
-       int id;
-       const char *name;       /* name of the usb controller */
-       u16 cpu_cs_register;    /* needs to be restarted, when the firmware has been downloaded. */
-};
-
-static struct usb_cypress_controller cypress[] = {
-       { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
-       { .id = CYPRESS_AN2135,  .name = "Cypress AN2135",  .cpu_cs_register = 0x7f92 },
-       { .id = CYPRESS_AN2235,  .name = "Cypress AN2235",  .cpu_cs_register = 0x7f92 },
-       { .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
-};
-
-/*
- * load a firmware packet to the device
- */
-static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
-{
-       return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-                       0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
-}
-
-int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
-{
-       struct hexline hx;
-       u8 reset;
-       int ret,pos=0;
-
-       /* stop the CPU */
-       reset = 1;
-       if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
-               err("could not stop the USB controller CPU.");
-
-       while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
-               deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
-               ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
-
-               if (ret != hx.len) {
-                       err("error while transferring firmware "
-                               "(transferred size: %d, block size: %d)",
-                               ret,hx.len);
-                       ret = -EINVAL;
-                       break;
-               }
-       }
-       if (ret < 0) {
-               err("firmware download failed at %d with %d",pos,ret);
-               return ret;
-       }
-
-       if (ret == 0) {
-               /* restart the CPU */
-               reset = 0;
-               if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
-                       err("could not restart the USB controller CPU.");
-                       ret = -EINVAL;
-               }
-       } else
-               ret = -EIO;
-
-       return ret;
-}
-EXPORT_SYMBOL(usb_cypress_load_firmware);
-
-int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
-{
-       int ret;
-       const struct firmware *fw = NULL;
-
-       if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
-               err("did not find the firmware file. (%s) "
-                       "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
-                       props->firmware,ret);
-               return ret;
-       }
-
-       info("downloading firmware from file '%s'",props->firmware);
-
-       switch (props->usb_ctrl) {
-               case CYPRESS_AN2135:
-               case CYPRESS_AN2235:
-               case CYPRESS_FX2:
-                       ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
-                       break;
-               case DEVICE_SPECIFIC:
-                       if (props->download_firmware)
-                               ret = props->download_firmware(udev,fw);
-                       else {
-                               err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
-                               ret = -EINVAL;
-                       }
-                       break;
-               default:
-                       ret = -EINVAL;
-                       break;
-       }
-
-       release_firmware(fw);
-       return ret;
-}
-
-int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
-                              int *pos)
-{
-       u8 *b = (u8 *) &fw->data[*pos];
-       int data_offs = 4;
-       if (*pos >= fw->size)
-               return 0;
-
-       memset(hx,0,sizeof(struct hexline));
-
-       hx->len  = b[0];
-
-       if ((*pos + hx->len + 4) >= fw->size)
-               return -EINVAL;
-
-       hx->addr = b[1] | (b[2] << 8);
-       hx->type = b[3];
-
-       if (hx->type == 0x04) {
-               /* b[4] and b[5] are the Extended linear address record data field */
-               hx->addr |= (b[4] << 24) | (b[5] << 16);
-/*             hx->len -= 2;
-               data_offs += 2; */
-       }
-       memcpy(hx->data,&b[data_offs],hx->len);
-       hx->chk = b[hx->len + data_offs];
-
-       *pos += hx->len + 5;
-
-       return *pos;
-}
-EXPORT_SYMBOL(dvb_usb_get_hexline);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
deleted file mode 100644 (file)
index 88e4a62..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* dvb-usb-i2c.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for (de-)initializing an I2C adapter.
- */
-#include "dvb-usb-common.h"
-
-int dvb_usb_i2c_init(struct dvb_usb_device *d)
-{
-       int ret = 0;
-
-       if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
-               return 0;
-
-       if (d->props.i2c_algo == NULL) {
-               err("no i2c algorithm specified");
-               return -EINVAL;
-       }
-
-       strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
-       d->i2c_adap.algo      = d->props.i2c_algo;
-       d->i2c_adap.algo_data = NULL;
-       d->i2c_adap.dev.parent = &d->udev->dev;
-
-       i2c_set_adapdata(&d->i2c_adap, d);
-
-       if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
-               err("could not add i2c adapter");
-
-       d->state |= DVB_USB_STATE_I2C;
-
-       return ret;
-}
-
-int dvb_usb_i2c_exit(struct dvb_usb_device *d)
-{
-       if (d->state & DVB_USB_STATE_I2C)
-               i2c_del_adapter(&d->i2c_adap);
-       d->state &= ~DVB_USB_STATE_I2C;
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
deleted file mode 100644 (file)
index 169196e..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * DVB USB library - provides a generic interface for a DVB USB device driver.
- *
- * dvb-usb-init.c
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dvb-usb-common.h"
-
-/* debug */
-int dvb_usb_debug;
-module_param_named(debug, dvb_usb_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256  (or-able))." DVB_USB_DEBUG_STATUS);
-
-int dvb_usb_disable_rc_polling;
-module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
-MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
-
-static int dvb_usb_force_pid_filter_usage;
-module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
-MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
-
-static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
-{
-       struct dvb_usb_adapter *adap;
-       int ret, n, o;
-
-       for (n = 0; n < d->props.num_adapters; n++) {
-               adap = &d->adapter[n];
-               adap->dev = d;
-               adap->id  = n;
-
-               memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
-
-       for (o = 0; o < adap->props.num_frontends; o++) {
-               struct dvb_usb_adapter_fe_properties *props = &adap->props.fe[o];
-               /* speed - when running at FULL speed we need a HW PID filter */
-               if (d->udev->speed == USB_SPEED_FULL && !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
-                       err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
-                       return -ENODEV;
-               }
-
-               if ((d->udev->speed == USB_SPEED_FULL && props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
-                       (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
-                       info("will use the device's hardware PID filter (table count: %d).", props->pid_filter_count);
-                       adap->fe_adap[o].pid_filtering  = 1;
-                       adap->fe_adap[o].max_feed_count = props->pid_filter_count;
-               } else {
-                       info("will pass the complete MPEG2 transport stream to the software demuxer.");
-                       adap->fe_adap[o].pid_filtering  = 0;
-                       adap->fe_adap[o].max_feed_count = 255;
-               }
-
-               if (!adap->fe_adap[o].pid_filtering &&
-                       dvb_usb_force_pid_filter_usage &&
-                       props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
-                       info("pid filter enabled by module option.");
-                       adap->fe_adap[o].pid_filtering  = 1;
-                       adap->fe_adap[o].max_feed_count = props->pid_filter_count;
-               }
-
-               if (props->size_of_priv > 0) {
-                       adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL);
-                       if (adap->fe_adap[o].priv == NULL) {
-                               err("no memory for priv for adapter %d fe %d.", n, o);
-                               return -ENOMEM;
-                       }
-               }
-       }
-
-               if (adap->props.size_of_priv > 0) {
-                       adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
-                       if (adap->priv == NULL) {
-                               err("no memory for priv for adapter %d.", n);
-                               return -ENOMEM;
-                       }
-               }
-
-               if ((ret = dvb_usb_adapter_stream_init(adap)) ||
-                       (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
-                       (ret = dvb_usb_adapter_frontend_init(adap))) {
-                       return ret;
-               }
-
-               /* use exclusive FE lock if there is multiple shared FEs */
-               if (adap->fe_adap[1].fe)
-                       adap->dvb_adap.mfe_shared = 1;
-
-               d->num_adapters_initialized++;
-               d->state |= DVB_USB_STATE_DVB;
-       }
-
-       /*
-        * when reloading the driver w/o replugging the device
-        * sometimes a timeout occures, this helps
-        */
-       if (d->props.generic_bulk_ctrl_endpoint != 0) {
-               usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-               usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
-       }
-
-       return 0;
-}
-
-static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
-{
-       int n;
-
-       for (n = 0; n < d->num_adapters_initialized; n++) {
-               dvb_usb_adapter_frontend_exit(&d->adapter[n]);
-               dvb_usb_adapter_dvb_exit(&d->adapter[n]);
-               dvb_usb_adapter_stream_exit(&d->adapter[n]);
-               kfree(d->adapter[n].priv);
-       }
-       d->num_adapters_initialized = 0;
-       d->state &= ~DVB_USB_STATE_DVB;
-       return 0;
-}
-
-
-/* general initialization functions */
-static int dvb_usb_exit(struct dvb_usb_device *d)
-{
-       deb_info("state before exiting everything: %x\n", d->state);
-       dvb_usb_remote_exit(d);
-       dvb_usb_adapter_exit(d);
-       dvb_usb_i2c_exit(d);
-       deb_info("state should be zero now: %x\n", d->state);
-       d->state = DVB_USB_STATE_INIT;
-       kfree(d->priv);
-       kfree(d);
-       return 0;
-}
-
-static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
-{
-       int ret = 0;
-
-       mutex_init(&d->usb_mutex);
-       mutex_init(&d->i2c_mutex);
-
-       d->state = DVB_USB_STATE_INIT;
-
-       if (d->props.size_of_priv > 0) {
-               d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
-               if (d->priv == NULL) {
-                       err("no memory for priv in 'struct dvb_usb_device'");
-                       return -ENOMEM;
-               }
-       }
-
-       /* check the capabilities and set appropriate variables */
-       dvb_usb_device_power_ctrl(d, 1);
-
-       if ((ret = dvb_usb_i2c_init(d)) ||
-               (ret = dvb_usb_adapter_init(d, adapter_nums))) {
-               dvb_usb_exit(d);
-               return ret;
-       }
-
-       if ((ret = dvb_usb_remote_init(d)))
-               err("could not initialize remote control.");
-
-       dvb_usb_device_power_ctrl(d, 0);
-
-       return 0;
-}
-
-/* determine the name and the state of the just found USB device */
-static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
-{
-       int i, j;
-       struct dvb_usb_device_description *desc = NULL;
-
-       *cold = -1;
-
-       for (i = 0; i < props->num_device_descs; i++) {
-
-               for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
-                       deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
-                       if (props->devices[i].cold_ids[j]->idVendor  == le16_to_cpu(udev->descriptor.idVendor) &&
-                               props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
-                               *cold = 1;
-                               desc = &props->devices[i];
-                               break;
-                       }
-               }
-
-               if (desc != NULL)
-                       break;
-
-               for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
-                       deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
-                       if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
-                               props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
-                               *cold = 0;
-                               desc = &props->devices[i];
-                               break;
-                       }
-               }
-       }
-
-       if (desc != NULL && props->identify_state != NULL)
-               props->identify_state(udev, props, &desc, cold);
-
-       return desc;
-}
-
-int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       if (onoff)
-               d->powered++;
-       else
-               d->powered--;
-
-       if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
-               deb_info("power control: %d\n", onoff);
-               if (d->props.power_ctrl)
-                       return d->props.power_ctrl(d, onoff);
-       }
-       return 0;
-}
-
-/*
- * USB
- */
-int dvb_usb_device_init(struct usb_interface *intf,
-                       struct dvb_usb_device_properties *props,
-                       struct module *owner, struct dvb_usb_device **du,
-                       short *adapter_nums)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct dvb_usb_device *d = NULL;
-       struct dvb_usb_device_description *desc = NULL;
-
-       int ret = -ENOMEM, cold = 0;
-
-       if (du != NULL)
-               *du = NULL;
-
-       if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
-               deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
-               return -ENODEV;
-       }
-
-       if (cold) {
-               info("found a '%s' in cold state, will try to load a firmware", desc->name);
-               ret = dvb_usb_download_firmware(udev, props);
-               if (!props->no_reconnect || ret != 0)
-                       return ret;
-       }
-
-       info("found a '%s' in warm state.", desc->name);
-       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
-       if (d == NULL) {
-               err("no memory for 'struct dvb_usb_device'");
-               return -ENOMEM;
-       }
-
-       d->udev = udev;
-       memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
-       d->desc = desc;
-       d->owner = owner;
-
-       usb_set_intfdata(intf, d);
-
-       if (du != NULL)
-               *du = d;
-
-       ret = dvb_usb_init(d, adapter_nums);
-
-       if (ret == 0)
-               info("%s successfully initialized and connected.", desc->name);
-       else
-               info("%s error while loading driver (%d)", desc->name, ret);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usb_device_init);
-
-void dvb_usb_device_exit(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       const char *name = "generic DVB-USB module";
-
-       usb_set_intfdata(intf, NULL);
-       if (d != NULL && d->desc != NULL) {
-               name = d->desc->name;
-               dvb_usb_exit(d);
-       }
-       info("%s successfully deinitialized and disconnected.", name);
-
-}
-EXPORT_SYMBOL(dvb_usb_device_exit);
-
-MODULE_VERSION("1.0");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
deleted file mode 100644 (file)
index 41bacff..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-/* dvb-usb-remote.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for initializing the input-device and for handling remote-control-queries.
- */
-#include "dvb-usb-common.h"
-#include <linux/usb/input.h>
-
-static unsigned int
-legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
-                               struct rc_map_table *keymap,
-                               unsigned int keymap_size)
-{
-       unsigned int index;
-       unsigned int scancode;
-
-       if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
-               index = ke->index;
-       } else {
-               if (input_scancode_to_scalar(ke, &scancode))
-                       return keymap_size;
-
-               /* See if we can match the raw key code. */
-               for (index = 0; index < keymap_size; index++)
-                       if (keymap[index].scancode == scancode)
-                               break;
-
-               /* See if there is an unused hole in the map */
-               if (index >= keymap_size) {
-                       for (index = 0; index < keymap_size; index++) {
-                               if (keymap[index].keycode == KEY_RESERVED ||
-                                   keymap[index].keycode == KEY_UNKNOWN) {
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       return index;
-}
-
-static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
-                                    struct input_keymap_entry *ke)
-{
-       struct dvb_usb_device *d = input_get_drvdata(dev);
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
-       unsigned int index;
-
-       index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
-       if (index >= keymap_size)
-               return -EINVAL;
-
-       ke->keycode = keymap[index].keycode;
-       if (ke->keycode == KEY_UNKNOWN)
-               ke->keycode = KEY_RESERVED;
-       ke->len = sizeof(keymap[index].scancode);
-       memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
-       ke->index = index;
-
-       return 0;
-}
-
-static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
-                                    const struct input_keymap_entry *ke,
-                                    unsigned int *old_keycode)
-{
-       struct dvb_usb_device *d = input_get_drvdata(dev);
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
-       unsigned int index;
-
-       index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
-       /*
-        * FIXME: Currently, it is not possible to increase the size of
-        * scancode table. For it to happen, one possibility
-        * would be to allocate a table with key_map_size + 1,
-        * copying data, appending the new key on it, and freeing
-        * the old one - or maybe just allocating some spare space
-        */
-       if (index >= keymap_size)
-               return -EINVAL;
-
-       *old_keycode = keymap[index].keycode;
-       keymap->keycode = ke->keycode;
-       __set_bit(ke->keycode, dev->keybit);
-
-       if (*old_keycode != KEY_RESERVED) {
-               __clear_bit(*old_keycode, dev->keybit);
-               for (index = 0; index < keymap_size; index++) {
-                       if (keymap[index].keycode == *old_keycode) {
-                               __set_bit(*old_keycode, dev->keybit);
-                               break;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/* Remote-control poll function - called every dib->rc_query_interval ms to see
- * whether the remote control has received anything.
- *
- * TODO: Fix the repeat rate of the input device.
- */
-static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
-{
-       struct dvb_usb_device *d =
-               container_of(work, struct dvb_usb_device, rc_query_work.work);
-       u32 event;
-       int state;
-
-       /* TODO: need a lock here.  We can simply skip checking for the remote control
-          if we're busy. */
-
-       /* when the parameter has been set to 1 via sysfs while the driver was running */
-       if (dvb_usb_disable_rc_polling)
-               return;
-
-       if (d->props.rc.legacy.rc_query(d,&event,&state)) {
-               err("error while querying for an remote control event.");
-               goto schedule;
-       }
-
-
-       switch (state) {
-               case REMOTE_NO_KEY_PRESSED:
-                       break;
-               case REMOTE_KEY_PRESSED:
-                       deb_rc("key pressed\n");
-                       d->last_event = event;
-               case REMOTE_KEY_REPEAT:
-                       deb_rc("key repeated\n");
-                       input_event(d->input_dev, EV_KEY, event, 1);
-                       input_sync(d->input_dev);
-                       input_event(d->input_dev, EV_KEY, d->last_event, 0);
-                       input_sync(d->input_dev);
-                       break;
-               default:
-                       break;
-       }
-
-/* improved repeat handling ???
-       switch (state) {
-               case REMOTE_NO_KEY_PRESSED:
-                       deb_rc("NO KEY PRESSED\n");
-                       if (d->last_state != REMOTE_NO_KEY_PRESSED) {
-                               deb_rc("releasing event %d\n",d->last_event);
-                               input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
-                               input_sync(d->rc_input_dev);
-                       }
-                       d->last_state = REMOTE_NO_KEY_PRESSED;
-                       d->last_event = 0;
-                       break;
-               case REMOTE_KEY_PRESSED:
-                       deb_rc("KEY PRESSED\n");
-                       deb_rc("pressing event %d\n",event);
-
-                       input_event(d->rc_input_dev, EV_KEY, event, 1);
-                       input_sync(d->rc_input_dev);
-
-                       d->last_event = event;
-                       d->last_state = REMOTE_KEY_PRESSED;
-                       break;
-               case REMOTE_KEY_REPEAT:
-                       deb_rc("KEY_REPEAT\n");
-                       if (d->last_state != REMOTE_NO_KEY_PRESSED) {
-                               deb_rc("repeating event %d\n",d->last_event);
-                               input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
-                               input_sync(d->rc_input_dev);
-                               d->last_state = REMOTE_KEY_REPEAT;
-                       }
-               default:
-                       break;
-       }
-*/
-
-schedule:
-       schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
-}
-
-static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
-{
-       int i, err, rc_interval;
-       struct input_dev *input_dev;
-
-       input_dev = input_allocate_device();
-       if (!input_dev)
-               return -ENOMEM;
-
-       input_dev->evbit[0] = BIT_MASK(EV_KEY);
-       input_dev->name = "IR-receiver inside an USB DVB receiver";
-       input_dev->phys = d->rc_phys;
-       usb_to_input_id(d->udev, &input_dev->id);
-       input_dev->dev.parent = &d->udev->dev;
-       d->input_dev = input_dev;
-       d->rc_dev = NULL;
-
-       input_dev->getkeycode = legacy_dvb_usb_getkeycode;
-       input_dev->setkeycode = legacy_dvb_usb_setkeycode;
-
-       /* set the bits for the keys */
-       deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               deb_rc("setting bit for event %d item %d\n",
-                       d->props.rc.legacy.rc_map_table[i].keycode, i);
-               set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
-       }
-
-       /* setting these two values to non-zero, we have to manage key repeats */
-       input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
-       input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
-
-       input_set_drvdata(input_dev, d);
-
-       err = input_register_device(input_dev);
-       if (err)
-               input_free_device(input_dev);
-
-       rc_interval = d->props.rc.legacy.rc_interval;
-
-       INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
-
-       info("schedule remote query interval to %d msecs.", rc_interval);
-       schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(rc_interval));
-
-       d->state |= DVB_USB_STATE_REMOTE;
-
-       return err;
-}
-
-/* Remote-control poll function - called every dib->rc_query_interval ms to see
- * whether the remote control has received anything.
- *
- * TODO: Fix the repeat rate of the input device.
- */
-static void dvb_usb_read_remote_control(struct work_struct *work)
-{
-       struct dvb_usb_device *d =
-               container_of(work, struct dvb_usb_device, rc_query_work.work);
-       int err;
-
-       /* TODO: need a lock here.  We can simply skip checking for the remote control
-          if we're busy. */
-
-       /* when the parameter has been set to 1 via sysfs while the
-        * driver was running, or when bulk mode is enabled after IR init
-        */
-       if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
-               return;
-
-       err = d->props.rc.core.rc_query(d);
-       if (err)
-               err("error %d while querying for an remote control event.", err);
-
-       schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(d->props.rc.core.rc_interval));
-}
-
-static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
-{
-       int err, rc_interval;
-       struct rc_dev *dev;
-
-       dev = rc_allocate_device();
-       if (!dev)
-               return -ENOMEM;
-
-       dev->driver_name = d->props.rc.core.module_name;
-       dev->map_name = d->props.rc.core.rc_codes;
-       dev->change_protocol = d->props.rc.core.change_protocol;
-       dev->allowed_protos = d->props.rc.core.allowed_protos;
-       dev->driver_type = d->props.rc.core.driver_type;
-       usb_to_input_id(d->udev, &dev->input_id);
-       dev->input_name = "IR-receiver inside an USB DVB receiver";
-       dev->input_phys = d->rc_phys;
-       dev->dev.parent = &d->udev->dev;
-       dev->priv = d;
-
-       err = rc_register_device(dev);
-       if (err < 0) {
-               rc_free_device(dev);
-               return err;
-       }
-
-       d->input_dev = NULL;
-       d->rc_dev = dev;
-
-       if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
-               return 0;
-
-       /* Polling mode - initialize a work queue for handling it */
-       INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
-
-       rc_interval = d->props.rc.core.rc_interval;
-
-       info("schedule remote query interval to %d msecs.", rc_interval);
-       schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(rc_interval));
-
-       return 0;
-}
-
-int dvb_usb_remote_init(struct dvb_usb_device *d)
-{
-       int err;
-
-       if (dvb_usb_disable_rc_polling)
-               return 0;
-
-       if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
-               d->props.rc.mode = DVB_RC_LEGACY;
-       else if (d->props.rc.core.rc_codes)
-               d->props.rc.mode = DVB_RC_CORE;
-       else
-               return 0;
-
-       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
-       /* Start the remote-control polling. */
-       if (d->props.rc.legacy.rc_interval < 40)
-               d->props.rc.legacy.rc_interval = 100; /* default */
-
-       if (d->props.rc.mode == DVB_RC_LEGACY)
-               err = legacy_dvb_usb_remote_init(d);
-       else
-               err = rc_core_dvb_usb_remote_init(d);
-       if (err)
-               return err;
-
-       d->state |= DVB_USB_STATE_REMOTE;
-
-       return 0;
-}
-
-int dvb_usb_remote_exit(struct dvb_usb_device *d)
-{
-       if (d->state & DVB_USB_STATE_REMOTE) {
-               cancel_delayed_work_sync(&d->rc_query_work);
-               if (d->props.rc.mode == DVB_RC_LEGACY)
-                       input_unregister_device(d->input_dev);
-               else
-                       rc_unregister_device(d->rc_dev);
-       }
-       d->state &= ~DVB_USB_STATE_REMOTE;
-       return 0;
-}
-
-#define DVB_USB_RC_NEC_EMPTY           0x00
-#define DVB_USB_RC_NEC_KEY_PRESSED     0x01
-#define DVB_USB_RC_NEC_KEY_REPEATED    0x02
-int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
-               u8 keybuf[5], u32 *event, int *state)
-{
-       int i;
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-       switch (keybuf[0]) {
-               case DVB_USB_RC_NEC_EMPTY:
-                       break;
-               case DVB_USB_RC_NEC_KEY_PRESSED:
-                       if ((u8) ~keybuf[1] != keybuf[2] ||
-                               (u8) ~keybuf[3] != keybuf[4]) {
-                               deb_err("remote control checksum failed.\n");
-                               break;
-                       }
-                       /* See if we can match the raw key code. */
-                       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
-                               if (rc5_custom(&keymap[i]) == keybuf[1] &&
-                                       rc5_data(&keymap[i]) == keybuf[3]) {
-                                       *event = keymap[i].keycode;
-                                       *state = REMOTE_KEY_PRESSED;
-                                       return 0;
-                               }
-                       deb_err("key mapping failed - no appropriate key found in keymapping\n");
-                       break;
-               case DVB_USB_RC_NEC_KEY_REPEATED:
-                       *state = REMOTE_KEY_REPEAT;
-                       break;
-               default:
-                       deb_err("unknown type of remote status: %d\n",keybuf[0]);
-                       break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
deleted file mode 100644 (file)
index 5c8f651..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* dvb-usb-urb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file keeps functions for initializing and handling the
- * USB and URB stuff.
- */
-#include "dvb-usb-common.h"
-
-int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
-       u16 rlen, int delay_ms)
-{
-       int actlen,ret = -ENOMEM;
-
-       if (!d || wbuf == NULL || wlen == 0)
-               return -EINVAL;
-
-       if (d->props.generic_bulk_ctrl_endpoint == 0) {
-               err("endpoint for generic control not specified.");
-               return -EINVAL;
-       }
-
-       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
-               return ret;
-
-       deb_xfer(">>> ");
-       debug_dump(wbuf,wlen,deb_xfer);
-
-       ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
-                       d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
-                       2000);
-
-       if (ret)
-               err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
-       else
-               ret = actlen != wlen ? -1 : 0;
-
-       /* an answer is expected, and no error before */
-       if (!ret && rbuf && rlen) {
-               if (delay_ms)
-                       msleep(delay_ms);
-
-               ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
-                               d->props.generic_bulk_ctrl_endpoint_response ?
-                               d->props.generic_bulk_ctrl_endpoint_response :
-                               d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
-                               2000);
-
-               if (ret)
-                       err("recv bulk message failed: %d",ret);
-               else {
-                       deb_xfer("<<< ");
-                       debug_dump(rbuf,actlen,deb_xfer);
-               }
-       }
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usb_generic_rw);
-
-int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
-{
-       return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
-}
-EXPORT_SYMBOL(dvb_usb_generic_write);
-
-static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
-               dvb_dmx_swfilter(&adap->demux, buffer, length);
-}
-
-static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
-               dvb_dmx_swfilter_204(&adap->demux, buffer, length);
-}
-
-static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
-                                     u8 *buffer, size_t length)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
-               dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
-}
-
-int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
-{
-       int i, ret = 0;
-       for (i = 0; i < adap->props.num_frontends; i++) {
-
-               adap->fe_adap[i].stream.udev      = adap->dev->udev;
-               if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
-                       adap->fe_adap[i].stream.complete =
-                               dvb_usb_data_complete_204;
-               else
-               if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
-                       adap->fe_adap[i].stream.complete =
-                               dvb_usb_data_complete_raw;
-               else
-               adap->fe_adap[i].stream.complete  = dvb_usb_data_complete;
-               adap->fe_adap[i].stream.user_priv = adap;
-               ret = usb_urb_init(&adap->fe_adap[i].stream,
-                                  &adap->props.fe[i].stream);
-               if (ret < 0)
-                       break;
-       }
-       return ret;
-}
-
-int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
-{
-       int i;
-       for (i = 0; i < adap->props.num_frontends; i++)
-               usb_urb_exit(&adap->fe_adap[i].stream);
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
deleted file mode 100644 (file)
index aab0f99..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/* dvb-usb.h is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * the headerfile, all dvb-usb-drivers have to include.
- *
- * TODO: clean-up the structures for unused fields and update the comments
- */
-#ifndef __DVB_USB_H__
-#define __DVB_USB_H__
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/mutex.h>
-#include <media/rc-core.h>
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-
-#include "dvb-pll.h"
-
-#include "dvb-usb-ids.h"
-
-/* debug */
-#ifdef CONFIG_DVB_USB_DEBUG
-#define dprintk(var,level,args...) \
-           do { if ((var & level)) { printk(args); } } while (0)
-
-#define debug_dump(b,l,func) {\
-       int loop_; \
-       for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
-       func("\n");\
-}
-#define DVB_USB_DEBUG_STATUS
-#else
-#define dprintk(args...)
-#define debug_dump(b,l,func)
-
-#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
-
-#endif
-
-/* generic log methods - taken from usb.h */
-#ifndef DVB_USB_LOG_PREFIX
- #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
-#endif
-
-#undef err
-#define err(format, arg...)  printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) printk(KERN_INFO    DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-
-/**
- * struct dvb_usb_device_description - name and its according USB IDs
- * @name: real name of the box, regardless which DVB USB device class is in use
- * @cold_ids: array of struct usb_device_id which describe the device in
- *  pre-firmware state
- * @warm_ids: array of struct usb_device_id which describe the device in
- *  post-firmware state
- *
- * Each DVB USB device class can have one or more actual devices, this struct
- * assigns a name to it.
- */
-struct dvb_usb_device_description {
-       const char *name;
-
-#define DVB_USB_ID_MAX_NUM 15
-       struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
-       struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
-};
-
-static inline u8 rc5_custom(struct rc_map_table *key)
-{
-       return (key->scancode >> 8) & 0xff;
-}
-
-static inline u8 rc5_data(struct rc_map_table *key)
-{
-       return key->scancode & 0xff;
-}
-
-static inline u16 rc5_scan(struct rc_map_table *key)
-{
-       return key->scancode & 0xffff;
-}
-
-struct dvb_usb_device;
-struct dvb_usb_adapter;
-struct usb_data_stream;
-
-/**
- * Properties of USB streaming - TODO this structure should be somewhere else
- * describes the kind of USB transfer used for data-streaming.
- *  (BULK or ISOC)
- */
-struct usb_data_stream_properties {
-#define USB_BULK  1
-#define USB_ISOC  2
-       int type;
-       int count;
-       int endpoint;
-
-       union {
-               struct {
-                       int buffersize; /* per URB */
-               } bulk;
-               struct {
-                       int framesperurb;
-                       int framesize;
-                       int interval;
-               } isoc;
-       } u;
-};
-
-/**
- * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
- *    A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
- * @caps: capabilities of the DVB USB device.
- * @pid_filter_count: number of PID filter position in the optional hardware
- *  PID-filter.
- * @num_frontends: number of frontends of the DVB USB adapter.
- * @frontend_ctrl: called to power on/off active frontend.
- * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
- *  device (not URB submitting/killing).
- * @pid_filter_ctrl: called to en/disable the PID filter, if any.
- * @pid_filter: called to set/unset a PID for filtering.
- * @frontend_attach: called to attach the possible frontends (fill fe-field
- *  of struct dvb_usb_device).
- * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
- *  pll_desc and pll_init_buf of struct dvb_usb_device).
- * @stream: configuration of the USB streaming
- */
-struct dvb_usb_adapter_fe_properties {
-#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
-#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
-#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
-#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS         0x08
-#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD         0x10
-       int caps;
-       int pid_filter_count;
-
-       int (*streaming_ctrl)  (struct dvb_usb_adapter *, int);
-       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
-       int (*pid_filter)      (struct dvb_usb_adapter *, int, u16, int);
-
-       int (*frontend_attach) (struct dvb_usb_adapter *);
-       int (*tuner_attach)    (struct dvb_usb_adapter *);
-
-       struct usb_data_stream_properties stream;
-
-       int size_of_priv;
-};
-
-#define MAX_NO_OF_FE_PER_ADAP 3
-struct dvb_usb_adapter_properties {
-       int size_of_priv;
-
-       int (*frontend_ctrl)   (struct dvb_frontend *, int);
-
-       int num_frontends;
-       struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP];
-};
-
-/**
- * struct dvb_rc_legacy - old properties of remote controller
- * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
- *  remote control handling).
- * @rc_map_size: number of items in @rc_map_table.
- * @rc_query: called to query an event event.
- * @rc_interval: time in ms between two queries.
- */
-struct dvb_rc_legacy {
-/* remote control properties */
-#define REMOTE_NO_KEY_PRESSED      0x00
-#define REMOTE_KEY_PRESSED         0x01
-#define REMOTE_KEY_REPEAT          0x02
-       struct rc_map_table  *rc_map_table;
-       int rc_map_size;
-       int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
-       int rc_interval;
-};
-
-/**
- * struct dvb_rc properties of remote controller, using rc-core
- * @rc_codes: name of rc codes table
- * @protocol: type of protocol(s) currently used by the driver
- * @allowed_protos: protocol(s) supported by the driver
- * @driver_type: Used to point if a device supports raw mode
- * @change_protocol: callback to change protocol
- * @rc_query: called to query an event event.
- * @rc_interval: time in ms between two queries.
- * @bulk_mode: device supports bulk mode for RC (disable polling mode)
- */
-struct dvb_rc {
-       char *rc_codes;
-       u64 protocol;
-       u64 allowed_protos;
-       enum rc_driver_type driver_type;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
-       char *module_name;
-       int (*rc_query) (struct dvb_usb_device *d);
-       int rc_interval;
-       bool bulk_mode;                         /* uses bulk mode */
-};
-
-/**
- * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one
- *                    based on rc-core
- * This is initialized/used only inside dvb-usb-remote.c.
- * It shouldn't be set by the drivers.
- */
-enum dvb_usb_mode {
-       DVB_RC_LEGACY,
-       DVB_RC_CORE,
-};
-
-/**
- * struct dvb_usb_device_properties - properties of a dvb-usb-device
- * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
- *  download.
- * @firmware: name of the firmware file.
- * @download_firmware: called to download the firmware when the usb_ctrl is
- *  DEVICE_SPECIFIC.
- * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
- *  so do the warm initialization right after it
- *
- * @size_of_priv: how many bytes shall be allocated for the private field
- *  of struct dvb_usb_device.
- *
- * @power_ctrl: called to enable/disable power of the device.
- * @read_mac_address: called to read the MAC address of the device.
- * @identify_state: called to determine the state (cold or warm), when it
- *  is not distinguishable by the USB IDs.
- *
- * @rc: remote controller properties
- *
- * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
- *
- * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
- *  endpoint which received control messages with bulk transfers. When this
- *  is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
- *  helper functions.
- *
- * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
- *  endpoint for responses to control messages sent with bulk transfers via
- *  the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
- *  instead of the generic_bulk_ctrl_endpoint when reading usb responses in
- *  the dvb_usb_generic_rw helper function.
- *
- * @num_device_descs: number of struct dvb_usb_device_description in @devices
- * @devices: array of struct dvb_usb_device_description compatibles with these
- *  properties.
- */
-#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
-struct dvb_usb_device_properties {
-
-#define DVB_USB_IS_AN_I2C_ADAPTER            0x01
-       int caps;
-
-#define DEVICE_SPECIFIC 0
-#define CYPRESS_AN2135  1
-#define CYPRESS_AN2235  2
-#define CYPRESS_FX2     3
-       int        usb_ctrl;
-       int        (*download_firmware) (struct usb_device *, const struct firmware *);
-       const char *firmware;
-       int        no_reconnect;
-
-       int size_of_priv;
-
-       int num_adapters;
-       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-
-       int (*power_ctrl)       (struct dvb_usb_device *, int);
-       int (*read_mac_address) (struct dvb_usb_device *, u8 []);
-       int (*identify_state)   (struct usb_device *, struct dvb_usb_device_properties *,
-                       struct dvb_usb_device_description **, int *);
-
-       struct {
-               enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */
-               struct dvb_rc_legacy legacy;
-               struct dvb_rc core;
-       } rc;
-
-       struct i2c_algorithm *i2c_algo;
-
-       int generic_bulk_ctrl_endpoint;
-       int generic_bulk_ctrl_endpoint_response;
-
-       int num_device_descs;
-       struct dvb_usb_device_description devices[12];
-};
-
-/**
- * struct usb_data_stream - generic object of an USB stream
- * @buf_num: number of buffer allocated.
- * @buf_size: size of each buffer in buf_list.
- * @buf_list: array containing all allocate buffers for streaming.
- * @dma_addr: list of dma_addr_t for each buffer in buf_list.
- *
- * @urbs_initialized: number of URBs initialized.
- * @urbs_submitted: number of URBs submitted.
- */
-#define MAX_NO_URBS_FOR_DATA_STREAM 10
-struct usb_data_stream {
-       struct usb_device                 *udev;
-       struct usb_data_stream_properties  props;
-
-#define USB_STATE_INIT    0x00
-#define USB_STATE_URB_BUF 0x01
-       int state;
-
-       void (*complete) (struct usb_data_stream *, u8 *, size_t);
-
-       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       int            buf_num;
-       unsigned long  buf_size;
-       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
-
-       int urbs_initialized;
-       int urbs_submitted;
-
-       void *user_priv;
-};
-
-/**
- * struct dvb_usb_adapter - a DVB adapter on a USB device
- * @id: index of this adapter (starting with 0).
- *
- * @feedcount: number of reqested feeds (used for streaming-activation)
- * @pid_filtering: is hardware pid_filtering used or not.
- *
- * @pll_addr: I2C address of the tuner for programming
- * @pll_init: array containing the initialization buffer
- * @pll_desc: pointer to the appropriate struct dvb_pll_desc
- * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
- *
- * @dvb_adap: device's dvb_adapter.
- * @dmxdev: device's dmxdev.
- * @demux: device's software demuxer.
- * @dvb_net: device's dvb_net interfaces.
- * @dvb_frontend: device's frontend.
- * @max_feed_count: how many feeds can be handled simultaneously by this
- *  device
- *
- * @fe_init:  rerouted frontend-init (wakeup) function.
- * @fe_sleep: rerouted frontend-sleep function.
- *
- * @stream: the usb data stream.
- */
-struct dvb_usb_fe_adapter {
-       struct dvb_frontend *fe;
-
-       int (*fe_init)  (struct dvb_frontend *);
-       int (*fe_sleep) (struct dvb_frontend *);
-
-       struct usb_data_stream stream;
-
-       int pid_filtering;
-       int max_feed_count;
-
-       void *priv;
-};
-
-struct dvb_usb_adapter {
-       struct dvb_usb_device *dev;
-       struct dvb_usb_adapter_properties props;
-
-#define DVB_USB_ADAP_STATE_INIT 0x000
-#define DVB_USB_ADAP_STATE_DVB  0x001
-       int state;
-
-       u8  id;
-
-       int feedcount;
-
-       /* dvb */
-       struct dvb_adapter   dvb_adap;
-       struct dmxdev        dmxdev;
-       struct dvb_demux     demux;
-       struct dvb_net       dvb_net;
-
-       struct dvb_usb_fe_adapter fe_adap[MAX_NO_OF_FE_PER_ADAP];
-       int active_fe;
-       int num_frontends_initialized;
-
-       void *priv;
-};
-
-/**
- * struct dvb_usb_device - object of a DVB USB device
- * @props: copy of the struct dvb_usb_properties this device belongs to.
- * @desc: pointer to the device's struct dvb_usb_device_description.
- * @state: initialization and runtime state of the device.
- *
- * @powered: indicated whether the device is power or not.
- *  Powered is in/decremented for each call to modify the state.
- * @udev: pointer to the device's struct usb_device.
- *
- * @usb_mutex: semaphore of USB control messages (reading needs two messages)
- * @i2c_mutex: semaphore for i2c-transfers
- *
- * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
- *
- * @rc_dev: rc device for the remote control (rc-core mode)
- * @input_dev: input device for the remote control (legacy mode)
- * @rc_query_work: struct work_struct frequent rc queries
- * @last_event: last triggered event
- * @last_state: last state (no, pressed, repeat)
- * @owner: owner of the dvb_adapter
- * @priv: private data of the actual driver (allocate by dvb-usb, size defined
- *  in size_of_priv of dvb_usb_properties).
- */
-struct dvb_usb_device {
-       struct dvb_usb_device_properties props;
-       struct dvb_usb_device_description *desc;
-
-       struct usb_device *udev;
-
-#define DVB_USB_STATE_INIT        0x000
-#define DVB_USB_STATE_I2C         0x001
-#define DVB_USB_STATE_DVB         0x002
-#define DVB_USB_STATE_REMOTE      0x004
-       int state;
-
-       int powered;
-
-       /* locking */
-       struct mutex usb_mutex;
-
-       /* i2c */
-       struct mutex i2c_mutex;
-       struct i2c_adapter i2c_adap;
-
-       int                    num_adapters_initialized;
-       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-
-       /* remote control */
-       struct rc_dev *rc_dev;
-       struct input_dev *input_dev;
-       char rc_phys[64];
-       struct delayed_work rc_query_work;
-       u32 last_event;
-       int last_state;
-
-       struct module *owner;
-
-       void *priv;
-};
-
-extern int dvb_usb_device_init(struct usb_interface *,
-                              struct dvb_usb_device_properties *,
-                              struct module *, struct dvb_usb_device **,
-                              short *adapter_nums);
-extern void dvb_usb_device_exit(struct usb_interface *);
-
-/* the generic read/write method for device control */
-extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
-extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
-
-/* commonly used remote control parsing */
-extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
-
-/* commonly used firmware download types and function */
-struct hexline {
-       u8 len;
-       u32 addr;
-       u8 type;
-       u8 data[255];
-       u8 chk;
-};
-extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
-extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
-
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c b/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c
deleted file mode 100644 (file)
index 384fe8e..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-/* dvb-usb-dvb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for initializing and handling the
- * linux-dvb API.
- */
-#include "dvb_usb_common.h"
-
-static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_204(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
-}
-
-int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-
-       adap->stream.udev = adap_to_d(adap)->udev;
-       adap->stream.user_priv = adap;
-       adap->stream.complete = dvb_usb_data_complete;
-
-       return usb_urb_initv2(&adap->stream, &adap->props->stream);
-}
-
-int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-       usb_urb_exitv2(&adap->stream);
-
-       return 0;
-}
-
-/* does the complete input transfer handling */
-static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int count)
-{
-       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       pr_debug("%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: " \
-                       "%04x (%04d) at index %d '%s'\n", __func__, adap->id,
-                       adap->active_fe, dvbdmxfeed->type,
-                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
-                       dvbdmxfeed->pid, dvbdmxfeed->index,
-                       (count == 1) ? "on" : "off");
-
-       if (adap->active_fe == -1)
-               return -EINVAL;
-
-       adap->feed_count += count;
-
-       /* stop feeding if it is last pid */
-       if (adap->feed_count == 0) {
-               pr_debug("%s: stop feeding\n", __func__);
-               usb_urb_killv2(&adap->stream);
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(adap, 0);
-                       if (ret < 0) {
-                               pr_err("%s: streaming_ctrl() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-               mutex_unlock(&adap->sync_mutex);
-       }
-
-       /* activate the pid on the device pid filter */
-       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                       adap->pid_filtering &&
-                       adap->props->pid_filter)
-               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
-                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
-                       if (ret < 0)
-                               pr_err("%s: pid_filter() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-
-       /* start feeding if it is first pid */
-       if (adap->feed_count == 1 && count == 1) {
-               struct usb_data_stream_properties stream_props;
-               mutex_lock(&adap->sync_mutex);
-               pr_debug("%s: start feeding\n", __func__);
-
-               /* resolve input and output streaming paramters */
-               if (d->props->get_stream_config) {
-                       memcpy(&stream_props, &adap->props->stream,
-                               sizeof(struct usb_data_stream_properties));
-                       ret = d->props->get_stream_config(
-                                       adap->fe[adap->active_fe],
-                                       &adap->ts_type, &stream_props);
-                       if (ret < 0)
-                               goto err_mutex_unlock;
-               } else {
-                       stream_props = adap->props->stream;
-               }
-
-               switch (adap->ts_type) {
-               case DVB_USB_FE_TS_TYPE_204:
-                       adap->stream.complete = dvb_usb_data_complete_204;
-                       break;
-               case DVB_USB_FE_TS_TYPE_RAW:
-                       adap->stream.complete = dvb_usb_data_complete_raw;
-                       break;
-               case DVB_USB_FE_TS_TYPE_188:
-               default:
-                       adap->stream.complete = dvb_usb_data_complete;
-                       break;
-               }
-
-               usb_urb_submitv2(&adap->stream, &stream_props);
-
-               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                               adap->props->caps &
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
-                               adap->props->pid_filter_ctrl) {
-                       ret = adap->props->pid_filter_ctrl(adap,
-                                       adap->pid_filtering);
-                       if (ret < 0) {
-                               pr_err("%s: pid_filter_ctrl() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(adap, 1);
-                       if (ret < 0) {
-                               pr_err("%s: streaming_ctrl() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-       }
-
-       return 0;
-err_mutex_unlock:
-       mutex_unlock(&adap->sync_mutex);
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
-}
-
-static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
-}
-
-int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-
-       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
-                       &d->udev->dev, d->props->adapter_nr);
-       if (ret < 0) {
-               pr_debug("%s: dvb_register_adapter() failed=%d\n", __func__,
-                               ret);
-               goto err;
-       }
-
-       adap->dvb_adap.priv = adap;
-
-       if (d->props->read_mac_address) {
-               ret = d->props->read_mac_address(adap,
-                               adap->dvb_adap.proposed_mac);
-               if (ret < 0)
-                       goto err_dmx;
-
-               pr_info("%s: MAC address: %pM\n", KBUILD_MODNAME,
-                               adap->dvb_adap.proposed_mac);
-       }
-
-       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       adap->demux.priv             = adap;
-       adap->demux.filternum        = 0;
-       if (adap->demux.filternum < adap->max_feed_count)
-               adap->demux.filternum = adap->max_feed_count;
-       adap->demux.feednum          = adap->demux.filternum;
-       adap->demux.start_feed       = dvb_usb_start_feed;
-       adap->demux.stop_feed        = dvb_usb_stop_feed;
-       adap->demux.write_to_decoder = NULL;
-       ret = dvb_dmx_init(&adap->demux);
-       if (ret < 0) {
-               pr_err("%s: dvb_dmx_init() failed=%d\n", KBUILD_MODNAME, ret);
-               goto err_dmx;
-       }
-
-       adap->dmxdev.filternum       = adap->demux.filternum;
-       adap->dmxdev.demux           = &adap->demux.dmx;
-       adap->dmxdev.capabilities    = 0;
-       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
-       if (ret < 0) {
-               pr_err("%s: dvb_dmxdev_init() failed=%d\n", KBUILD_MODNAME,
-                               ret);
-               goto err_dmx_dev;
-       }
-
-       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
-       if (ret < 0) {
-               pr_err("%s: dvb_net_init() failed=%d\n", KBUILD_MODNAME, ret);
-               goto err_net_init;
-       }
-
-       mutex_init(&adap->sync_mutex);
-
-       return 0;
-err_net_init:
-       dvb_dmxdev_release(&adap->dmxdev);
-err_dmx_dev:
-       dvb_dmx_release(&adap->demux);
-err_dmx:
-       dvb_unregister_adapter(&adap->dvb_adap);
-err:
-       adap->dvb_adap.priv = NULL;
-       return ret;
-}
-
-int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-
-       if (adap->dvb_adap.priv) {
-               dvb_net_release(&adap->dvb_net);
-               adap->demux.dmx.close(&adap->demux.dmx);
-               dvb_dmxdev_release(&adap->dmxdev);
-               dvb_dmx_release(&adap->demux);
-               dvb_unregister_adapter(&adap->dvb_adap);
-       }
-
-       return 0;
-}
-
-static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
-
-       ret = dvb_usbv2_device_power_ctrl(d, 1);
-       if (ret < 0)
-               goto err;
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 1);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (adap->fe_init[fe->id]) {
-               ret = adap->fe_init[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       adap->active_fe = fe->id;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
-
-       if (adap->fe_sleep[fe->id]) {
-               ret = adap->fe_sleep[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 0);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_device_power_ctrl(d, 0);
-       if (ret < 0)
-               goto err;
-
-       adap->active_fe = -1;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
-{
-       int ret, i, count_registered = 0;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-
-       memset(adap->fe, 0, sizeof(adap->fe));
-       adap->active_fe = -1;
-
-       if (d->props->frontend_attach) {
-               ret = d->props->frontend_attach(adap);
-               if (ret < 0) {
-                       pr_debug("%s: frontend_attach() failed=%d\n", __func__,
-                                       ret);
-                       goto err_dvb_frontend_detach;
-               }
-       } else {
-               pr_debug("%s: frontend_attach() do not exists\n", __func__);
-               ret = 0;
-               goto err;
-       }
-
-       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
-               adap->fe[i]->id = i;
-
-               /* re-assign sleep and wakeup functions */
-               adap->fe_init[i] = adap->fe[i]->ops.init;
-               adap->fe[i]->ops.init  = dvb_usb_fe_wakeup;
-               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
-               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
-
-               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
-               if (ret < 0) {
-                       pr_err("%s: frontend%d registration failed\n",
-                                       KBUILD_MODNAME, i);
-                       goto err_dvb_unregister_frontend;
-               }
-
-               count_registered++;
-       }
-
-       if (d->props->tuner_attach) {
-               ret = d->props->tuner_attach(adap);
-               if (ret < 0) {
-                       pr_debug("%s: tuner_attach() failed=%d\n", __func__,
-                                       ret);
-                       goto err_dvb_unregister_frontend;
-               }
-       }
-
-       return 0;
-
-err_dvb_unregister_frontend:
-       for (i = count_registered - 1; i >= 0; i--)
-               dvb_unregister_frontend(adap->fe[i]);
-
-err_dvb_frontend_detach:
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i])
-                       dvb_frontend_detach(adap->fe[i]);
-       }
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
-{
-       int i;
-       pr_debug("%s: adap=%d\n", __func__, adap->id);
-
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i]) {
-                       dvb_unregister_frontend(adap->fe[i]);
-                       dvb_frontend_detach(adap->fe[i]);
-               }
-       }
-
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c
deleted file mode 100644 (file)
index f856ab6..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* dvb-usb-remote.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file contains functions for initializing the input-device and for
- * handling remote-control-queries.
- */
-#include "dvb_usb_common.h"
-#include <linux/usb/input.h>
-
-/* Remote-control poll function - called every dib->rc_query_interval ms to see
- * whether the remote control has received anything.
- *
- * TODO: Fix the repeat rate of the input device.
- */
-static void dvb_usb_read_remote_control(struct work_struct *work)
-{
-       struct dvb_usb_device *d = container_of(work,
-                       struct dvb_usb_device, rc_query_work.work);
-       int ret;
-
-       /* TODO: need a lock here.  We can simply skip checking for the remote
-          control if we're busy. */
-
-       /* when the parameter has been set to 1 via sysfs while the
-        * driver was running, or when bulk mode is enabled after IR init
-        */
-       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
-               return;
-
-       ret = d->rc.query(d);
-       if (ret < 0)
-               pr_err("%s: error %d while querying for an remote control " \
-                               "event\n", KBUILD_MODNAME, ret);
-
-       schedule_delayed_work(&d->rc_query_work,
-                             msecs_to_jiffies(d->rc.interval));
-}
-
-int dvb_usbv2_remote_init(struct dvb_usb_device *d)
-{
-       int ret;
-       struct rc_dev *dev;
-
-       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
-               return 0;
-
-       ret = d->props->get_rc_config(d, &d->rc);
-       if (ret < 0)
-               goto err;
-
-       dev = rc_allocate_device();
-       if (!dev) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       dev->dev.parent = &d->udev->dev;
-       dev->input_name = "IR-receiver inside an USB DVB receiver";
-       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-       dev->input_phys = d->rc_phys;
-       usb_to_input_id(d->udev, &dev->input_id);
-       /* TODO: likely RC-core should took const char * */
-       dev->driver_name = (char *) d->props->driver_name;
-       dev->driver_type = d->rc.driver_type;
-       dev->allowed_protos = d->rc.allowed_protos;
-       dev->change_protocol = d->rc.change_protocol;
-       dev->priv = d;
-       /* select used keymap */
-       if (d->rc.map_name)
-               dev->map_name = d->rc.map_name;
-       else if (d->rc_map)
-               dev->map_name = d->rc_map;
-       else
-               dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
-
-       ret = rc_register_device(dev);
-       if (ret < 0) {
-               rc_free_device(dev);
-               goto err;
-       }
-
-       d->input_dev = NULL;
-       d->rc_dev = dev;
-
-       /* start polling if needed */
-       if (d->rc.query && !d->rc.bulk_mode) {
-               /* initialize a work queue for handling polling */
-               INIT_DELAYED_WORK(&d->rc_query_work,
-                               dvb_usb_read_remote_control);
-               pr_info("%s: schedule remote query interval to %d msecs\n",
-                               KBUILD_MODNAME, d->rc.interval);
-               schedule_delayed_work(&d->rc_query_work,
-                               msecs_to_jiffies(d->rc.interval));
-       }
-
-       d->state |= DVB_USB_STATE_REMOTE;
-
-       return 0;
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
-{
-       if (d->state & DVB_USB_STATE_REMOTE) {
-               cancel_delayed_work_sync(&d->rc_query_work);
-               rc_unregister_device(d->rc_dev);
-       }
-
-       d->state &= ~DVB_USB_STATE_REMOTE;
-
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
deleted file mode 100644 (file)
index 9382895..0000000
+++ /dev/null
@@ -1,1951 +0,0 @@
-/* DVB USB framework compliant Linux driver for the
- *     DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
- *     TeVii S600, S630, S650, S660, S480,
- *     Prof 1100, 7500,
- *     Geniatech SU3000 Cards
- * Copyright (C) 2008-2011 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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dw2102.h"
-#include "si21xx.h"
-#include "stv0299.h"
-#include "z0194a.h"
-#include "stv0288.h"
-#include "stb6000.h"
-#include "eds1547.h"
-#include "cx24116.h"
-#include "tda1002x.h"
-#include "mt312.h"
-#include "zl10039.h"
-#include "ds3000.h"
-#include "stv0900.h"
-#include "stv6110.h"
-#include "stb6100.h"
-#include "stb6100_proc.h"
-
-#ifndef USB_PID_DW2102
-#define USB_PID_DW2102 0x2102
-#endif
-
-#ifndef USB_PID_DW2104
-#define USB_PID_DW2104 0x2104
-#endif
-
-#ifndef USB_PID_DW3101
-#define USB_PID_DW3101 0x3101
-#endif
-
-#ifndef USB_PID_CINERGY_S
-#define USB_PID_CINERGY_S 0x0064
-#endif
-
-#ifndef USB_PID_TEVII_S630
-#define USB_PID_TEVII_S630 0xd630
-#endif
-
-#ifndef USB_PID_TEVII_S650
-#define USB_PID_TEVII_S650 0xd650
-#endif
-
-#ifndef USB_PID_TEVII_S660
-#define USB_PID_TEVII_S660 0xd660
-#endif
-
-#ifndef USB_PID_TEVII_S480_1
-#define USB_PID_TEVII_S480_1 0xd481
-#endif
-
-#ifndef USB_PID_TEVII_S480_2
-#define USB_PID_TEVII_S480_2 0xd482
-#endif
-
-#ifndef USB_PID_PROF_1100
-#define USB_PID_PROF_1100 0xb012
-#endif
-
-#define DW210X_READ_MSG 0
-#define DW210X_WRITE_MSG 1
-
-#define REG_1F_SYMBOLRATE_BYTE0 0x1f
-#define REG_20_SYMBOLRATE_BYTE1 0x20
-#define REG_21_SYMBOLRATE_BYTE2 0x21
-/* on my own*/
-#define DW2102_VOLTAGE_CTRL (0x1800)
-#define SU3000_STREAM_CTRL (0x1900)
-#define DW2102_RC_QUERY (0x1a00)
-#define DW2102_LED_CTRL (0x1b00)
-
-#define        err_str "did not find the firmware file. (%s) " \
-               "Please see linux/Documentation/dvb/ for more details " \
-               "on firmware-problems."
-
-struct rc_map_dvb_usb_table_table {
-       struct rc_map_table *rc_keys;
-       int rc_keys_size;
-};
-
-struct su3000_state {
-       u8 initialized;
-};
-
-struct s6x0_state {
-       int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
-};
-
-/* debug */
-static int dvb_usb_dw2102_debug;
-module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
-                                               DVB_USB_DEBUG_STATUS);
-
-/* keymaps */
-static int ir_keymap;
-module_param_named(keymap, ir_keymap, int, 0644);
-MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ..."
-                       " 256=none");
-
-/* demod probe */
-static int demod_probe = 1;
-module_param_named(demod, demod_probe, int, 0644);
-MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
-                       "4=stv0903+stb6100(or-able)).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
-                       u16 index, u8 * data, u16 len, int flags)
-{
-       int ret;
-       u8 *u8buf;
-       unsigned int pipe = (flags == DW210X_READ_MSG) ?
-                               usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
-       u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
-
-       u8buf = kmalloc(len, GFP_KERNEL);
-       if (!u8buf)
-               return -ENOMEM;
-
-
-       if (flags == DW210X_WRITE_MSG)
-               memcpy(u8buf, data, len);
-       ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
-                               value, index , u8buf, len, 2000);
-
-       if (flags == DW210X_READ_MSG)
-               memcpy(data, u8buf, len);
-
-       kfree(u8buf);
-       return ret;
-}
-
-/* I2C */
-static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-               int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i = 0;
-       u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
-       u16 value;
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       switch (num) {
-       case 2:
-               /* read stv0299 register */
-               value = msg[0].buf[0];/* register */
-               for (i = 0; i < msg[1].len; i++) {
-                       dw210x_op_rw(d->udev, 0xb5, value + i, 0,
-                                       buf6, 2, DW210X_READ_MSG);
-                       msg[1].buf[i] = buf6[0];
-               }
-               break;
-       case 1:
-               switch (msg[0].addr) {
-               case 0x68:
-                       /* write to stv0299 register */
-                       buf6[0] = 0x2a;
-                       buf6[1] = msg[0].buf[0];
-                       buf6[2] = msg[0].buf[1];
-                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                       buf6, 3, DW210X_WRITE_MSG);
-                       break;
-               case 0x60:
-                       if (msg[0].flags == 0) {
-                       /* write to tuner pll */
-                               buf6[0] = 0x2c;
-                               buf6[1] = 5;
-                               buf6[2] = 0xc0;
-                               buf6[3] = msg[0].buf[0];
-                               buf6[4] = msg[0].buf[1];
-                               buf6[5] = msg[0].buf[2];
-                               buf6[6] = msg[0].buf[3];
-                               dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                               buf6, 7, DW210X_WRITE_MSG);
-                       } else {
-                       /* read from tuner */
-                               dw210x_op_rw(d->udev, 0xb5, 0, 0,
-                                               buf6, 1, DW210X_READ_MSG);
-                               msg[0].buf[0] = buf6[0];
-                       }
-                       break;
-               case (DW2102_RC_QUERY):
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       buf6, 2, DW210X_READ_MSG);
-                       msg[0].buf[0] = buf6[0];
-                       msg[0].buf[1] = buf6[1];
-                       break;
-               case (DW2102_VOLTAGE_CTRL):
-                       buf6[0] = 0x30;
-                       buf6[1] = msg[0].buf[0];
-                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                       buf6, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-
-               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
-                                               struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       switch (num) {
-       case 2:
-               /* read si2109 register by number */
-               buf6[0] = msg[0].addr << 1;
-               buf6[1] = msg[0].len;
-               buf6[2] = msg[0].buf[0];
-               dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                               buf6, msg[0].len + 2, DW210X_WRITE_MSG);
-               /* read si2109 register */
-               dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
-                               buf6, msg[1].len + 2, DW210X_READ_MSG);
-               memcpy(msg[1].buf, buf6 + 2, msg[1].len);
-
-               break;
-       case 1:
-               switch (msg[0].addr) {
-               case 0x68:
-                       /* write to si2109 register */
-                       buf6[0] = msg[0].addr << 1;
-                       buf6[1] = msg[0].len;
-                       memcpy(buf6 + 2, msg[0].buf, msg[0].len);
-                       dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
-                                       msg[0].len + 2, DW210X_WRITE_MSG);
-                       break;
-               case(DW2102_RC_QUERY):
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       buf6, 2, DW210X_READ_MSG);
-                       msg[0].buf[0] = buf6[0];
-                       msg[0].buf[1] = buf6[1];
-                       break;
-               case(DW2102_VOLTAGE_CTRL):
-                       buf6[0] = 0x30;
-                       buf6[1] = msg[0].buf[0];
-                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                       buf6, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       switch (num) {
-       case 2: {
-               /* read */
-               /* first write first register number */
-               u8 ibuf[msg[1].len + 2], obuf[3];
-               obuf[0] = msg[0].addr << 1;
-               obuf[1] = msg[0].len;
-               obuf[2] = msg[0].buf[0];
-               dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-               /* second read registers */
-               dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
-                               ibuf, msg[1].len + 2, DW210X_READ_MSG);
-               memcpy(msg[1].buf, ibuf + 2, msg[1].len);
-
-               break;
-       }
-       case 1:
-               switch (msg[0].addr) {
-               case 0x68: {
-                       /* write to register */
-                       u8 obuf[msg[0].len + 2];
-                       obuf[0] = msg[0].addr << 1;
-                       obuf[1] = msg[0].len;
-                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
-                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               case 0x61: {
-                       /* write to tuner */
-                       u8 obuf[msg[0].len + 2];
-                       obuf[0] = msg[0].addr << 1;
-                       obuf[1] = msg[0].len;
-                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
-                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               case(DW2102_RC_QUERY): {
-                       u8 ibuf[2];
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       ibuf, 2, DW210X_READ_MSG);
-                       memcpy(msg[0].buf, ibuf , 2);
-                       break;
-               }
-               case(DW2102_VOLTAGE_CTRL): {
-                       u8 obuf[2];
-                       obuf[0] = 0x30;
-                       obuf[1] = msg[0].buf[0];
-                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                       obuf, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               }
-
-               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int len, i, j;
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (j = 0; j < num; j++) {
-               switch (msg[j].addr) {
-               case(DW2102_RC_QUERY): {
-                       u8 ibuf[2];
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       ibuf, 2, DW210X_READ_MSG);
-                       memcpy(msg[j].buf, ibuf , 2);
-                       break;
-               }
-               case(DW2102_VOLTAGE_CTRL): {
-                       u8 obuf[2];
-                       obuf[0] = 0x30;
-                       obuf[1] = msg[j].buf[0];
-                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
-                                       obuf, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               /*case 0x55: cx24116
-               case 0x6a: stv0903
-               case 0x68: ds3000, stv0903
-               case 0x60: ts2020, stv6110, stb6100 */
-               default: {
-                       if (msg[j].flags == I2C_M_RD) {
-                               /* read registers */
-                               u8  ibuf[msg[j].len + 2];
-                               dw210x_op_rw(d->udev, 0xc3,
-                                               (msg[j].addr << 1) + 1, 0,
-                                               ibuf, msg[j].len + 2,
-                                               DW210X_READ_MSG);
-                               memcpy(msg[j].buf, ibuf + 2, msg[j].len);
-                       mdelay(10);
-                       } else if (((msg[j].buf[0] == 0xb0) &&
-                                               (msg[j].addr == 0x68)) ||
-                                               ((msg[j].buf[0] == 0xf7) &&
-                                               (msg[j].addr == 0x55))) {
-                               /* write firmware */
-                               u8 obuf[19];
-                               obuf[0] = msg[j].addr << 1;
-                               obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
-                               obuf[2] = msg[j].buf[0];
-                               len = msg[j].len - 1;
-                               i = 1;
-                               do {
-                                       memcpy(obuf + 3, msg[j].buf + i,
-                                                       (len > 16 ? 16 : len));
-                                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                               obuf, (len > 16 ? 16 : len) + 3,
-                                               DW210X_WRITE_MSG);
-                                       i += 16;
-                                       len -= 16;
-                               } while (len > 0);
-                       } else {
-                               /* write registers */
-                               u8 obuf[msg[j].len + 2];
-                               obuf[0] = msg[j].addr << 1;
-                               obuf[1] = msg[j].len;
-                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
-                               dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                               obuf, msg[j].len + 2,
-                                               DW210X_WRITE_MSG);
-                       }
-                       break;
-               }
-               }
-
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                                               int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       switch (num) {
-       case 2: {
-               /* read */
-               /* first write first register number */
-               u8 ibuf[msg[1].len + 2], obuf[3];
-               obuf[0] = msg[0].addr << 1;
-               obuf[1] = msg[0].len;
-               obuf[2] = msg[0].buf[0];
-               dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-               /* second read registers */
-               dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
-                               ibuf, msg[1].len + 2, DW210X_READ_MSG);
-               memcpy(msg[1].buf, ibuf + 2, msg[1].len);
-
-               break;
-       }
-       case 1:
-               switch (msg[0].addr) {
-               case 0x60:
-               case 0x0c: {
-                       /* write to register */
-                       u8 obuf[msg[0].len + 2];
-                       obuf[0] = msg[0].addr << 1;
-                       obuf[1] = msg[0].len;
-                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
-                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
-                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               case(DW2102_RC_QUERY): {
-                       u8 ibuf[2];
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       ibuf, 2, DW210X_READ_MSG);
-                       memcpy(msg[0].buf, ibuf , 2);
-                       break;
-               }
-               }
-
-               break;
-       }
-
-       for (i = 0; i < num; i++) {
-               deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
-                               msg[i].flags == 0 ? ">>>" : "<<<");
-               debug_dump(msg[i].buf, msg[i].len, deb_xfer);
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                                               int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct usb_device *udev;
-       int len, i, j;
-
-       if (!d)
-               return -ENODEV;
-       udev = d->udev;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (j = 0; j < num; j++) {
-               switch (msg[j].addr) {
-               case (DW2102_RC_QUERY): {
-                       u8 ibuf[5];
-                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
-                                       ibuf, 5, DW210X_READ_MSG);
-                       memcpy(msg[j].buf, ibuf + 3, 2);
-                       break;
-               }
-               case (DW2102_VOLTAGE_CTRL): {
-                       u8 obuf[2];
-
-                       obuf[0] = 1;
-                       obuf[1] = msg[j].buf[1];/* off-on */
-                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
-                                       obuf, 2, DW210X_WRITE_MSG);
-                       obuf[0] = 3;
-                       obuf[1] = msg[j].buf[0];/* 13v-18v */
-                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
-                                       obuf, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               case (DW2102_LED_CTRL): {
-                       u8 obuf[2];
-
-                       obuf[0] = 5;
-                       obuf[1] = msg[j].buf[0];
-                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
-                                       obuf, 2, DW210X_WRITE_MSG);
-                       break;
-               }
-               /*case 0x55: cx24116
-               case 0x6a: stv0903
-               case 0x68: ds3000, stv0903
-               case 0x60: ts2020, stv6110, stb6100
-               case 0xa0: eeprom */
-               default: {
-                       if (msg[j].flags == I2C_M_RD) {
-                               /* read registers */
-                               u8 ibuf[msg[j].len];
-                               dw210x_op_rw(d->udev, 0x91, 0, 0,
-                                               ibuf, msg[j].len,
-                                               DW210X_READ_MSG);
-                               memcpy(msg[j].buf, ibuf, msg[j].len);
-                               break;
-                       } else if ((msg[j].buf[0] == 0xb0) &&
-                                               (msg[j].addr == 0x68)) {
-                               /* write firmware */
-                               u8 obuf[19];
-                               obuf[0] = (msg[j].len > 16 ?
-                                               18 : msg[j].len + 1);
-                               obuf[1] = msg[j].addr << 1;
-                               obuf[2] = msg[j].buf[0];
-                               len = msg[j].len - 1;
-                               i = 1;
-                               do {
-                                       memcpy(obuf + 3, msg[j].buf + i,
-                                                       (len > 16 ? 16 : len));
-                                       dw210x_op_rw(d->udev, 0x80, 0, 0,
-                                               obuf, (len > 16 ? 16 : len) + 3,
-                                               DW210X_WRITE_MSG);
-                                       i += 16;
-                                       len -= 16;
-                               } while (len > 0);
-                       } else if (j < (num - 1)) {
-                               /* write register addr before read */
-                               u8 obuf[msg[j].len + 2];
-                               obuf[0] = msg[j + 1].len;
-                               obuf[1] = (msg[j].addr << 1);
-                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
-                               dw210x_op_rw(d->udev,
-                                               udev->descriptor.idProduct ==
-                                               0x7500 ? 0x92 : 0x90, 0, 0,
-                                               obuf, msg[j].len + 2,
-                                               DW210X_WRITE_MSG);
-                               break;
-                       } else {
-                               /* write registers */
-                               u8 obuf[msg[j].len + 2];
-                               obuf[0] = msg[j].len + 1;
-                               obuf[1] = (msg[j].addr << 1);
-                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
-                               dw210x_op_rw(d->udev, 0x80, 0, 0,
-                                               obuf, msg[j].len + 2,
-                                               DW210X_WRITE_MSG);
-                               break;
-                       }
-                       break;
-               }
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                                               int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       u8 obuf[0x40], ibuf[0x40];
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       switch (num) {
-       case 1:
-               switch (msg[0].addr) {
-               case SU3000_STREAM_CTRL:
-                       obuf[0] = msg[0].buf[0] + 0x36;
-                       obuf[1] = 3;
-                       obuf[2] = 0;
-                       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
-                               err("i2c transfer failed.");
-                       break;
-               case DW2102_RC_QUERY:
-                       obuf[0] = 0x10;
-                       if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
-                               err("i2c transfer failed.");
-                       msg[0].buf[1] = ibuf[0];
-                       msg[0].buf[0] = ibuf[1];
-                       break;
-               default:
-                       /* always i2c write*/
-                       obuf[0] = 0x08;
-                       obuf[1] = msg[0].addr;
-                       obuf[2] = msg[0].len;
-
-                       memcpy(&obuf[3], msg[0].buf, msg[0].len);
-
-                       if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-                                               ibuf, 1, 0) < 0)
-                               err("i2c transfer failed.");
-
-               }
-               break;
-       case 2:
-               /* always i2c read */
-               obuf[0] = 0x09;
-               obuf[1] = msg[0].len;
-               obuf[2] = msg[1].len;
-               obuf[3] = msg[0].addr;
-               memcpy(&obuf[4], msg[0].buf, msg[0].len);
-
-               if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-                                       ibuf, msg[1].len + 1, 0) < 0)
-                       err("i2c transfer failed.");
-
-               memcpy(msg[1].buf, &ibuf[1], msg[1].len);
-               break;
-       default:
-               warn("more than 2 i2c messages at a time is not handled yet.");
-               break;
-       }
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dw2102_i2c_algo = {
-       .master_xfer = dw2102_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm dw2102_serit_i2c_algo = {
-       .master_xfer = dw2102_serit_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm dw2102_earda_i2c_algo = {
-       .master_xfer = dw2102_earda_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm dw2104_i2c_algo = {
-       .master_xfer = dw2104_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm dw3101_i2c_algo = {
-       .master_xfer = dw3101_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm s6x0_i2c_algo = {
-       .master_xfer = s6x0_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static struct i2c_algorithm su3000_i2c_algo = {
-       .master_xfer = su3000_i2c_transfer,
-       .functionality = dw210x_i2c_func,
-};
-
-static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-{
-       int i;
-       u8 ibuf[] = {0, 0};
-       u8 eeprom[256], eepromline[16];
-
-       for (i = 0; i < 256; i++) {
-               if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
-                       err("read eeprom failed.");
-                       return -1;
-               } else {
-                       eepromline[i%16] = ibuf[0];
-                       eeprom[i] = ibuf[0];
-               }
-               if ((i % 16) == 15) {
-                       deb_xfer("%02x: ", i - 15);
-                       debug_dump(eepromline, 16, deb_xfer);
-               }
-       }
-
-       memcpy(mac, eeprom + 8, 6);
-       return 0;
-};
-
-static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-{
-       int i, ret;
-       u8 ibuf[] = { 0 }, obuf[] = { 0 };
-       u8 eeprom[256], eepromline[16];
-       struct i2c_msg msg[] = {
-               {
-                       .addr = 0xa0 >> 1,
-                       .flags = 0,
-                       .buf = obuf,
-                       .len = 1,
-               }, {
-                       .addr = 0xa0 >> 1,
-                       .flags = I2C_M_RD,
-                       .buf = ibuf,
-                       .len = 1,
-               }
-       };
-
-       for (i = 0; i < 256; i++) {
-               obuf[0] = i;
-               ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
-               if (ret != 2) {
-                       err("read eeprom failed.");
-                       return -1;
-               } else {
-                       eepromline[i % 16] = ibuf[0];
-                       eeprom[i] = ibuf[0];
-               }
-
-               if ((i % 16) == 15) {
-                       deb_xfer("%02x: ", i - 15);
-                       debug_dump(eepromline, 16, deb_xfer);
-               }
-       }
-
-       memcpy(mac, eeprom + 16, 6);
-       return 0;
-};
-
-static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       static u8 command_start[] = {0x00};
-       static u8 command_stop[] = {0x01};
-       struct i2c_msg msg = {
-               .addr = SU3000_STREAM_CTRL,
-               .flags = 0,
-               .buf = onoff ? command_start : command_stop,
-               .len = 1
-       };
-
-       i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
-
-       return 0;
-}
-
-static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
-{
-       struct su3000_state *state = (struct su3000_state *)d->priv;
-       u8 obuf[] = {0xde, 0};
-
-       info("%s: %d, initialized %d\n", __func__, i, state->initialized);
-
-       if (i && !state->initialized) {
-               state->initialized = 1;
-               /* reset board */
-               dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
-       }
-
-       return 0;
-}
-
-static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-{
-       int i;
-       u8 obuf[] = { 0x1f, 0xf0 };
-       u8 ibuf[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = 0x51,
-                       .flags = 0,
-                       .buf = obuf,
-                       .len = 2,
-               }, {
-                       .addr = 0x51,
-                       .flags = I2C_M_RD,
-                       .buf = ibuf,
-                       .len = 1,
-
-               }
-       };
-
-       for (i = 0; i < 6; i++) {
-               obuf[1] = 0xf0 + i;
-               if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
-                       break;
-               else
-                       mac[i] = ibuf[0];
-
-               debug_dump(mac, 6, printk);
-       }
-
-       return 0;
-}
-
-static int su3000_identify_state(struct usb_device *udev,
-                                struct dvb_usb_device_properties *props,
-                                struct dvb_usb_device_description **desc,
-                                int *cold)
-{
-       info("%s\n", __func__);
-
-       *cold = 0;
-       return 0;
-}
-
-static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       static u8 command_13v[] = {0x00, 0x01};
-       static u8 command_18v[] = {0x01, 0x01};
-       static u8 command_off[] = {0x00, 0x00};
-       struct i2c_msg msg = {
-               .addr = DW2102_VOLTAGE_CTRL,
-               .flags = 0,
-               .buf = command_off,
-               .len = 2,
-       };
-
-       struct dvb_usb_adapter *udev_adap =
-               (struct dvb_usb_adapter *)(fe->dvb->priv);
-       if (voltage == SEC_VOLTAGE_18)
-               msg.buf = command_18v;
-       else if (voltage == SEC_VOLTAGE_13)
-               msg.buf = command_13v;
-
-       i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
-
-       return 0;
-}
-
-static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct dvb_usb_adapter *d =
-               (struct dvb_usb_adapter *)(fe->dvb->priv);
-       struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
-
-       dw210x_set_voltage(fe, voltage);
-       if (st->old_set_voltage)
-               st->old_set_voltage(fe, voltage);
-
-       return 0;
-}
-
-static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
-{
-       static u8 led_off[] = { 0 };
-       static u8 led_on[] = { 1 };
-       struct i2c_msg msg = {
-               .addr = DW2102_LED_CTRL,
-               .flags = 0,
-               .buf = led_off,
-               .len = 1
-       };
-       struct dvb_usb_adapter *udev_adap =
-               (struct dvb_usb_adapter *)(fe->dvb->priv);
-
-       if (offon)
-               msg.buf = led_on;
-       i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
-}
-
-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 cx24116_config dw2104_config = {
-       .demod_address = 0x55,
-       .mpg_clk_pos_pol = 0x01,
-};
-
-static struct si21xx_config serit_sp1511lhb_config = {
-       .demod_address = 0x68,
-       .min_delay_ms = 100,
-
-};
-
-static struct tda10023_config dw3101_tda10023_config = {
-       .demod_address = 0x0c,
-       .invert = 1,
-};
-
-static struct mt312_config zl313_config = {
-       .demod_address = 0x0e,
-};
-
-static struct ds3000_config dw2104_ds3000_config = {
-       .demod_address = 0x68,
-};
-
-static struct stv0900_config dw2104a_stv0900_config = {
-       .demod_address = 0x6a,
-       .demod_mode = 0,
-       .xtal = 27000000,
-       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
-       .diseqc_mode = 2,/* 2/3 PWM */
-       .tun1_maddress = 0,/* 0x60 */
-       .tun1_adc = 0,/* 2 Vpp */
-       .path1_mode = 3,
-};
-
-static struct stb6100_config dw2104a_stb6100_config = {
-       .tuner_address = 0x60,
-       .refclock = 27000000,
-};
-
-static struct stv0900_config dw2104_stv0900_config = {
-       .demod_address = 0x68,
-       .demod_mode = 0,
-       .xtal = 8000000,
-       .clkmode = 3,
-       .diseqc_mode = 2,
-       .tun1_maddress = 0,
-       .tun1_adc = 1,/* 1 Vpp */
-       .path1_mode = 3,
-};
-
-static struct stv6110_config dw2104_stv6110_config = {
-       .i2c_address = 0x60,
-       .mclk = 16000000,
-       .clk_div = 1,
-};
-
-static struct stv0900_config prof_7500_stv0900_config = {
-       .demod_address = 0x6a,
-       .demod_mode = 0,
-       .xtal = 27000000,
-       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
-       .diseqc_mode = 2,/* 2/3 PWM */
-       .tun1_maddress = 0,/* 0x60 */
-       .tun1_adc = 0,/* 2 Vpp */
-       .path1_mode = 3,
-       .tun1_type = 3,
-       .set_lock_led = dw210x_led_ctrl,
-};
-
-static struct ds3000_config su3000_ds3000_config = {
-       .demod_address = 0x68,
-       .ci_mode = 1,
-};
-
-static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
-{
-       struct dvb_tuner_ops *tuner_ops = NULL;
-
-       if (demod_probe & 4) {
-               d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
-                               &d->dev->i2c_adap, 0);
-               if (d->fe_adap[0].fe != NULL) {
-                       if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
-                                       &dw2104a_stb6100_config,
-                                       &d->dev->i2c_adap)) {
-                               tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
-                               tuner_ops->set_frequency = stb6100_set_freq;
-                               tuner_ops->get_frequency = stb6100_get_freq;
-                               tuner_ops->set_bandwidth = stb6100_set_bandw;
-                               tuner_ops->get_bandwidth = stb6100_get_bandw;
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                               info("Attached STV0900+STB6100!\n");
-                               return 0;
-                       }
-               }
-       }
-
-       if (demod_probe & 2) {
-               d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
-                               &d->dev->i2c_adap, 0);
-               if (d->fe_adap[0].fe != NULL) {
-                       if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
-                                       &dw2104_stv6110_config,
-                                       &d->dev->i2c_adap)) {
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                               info("Attached STV0900+STV6110A!\n");
-                               return 0;
-                       }
-               }
-       }
-
-       if (demod_probe & 1) {
-               d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
-                               &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                       info("Attached cx24116!\n");
-                       return 0;
-               }
-       }
-
-       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
-                       &d->dev->i2c_adap);
-       if (d->fe_adap[0].fe != NULL) {
-               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-               info("Attached DS3000!\n");
-               return 0;
-       }
-
-       return -EIO;
-}
-
-static struct dvb_usb_device_properties dw2102_properties;
-static struct dvb_usb_device_properties dw2104_properties;
-static struct dvb_usb_device_properties s6x0_properties;
-
-static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
-{
-       if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
-               /*dw2102_properties.adapter->tuner_attach = NULL;*/
-               d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
-                                       &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                       info("Attached si21xx!\n");
-                       return 0;
-               }
-       }
-
-       if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
-               d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
-                                       &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
-                                       &d->dev->i2c_adap)) {
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                               info("Attached stv0288!\n");
-                               return 0;
-                       }
-               }
-       }
-
-       if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
-               /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
-               d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
-                                       &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                       info("Attached stv0299!\n");
-                       return 0;
-               }
-       }
-       return -EIO;
-}
-
-static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
-{
-       d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
-                               &d->dev->i2c_adap, 0x48);
-       if (d->fe_adap[0].fe != NULL) {
-               info("Attached tda10023!\n");
-               return 0;
-       }
-       return -EIO;
-}
-
-static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
-{
-       d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
-                       &d->dev->i2c_adap);
-       if (d->fe_adap[0].fe != NULL) {
-               if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
-                               &d->dev->i2c_adap)) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-                       info("Attached zl100313+zl10039!\n");
-                       return 0;
-               }
-       }
-
-       return -EIO;
-}
-
-static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
-{
-       u8 obuf[] = {7, 1};
-
-       d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
-                       &d->dev->i2c_adap);
-
-       if (d->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
-               return -EIO;
-
-       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
-
-       info("Attached stv0288+stb6000!\n");
-
-       return 0;
-
-}
-
-static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
-{
-       struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
-       u8 obuf[] = {7, 1};
-
-       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
-                       &d->dev->i2c_adap);
-
-       if (d->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
-       d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
-
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
-
-       info("Attached ds3000+ds2020!\n");
-
-       return 0;
-}
-
-static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
-{
-       u8 obuf[] = {7, 1};
-
-       d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
-                                       &d->dev->i2c_adap, 0);
-       if (d->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
-
-       info("Attached STV0900+STB6100A!\n");
-
-       return 0;
-}
-
-static int su3000_frontend_attach(struct dvb_usb_adapter *d)
-{
-       u8 obuf[3] = { 0xe, 0x80, 0 };
-       u8 ibuf[] = { 0 };
-
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-               err("command 0x0e transfer failed.");
-
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 0;
-
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-               err("command 0x0e transfer failed.");
-
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 1;
-
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-               err("command 0x0e transfer failed.");
-
-       obuf[0] = 0x51;
-
-       if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
-               err("command 0x51 transfer failed.");
-
-       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
-                                       &d->dev->i2c_adap);
-       if (d->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       info("Attached DS3000!\n");
-
-       return 0;
-}
-
-static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
-               &adap->dev->i2c_adap, DVB_PLL_OPERA1);
-       return 0;
-}
-
-static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
-               &adap->dev->i2c_adap, DVB_PLL_TUA6034);
-
-       return 0;
-}
-
-static struct rc_map_table rc_map_dw210x_table[] = {
-       { 0xf80a, KEY_POWER2 },         /*power*/
-       { 0xf80c, KEY_MUTE },           /*mute*/
-       { 0xf811, KEY_1 },
-       { 0xf812, KEY_2 },
-       { 0xf813, KEY_3 },
-       { 0xf814, KEY_4 },
-       { 0xf815, KEY_5 },
-       { 0xf816, KEY_6 },
-       { 0xf817, KEY_7 },
-       { 0xf818, KEY_8 },
-       { 0xf819, KEY_9 },
-       { 0xf810, KEY_0 },
-       { 0xf81c, KEY_CHANNELUP },      /*ch+*/
-       { 0xf80f, KEY_CHANNELDOWN },    /*ch-*/
-       { 0xf81a, KEY_VOLUMEUP },       /*vol+*/
-       { 0xf80e, KEY_VOLUMEDOWN },     /*vol-*/
-       { 0xf804, KEY_RECORD },         /*rec*/
-       { 0xf809, KEY_FAVORITES },      /*fav*/
-       { 0xf808, KEY_REWIND },         /*rewind*/
-       { 0xf807, KEY_FASTFORWARD },    /*fast*/
-       { 0xf80b, KEY_PAUSE },          /*pause*/
-       { 0xf802, KEY_ESC },            /*cancel*/
-       { 0xf803, KEY_TAB },            /*tab*/
-       { 0xf800, KEY_UP },             /*up*/
-       { 0xf81f, KEY_OK },             /*ok*/
-       { 0xf801, KEY_DOWN },           /*down*/
-       { 0xf805, KEY_CAMERA },         /*cap*/
-       { 0xf806, KEY_STOP },           /*stop*/
-       { 0xf840, KEY_ZOOM },           /*full*/
-       { 0xf81e, KEY_TV },             /*tvmode*/
-       { 0xf81b, KEY_LAST },           /*recall*/
-};
-
-static struct rc_map_table rc_map_tevii_table[] = {
-       { 0xf80a, KEY_POWER },
-       { 0xf80c, KEY_MUTE },
-       { 0xf811, KEY_1 },
-       { 0xf812, KEY_2 },
-       { 0xf813, KEY_3 },
-       { 0xf814, KEY_4 },
-       { 0xf815, KEY_5 },
-       { 0xf816, KEY_6 },
-       { 0xf817, KEY_7 },
-       { 0xf818, KEY_8 },
-       { 0xf819, KEY_9 },
-       { 0xf810, KEY_0 },
-       { 0xf81c, KEY_MENU },
-       { 0xf80f, KEY_VOLUMEDOWN },
-       { 0xf81a, KEY_LAST },
-       { 0xf80e, KEY_OPEN },
-       { 0xf804, KEY_RECORD },
-       { 0xf809, KEY_VOLUMEUP },
-       { 0xf808, KEY_CHANNELUP },
-       { 0xf807, KEY_PVR },
-       { 0xf80b, KEY_TIME },
-       { 0xf802, KEY_RIGHT },
-       { 0xf803, KEY_LEFT },
-       { 0xf800, KEY_UP },
-       { 0xf81f, KEY_OK },
-       { 0xf801, KEY_DOWN },
-       { 0xf805, KEY_TUNER },
-       { 0xf806, KEY_CHANNELDOWN },
-       { 0xf840, KEY_PLAYPAUSE },
-       { 0xf81e, KEY_REWIND },
-       { 0xf81b, KEY_FAVORITES },
-       { 0xf81d, KEY_BACK },
-       { 0xf84d, KEY_FASTFORWARD },
-       { 0xf844, KEY_EPG },
-       { 0xf84c, KEY_INFO },
-       { 0xf841, KEY_AB },
-       { 0xf843, KEY_AUDIO },
-       { 0xf845, KEY_SUBTITLE },
-       { 0xf84a, KEY_LIST },
-       { 0xf846, KEY_F1 },
-       { 0xf847, KEY_F2 },
-       { 0xf85e, KEY_F3 },
-       { 0xf85c, KEY_F4 },
-       { 0xf852, KEY_F5 },
-       { 0xf85a, KEY_F6 },
-       { 0xf856, KEY_MODE },
-       { 0xf858, KEY_SWITCHVIDEOMODE },
-};
-
-static struct rc_map_table rc_map_tbs_table[] = {
-       { 0xf884, KEY_POWER },
-       { 0xf894, KEY_MUTE },
-       { 0xf887, KEY_1 },
-       { 0xf886, KEY_2 },
-       { 0xf885, KEY_3 },
-       { 0xf88b, KEY_4 },
-       { 0xf88a, KEY_5 },
-       { 0xf889, KEY_6 },
-       { 0xf88f, KEY_7 },
-       { 0xf88e, KEY_8 },
-       { 0xf88d, KEY_9 },
-       { 0xf892, KEY_0 },
-       { 0xf896, KEY_CHANNELUP },
-       { 0xf891, KEY_CHANNELDOWN },
-       { 0xf893, KEY_VOLUMEUP },
-       { 0xf88c, KEY_VOLUMEDOWN },
-       { 0xf883, KEY_RECORD },
-       { 0xf898, KEY_PAUSE  },
-       { 0xf899, KEY_OK },
-       { 0xf89a, KEY_SHUFFLE },
-       { 0xf881, KEY_UP },
-       { 0xf890, KEY_LEFT },
-       { 0xf882, KEY_RIGHT },
-       { 0xf888, KEY_DOWN },
-       { 0xf895, KEY_FAVORITES },
-       { 0xf897, KEY_SUBTITLE },
-       { 0xf89d, KEY_ZOOM },
-       { 0xf89f, KEY_EXIT },
-       { 0xf89e, KEY_MENU },
-       { 0xf89c, KEY_EPG },
-       { 0xf880, KEY_PREVIOUS },
-       { 0xf89b, KEY_MODE }
-};
-
-static struct rc_map_table rc_map_su3000_table[] = {
-       { 0x25, KEY_POWER },    /* right-bottom Red */
-       { 0x0a, KEY_MUTE },     /* -/-- */
-       { 0x01, KEY_1 },
-       { 0x02, KEY_2 },
-       { 0x03, KEY_3 },
-       { 0x04, KEY_4 },
-       { 0x05, KEY_5 },
-       { 0x06, KEY_6 },
-       { 0x07, KEY_7 },
-       { 0x08, KEY_8 },
-       { 0x09, KEY_9 },
-       { 0x00, KEY_0 },
-       { 0x20, KEY_UP },       /* CH+ */
-       { 0x21, KEY_DOWN },     /* CH+ */
-       { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
-       { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
-       { 0x1f, KEY_RECORD },
-       { 0x17, KEY_PLAY },
-       { 0x16, KEY_PAUSE },
-       { 0x0b, KEY_STOP },
-       { 0x27, KEY_FASTFORWARD },/* >> */
-       { 0x26, KEY_REWIND },   /* << */
-       { 0x0d, KEY_OK },       /* Mute */
-       { 0x11, KEY_LEFT },     /* VOL- */
-       { 0x10, KEY_RIGHT },    /* VOL+ */
-       { 0x29, KEY_BACK },     /* button under 9 */
-       { 0x2c, KEY_MENU },     /* TTX */
-       { 0x2b, KEY_EPG },      /* EPG */
-       { 0x1e, KEY_RED },      /* OSD */
-       { 0x0e, KEY_GREEN },    /* Window */
-       { 0x2d, KEY_YELLOW },   /* button under << */
-       { 0x0f, KEY_BLUE },     /* bottom yellow button */
-       { 0x14, KEY_AUDIO },    /* Snapshot */
-       { 0x38, KEY_TV },       /* TV/Radio */
-       { 0x0c, KEY_ESC }       /* upper Red button */
-};
-
-static struct rc_map_dvb_usb_table_table keys_tables[] = {
-       { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
-       { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
-       { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
-       { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
-};
-
-static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
-       int keymap_size = d->props.rc.legacy.rc_map_size;
-       u8 key[2];
-       struct i2c_msg msg = {
-               .addr = DW2102_RC_QUERY,
-               .flags = I2C_M_RD,
-               .buf = key,
-               .len = 2
-       };
-       int i;
-       /* override keymap */
-       if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
-               keymap = keys_tables[ir_keymap - 1].rc_keys ;
-               keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
-       } else if (ir_keymap > ARRAY_SIZE(keys_tables))
-               return 0; /* none */
-
-       *state = REMOTE_NO_KEY_PRESSED;
-       if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
-               for (i = 0; i < keymap_size ; i++) {
-                       if (rc5_data(&keymap[i]) == msg.buf[0]) {
-                               *state = REMOTE_KEY_PRESSED;
-                               *event = keymap[i].keycode;
-                               break;
-                       }
-
-               }
-
-               if ((*state) == REMOTE_KEY_PRESSED)
-                       deb_rc("%s: found rc key: %x, %x, event: %x\n",
-                                       __func__, key[0], key[1], (*event));
-               else if (key[0] != 0xff)
-                       deb_rc("%s: unknown rc key: %x, %x\n",
-                                       __func__, key[0], key[1]);
-
-       }
-
-       return 0;
-}
-
-enum dw2102_table_entry {
-       CYPRESS_DW2102,
-       CYPRESS_DW2101,
-       CYPRESS_DW2104,
-       TEVII_S650,
-       TERRATEC_CINERGY_S,
-       CYPRESS_DW3101,
-       TEVII_S630,
-       PROF_1100,
-       TEVII_S660,
-       PROF_7500,
-       GENIATECH_SU3000,
-       TERRATEC_CINERGY_S2,
-       TEVII_S480_1,
-       TEVII_S480_2,
-       X3M_SPC1400HD,
-};
-
-static struct usb_device_id dw2102_table[] = {
-       [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
-       [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
-       [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
-       [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
-       [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
-       [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
-       [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
-       [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
-       [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
-       [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
-       [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
-       [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
-       [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
-       [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
-       [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
-       { }
-};
-
-MODULE_DEVICE_TABLE(usb, dw2102_table);
-
-static int dw2102_load_firmware(struct usb_device *dev,
-                       const struct firmware *frmwr)
-{
-       u8 *b, *p;
-       int ret = 0, i;
-       u8 reset;
-       u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
-       const struct firmware *fw;
-       const char *fw_2101 = "dvb-usb-dw2101.fw";
-
-       switch (dev->descriptor.idProduct) {
-       case 0x2101:
-               ret = request_firmware(&fw, fw_2101, &dev->dev);
-               if (ret != 0) {
-                       err(err_str, fw_2101);
-                       return ret;
-               }
-               break;
-       default:
-               fw = frmwr;
-               break;
-       }
-       info("start downloading DW210X firmware");
-       p = kmalloc(fw->size, GFP_KERNEL);
-       reset = 1;
-       /*stop the CPU*/
-       dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
-       dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
-
-       if (p != NULL) {
-               memcpy(p, fw->data, fw->size);
-               for (i = 0; i < fw->size; i += 0x40) {
-                       b = (u8 *) p + i;
-                       if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
-                                       DW210X_WRITE_MSG) != 0x40) {
-                               err("error while transferring firmware");
-                               ret = -EINVAL;
-                               break;
-                       }
-               }
-               /* restart the CPU */
-               reset = 0;
-               if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
-                                       DW210X_WRITE_MSG) != 1) {
-                       err("could not restart the USB controller CPU.");
-                       ret = -EINVAL;
-               }
-               if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
-                                       DW210X_WRITE_MSG) != 1) {
-                       err("could not restart the USB controller CPU.");
-                       ret = -EINVAL;
-               }
-               /* init registers */
-               switch (dev->descriptor.idProduct) {
-               case USB_PID_TEVII_S650:
-                       dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
-                       dw2104_properties.rc.legacy.rc_map_size =
-                                       ARRAY_SIZE(rc_map_tevii_table);
-               case USB_PID_DW2104:
-                       reset = 1;
-                       dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
-                                       DW210X_WRITE_MSG);
-                       /* break omitted intentionally */
-               case USB_PID_DW3101:
-                       reset = 0;
-                       dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
-                                       DW210X_WRITE_MSG);
-                       break;
-               case USB_PID_CINERGY_S:
-               case USB_PID_DW2102:
-                       dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
-                                       DW210X_WRITE_MSG);
-                       dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
-                                       DW210X_READ_MSG);
-                       /* check STV0299 frontend  */
-                       dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
-                                       DW210X_READ_MSG);
-                       if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
-                               dw2102_properties.i2c_algo = &dw2102_i2c_algo;
-                               dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
-                               break;
-                       } else {
-                               /* check STV0288 frontend  */
-                               reset16[0] = 0xd0;
-                               reset16[1] = 1;
-                               reset16[2] = 0;
-                               dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
-                                               DW210X_WRITE_MSG);
-                               dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
-                                               DW210X_READ_MSG);
-                               if (reset16[2] == 0x11) {
-                                       dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
-                                       break;
-                               }
-                       }
-               case 0x2101:
-                       dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
-                                       DW210X_READ_MSG);
-                       dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
-                                       DW210X_READ_MSG);
-                       dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
-                                       DW210X_READ_MSG);
-                       dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
-                                       DW210X_READ_MSG);
-                       break;
-               }
-
-               msleep(100);
-               kfree(p);
-       }
-       return ret;
-}
-
-static struct dvb_usb_device_properties dw2102_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-dw2102.fw",
-       .no_reconnect = 1,
-
-       .i2c_algo = &dw2102_serit_i2c_algo,
-
-       .rc.legacy = {
-               .rc_map_table = rc_map_dw210x_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
-               .rc_interval = 150,
-               .rc_query = dw2102_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x81,
-       /* parameter for the MPEG2-data transfer */
-       .num_adapters = 1,
-       .download_firmware = dw2102_load_firmware,
-       .read_mac_address = dw210x_read_mac_address,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = dw2102_frontend_attach,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .num_device_descs = 3,
-       .devices = {
-               {"DVBWorld DVB-S 2102 USB2.0",
-                       {&dw2102_table[CYPRESS_DW2102], NULL},
-                       {NULL},
-               },
-               {"DVBWorld DVB-S 2101 USB2.0",
-                       {&dw2102_table[CYPRESS_DW2101], NULL},
-                       {NULL},
-               },
-               {"TerraTec Cinergy S USB",
-                       {&dw2102_table[TERRATEC_CINERGY_S], NULL},
-                       {NULL},
-               },
-       }
-};
-
-static struct dvb_usb_device_properties dw2104_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-dw2104.fw",
-       .no_reconnect = 1,
-
-       .i2c_algo = &dw2104_i2c_algo,
-       .rc.legacy = {
-               .rc_map_table = rc_map_dw210x_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
-               .rc_interval = 150,
-               .rc_query = dw2102_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x81,
-       /* parameter for the MPEG2-data transfer */
-       .num_adapters = 1,
-       .download_firmware = dw2102_load_firmware,
-       .read_mac_address = dw210x_read_mac_address,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = dw2104_frontend_attach,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .num_device_descs = 2,
-       .devices = {
-               { "DVBWorld DW2104 USB2.0",
-                       {&dw2102_table[CYPRESS_DW2104], NULL},
-                       {NULL},
-               },
-               { "TeVii S650 USB2.0",
-                       {&dw2102_table[TEVII_S650], NULL},
-                       {NULL},
-               },
-       }
-};
-
-static struct dvb_usb_device_properties dw3101_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-dw3101.fw",
-       .no_reconnect = 1,
-
-       .i2c_algo = &dw3101_i2c_algo,
-       .rc.legacy = {
-               .rc_map_table = rc_map_dw210x_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
-               .rc_interval = 150,
-               .rc_query = dw2102_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x81,
-       /* parameter for the MPEG2-data transfer */
-       .num_adapters = 1,
-       .download_firmware = dw2102_load_firmware,
-       .read_mac_address = dw210x_read_mac_address,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = dw3101_frontend_attach,
-                       .tuner_attach = dw3101_tuner_attach,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .num_device_descs = 1,
-       .devices = {
-               { "DVBWorld DVB-C 3101 USB2.0",
-                       {&dw2102_table[CYPRESS_DW3101], NULL},
-                       {NULL},
-               },
-       }
-};
-
-static struct dvb_usb_device_properties s6x0_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .size_of_priv = sizeof(struct s6x0_state),
-       .firmware = "dvb-usb-s630.fw",
-       .no_reconnect = 1,
-
-       .i2c_algo = &s6x0_i2c_algo,
-       .rc.legacy = {
-               .rc_map_table = rc_map_tevii_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
-               .rc_interval = 150,
-               .rc_query = dw2102_rc_query,
-       },
-
-       .generic_bulk_ctrl_endpoint = 0x81,
-       .num_adapters = 1,
-       .download_firmware = dw2102_load_firmware,
-       .read_mac_address = s6x0_read_mac_address,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = zl100313_frontend_attach,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .num_device_descs = 1,
-       .devices = {
-               {"TeVii S630 USB",
-                       {&dw2102_table[TEVII_S630], NULL},
-                       {NULL},
-               },
-       }
-};
-
-struct dvb_usb_device_properties *p1100;
-static struct dvb_usb_device_description d1100 = {
-       "Prof 1100 USB ",
-       {&dw2102_table[PROF_1100], NULL},
-       {NULL},
-};
-
-struct dvb_usb_device_properties *s660;
-static struct dvb_usb_device_description d660 = {
-       "TeVii S660 USB",
-       {&dw2102_table[TEVII_S660], NULL},
-       {NULL},
-};
-
-static struct dvb_usb_device_description d480_1 = {
-       "TeVii S480.1 USB",
-       {&dw2102_table[TEVII_S480_1], NULL},
-       {NULL},
-};
-
-static struct dvb_usb_device_description d480_2 = {
-       "TeVii S480.2 USB",
-       {&dw2102_table[TEVII_S480_2], NULL},
-       {NULL},
-};
-
-struct dvb_usb_device_properties *p7500;
-static struct dvb_usb_device_description d7500 = {
-       "Prof 7500 USB DVB-S2",
-       {&dw2102_table[PROF_7500], NULL},
-       {NULL},
-};
-
-static struct dvb_usb_device_properties su3000_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .size_of_priv = sizeof(struct su3000_state),
-       .power_ctrl = su3000_power_ctrl,
-       .num_adapters = 1,
-       .identify_state = su3000_identify_state,
-       .i2c_algo = &su3000_i2c_algo,
-
-       .rc.legacy = {
-               .rc_map_table = rc_map_su3000_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
-               .rc_interval = 150,
-               .rc_query = dw2102_rc_query,
-       },
-
-       .read_mac_address = su3000_read_mac_address,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = su3000_streaming_ctrl,
-                       .frontend_attach  = su3000_frontend_attach,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 8,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       }
-               }},
-               }
-       },
-       .num_device_descs = 3,
-       .devices = {
-               { "SU3000HD DVB-S USB2.0",
-                       { &dw2102_table[GENIATECH_SU3000], NULL },
-                       { NULL },
-               },
-               { "Terratec Cinergy S2 USB HD",
-                       { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
-                       { NULL },
-               },
-               { "X3M TV SPC1400HD PCI",
-                       { &dw2102_table[X3M_SPC1400HD], NULL },
-                       { NULL },
-               },
-       }
-};
-
-static int dw2102_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       p1100 = kmemdup(&s6x0_properties,
-                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
-       if (!p1100)
-               return -ENOMEM;
-       /* copy default structure */
-       /* fill only different fields */
-       p1100->firmware = "dvb-usb-p1100.fw";
-       p1100->devices[0] = d1100;
-       p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
-       p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
-       p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
-
-       s660 = kmemdup(&s6x0_properties,
-                      sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
-       if (!s660) {
-               kfree(p1100);
-               return -ENOMEM;
-       }
-       s660->firmware = "dvb-usb-s660.fw";
-       s660->num_device_descs = 3;
-       s660->devices[0] = d660;
-       s660->devices[1] = d480_1;
-       s660->devices[2] = d480_2;
-       s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
-
-       p7500 = kmemdup(&s6x0_properties,
-                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
-       if (!p7500) {
-               kfree(p1100);
-               kfree(s660);
-               return -ENOMEM;
-       }
-       p7500->firmware = "dvb-usb-p7500.fw";
-       p7500->devices[0] = d7500;
-       p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
-       p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
-       p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
-
-       if (0 == dvb_usb_device_init(intf, &dw2102_properties,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &dw2104_properties,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &dw3101_properties,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &s6x0_properties,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, p1100,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, s660,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, p7500,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &su3000_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-
-       return -ENODEV;
-}
-
-static struct usb_driver dw2102_driver = {
-       .name = "dw2102",
-       .probe = dw2102_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table = dw2102_table,
-};
-
-module_usb_driver(dw2102_driver);
-
-MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
-MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
-                               " DVB-C 3101 USB2.0,"
-                               " TeVii S600, S630, S650, S660, S480,"
-                               " Prof 1100, 7500 USB2.0,"
-                               " Geniatech SU3000 devices");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
deleted file mode 100644 (file)
index 5cd0b0e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _DW2102_H_
-#define _DW2102_H_
-
-#define DVB_USB_LOG_PREFIX "dw2102"
-#include "dvb-usb.h"
-
-#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
-#define deb_rc(args...)   dprintk(dvb_usb_dw2102_debug, 0x04, args)
-#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
deleted file mode 100644 (file)
index 90a70c6..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
- *
- * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
- *
- * This module is based off the the gl861 and vp702x modules.
- *
- * 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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "friio.h"
-
-struct jdvbt90502_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend frontend;
-       struct jdvbt90502_config config;
-};
-
-/* NOTE: TC90502 has 16bit register-address? */
-/* register 0x0100 is used for reading PLL status, so reg is u16 here */
-static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
-                              const u16 reg, u8 *buf, const size_t count)
-{
-       int ret;
-       u8 wbuf[3];
-       struct i2c_msg msg[2];
-
-       wbuf[0] = reg & 0xFF;
-       wbuf[1] = 0;
-       wbuf[2] = reg >> 8;
-
-       msg[0].addr = state->config.demod_address;
-       msg[0].flags = 0;
-       msg[0].buf = wbuf;
-       msg[0].len = sizeof(wbuf);
-
-       msg[1].addr = msg[0].addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].buf = buf;
-       msg[1].len = count;
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2) {
-               deb_fe(" reg read failed.\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* currently 16bit register-address is not used, so reg is u8 here */
-static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
-                                      const u8 reg, const u8 val)
-{
-       struct i2c_msg msg;
-       u8 wbuf[2];
-
-       wbuf[0] = reg;
-       wbuf[1] = val;
-
-       msg.addr = state->config.demod_address;
-       msg.flags = 0;
-       msg.buf = wbuf;
-       msg.len = sizeof(wbuf);
-
-       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
-               deb_fe(" reg write failed.");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
-{
-       struct jdvbt90502_state *state = fe->demodulator_priv;
-       int err, i;
-       for (i = 0; i < len - 1; i++) {
-               err = jdvbt90502_single_reg_write(state,
-                                                 buf[0] + i, buf[i + 1]);
-               if (err)
-                       return err;
-       }
-
-       return 0;
-}
-
-/* read pll status byte via the demodulator's I2C register */
-/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
-static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
-{
-       int ret;
-
-       /* +1 for reading */
-       u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
-
-       *result = 0;
-
-       ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
-                                         pll_addr_byte);
-       if (ret)
-               goto error;
-
-       ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
-       if (ret)
-               goto error;
-
-       deb_fe("PLL read val:%02x\n", *result);
-       return 0;
-
-error:
-       deb_fe("%s:ret == %d\n", __func__, ret);
-       return -EREMOTEIO;
-}
-
-
-/* set pll frequency via the demodulator's I2C register */
-static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
-{
-       int ret;
-       int retry;
-       u8 res1;
-       u8 res2[9];
-
-       u8 pll_freq_cmd[PLL_CMD_LEN];
-       u8 pll_agc_cmd[PLL_CMD_LEN];
-       struct i2c_msg msg[2];
-       u32 f;
-
-       deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
-              state->frontend.ops.info.frequency_stepsize);
-       /* freq -> oscilator frequency conversion. */
-       /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
-       f = freq / state->frontend.ops.info.frequency_stepsize;
-       /* add 399[1/7 MHZ] = 57MHz for the IF  */
-       f += 399;
-       /* add center frequency shift if necessary */
-       if (f % 7 == 0)
-               f++;
-       pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
-       pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
-       pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
-       pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
-       pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
-       pll_freq_cmd[BANDSWITCH_BYTE] = 0x08;   /* UHF band */
-
-       msg[0].addr = state->config.demod_address;
-       msg[0].flags = 0;
-       msg[0].buf = pll_freq_cmd;
-       msg[0].len = sizeof(pll_freq_cmd);
-
-       ret = i2c_transfer(state->i2c, &msg[0], 1);
-       if (ret != 1)
-               goto error;
-
-       udelay(50);
-
-       pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
-       pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
-       pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
-       pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
-       pll_agc_cmd[CONTROL_BYTE] = 0x9A; /*  AGC_CTRL instead of BANDSWITCH */
-       pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
-       /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
-
-       msg[1].addr = msg[0].addr;
-       msg[1].flags = 0;
-       msg[1].buf = pll_agc_cmd;
-       msg[1].len = sizeof(pll_agc_cmd);
-
-       ret = i2c_transfer(state->i2c, &msg[1], 1);
-       if (ret != 1)
-               goto error;
-
-       /* I don't know what these cmds are for,  */
-       /* but the USB log on a windows box contains them */
-       ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
-       ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
-       if (ret)
-               goto error;
-       udelay(100);
-
-       /* wait for the demod to be ready? */
-#define RETRY_COUNT 5
-       for (retry = 0; retry < RETRY_COUNT; retry++) {
-               ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
-               if (ret)
-                       goto error;
-               /* if (res1 != 0x00) goto error; */
-               ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
-               if (ret)
-                       goto error;
-               if (res2[0] >= 0xA7)
-                       break;
-               msleep(100);
-       }
-       if (retry >= RETRY_COUNT) {
-               deb_fe("%s: FE does not get ready after freq setting.\n",
-                      __func__);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-error:
-       deb_fe("%s:ret == %d\n", __func__, ret);
-       return -EREMOTEIO;
-}
-
-static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
-{
-       u8 result;
-       int ret;
-
-       *state = FE_HAS_SIGNAL;
-
-       ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
-       if (ret) {
-               deb_fe("%s:ret == %d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-
-       *state = FE_HAS_SIGNAL
-               | FE_HAS_CARRIER
-               | FE_HAS_VITERBI
-               | FE_HAS_SYNC;
-
-       if (result & PLL_STATUS_LOCKED)
-               *state |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
-                                          u16 *strength)
-{
-       int ret;
-       u8 rbuf[37];
-
-       *strength = 0;
-
-       /* status register (incl. signal strength) : 0x89  */
-       /* TODO: read just the necessary registers [0x8B..0x8D]? */
-       ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
-                                 rbuf, sizeof(rbuf));
-
-       if (ret) {
-               deb_fe("%s:ret == %d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-
-       /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
-       *strength = (rbuf[3] << 8) + rbuf[4];
-       if (rbuf[2])
-               *strength = 0xffff;
-
-       return 0;
-}
-
-
-/* filter out un-supported properties to notify users */
-static int jdvbt90502_set_property(struct dvb_frontend *fe,
-                                  struct dtv_property *tvp)
-{
-       int r = 0;
-
-       switch (tvp->cmd) {
-       case DTV_DELIVERY_SYSTEM:
-               if (tvp->u.data != SYS_ISDBT)
-                       r = -EINVAL;
-               break;
-       case DTV_CLEAR:
-       case DTV_TUNE:
-       case DTV_FREQUENCY:
-               break;
-       default:
-               r = -EINVAL;
-       }
-       return r;
-}
-
-static int jdvbt90502_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       p->inversion = INVERSION_AUTO;
-       p->bandwidth_hz = 6000000;
-       p->code_rate_HP = FEC_AUTO;
-       p->code_rate_LP = FEC_AUTO;
-       p->modulation = QAM_64;
-       p->transmission_mode = TRANSMISSION_MODE_AUTO;
-       p->guard_interval = GUARD_INTERVAL_AUTO;
-       p->hierarchy = HIERARCHY_AUTO;
-       return 0;
-}
-
-static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       /**
-        * NOTE: ignore all the parameters except frequency.
-        *       others should be fixed to the proper value for ISDB-T,
-        *       but don't check here.
-        */
-
-       struct jdvbt90502_state *state = fe->demodulator_priv;
-       int ret;
-
-       deb_fe("%s: Freq:%d\n", __func__, p->frequency);
-
-       /* for recovery from DTV_CLEAN */
-       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
-
-       ret = jdvbt90502_pll_set_freq(state, p->frequency);
-       if (ret) {
-               deb_fe("%s:ret == %d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-
-/**
- * (reg, val) commad list to initialize this module.
- *  captured on a Windows box.
- */
-static u8 init_code[][2] = {
-       {0x01, 0x40},
-       {0x04, 0x38},
-       {0x05, 0x40},
-       {0x07, 0x40},
-       {0x0F, 0x4F},
-       {0x11, 0x21},
-       {0x12, 0x0B},
-       {0x13, 0x2F},
-       {0x14, 0x31},
-       {0x16, 0x02},
-       {0x21, 0xC4},
-       {0x22, 0x20},
-       {0x2C, 0x79},
-       {0x2D, 0x34},
-       {0x2F, 0x00},
-       {0x30, 0x28},
-       {0x31, 0x31},
-       {0x32, 0xDF},
-       {0x38, 0x01},
-       {0x39, 0x78},
-       {0x3B, 0x33},
-       {0x3C, 0x33},
-       {0x48, 0x90},
-       {0x51, 0x68},
-       {0x5E, 0x38},
-       {0x71, 0x00},
-       {0x72, 0x08},
-       {0x77, 0x00},
-       {0xC0, 0x21},
-       {0xC1, 0x10},
-       {0xE4, 0x1A},
-       {0xEA, 0x1F},
-       {0x77, 0x00},
-       {0x71, 0x00},
-       {0x71, 0x00},
-       {0x76, 0x0C},
-};
-
-static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
-
-static int jdvbt90502_init(struct dvb_frontend *fe)
-{
-       int i = -1;
-       int ret;
-       struct i2c_msg msg;
-
-       struct jdvbt90502_state *state = fe->demodulator_priv;
-
-       deb_fe("%s called.\n", __func__);
-
-       msg.addr = state->config.demod_address;
-       msg.flags = 0;
-       msg.len = 2;
-       for (i = 0; i < init_code_len; i++) {
-               msg.buf = init_code[i];
-               ret = i2c_transfer(state->i2c, &msg, 1);
-               if (ret != 1)
-                       goto error;
-       }
-       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
-       msleep(100);
-
-       return 0;
-
-error:
-       deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
-       return -EREMOTEIO;
-}
-
-
-static void jdvbt90502_release(struct dvb_frontend *fe)
-{
-       struct jdvbt90502_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-
-static struct dvb_frontend_ops jdvbt90502_ops;
-
-struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
-{
-       struct jdvbt90502_state *state = NULL;
-
-       deb_info("%s called.\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = &d->i2c_adap;
-       memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &jdvbt90502_ops,
-              sizeof(jdvbt90502_ops));
-       state->frontend.demodulator_priv = state;
-
-       if (jdvbt90502_init(&state->frontend) < 0)
-               goto error;
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops jdvbt90502_ops = {
-       .delsys = { SYS_ISDBT },
-       .info = {
-               .name                   = "Comtech JDVBT90502 ISDB-T",
-               .frequency_min          = 473000000, /* UHF 13ch, center */
-               .frequency_max          = 767142857, /* UHF 62ch, center */
-               .frequency_stepsize     = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER,
-               .frequency_tolerance    = 0,
-
-               /* NOTE: this driver ignores all parameters but frequency. */
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = jdvbt90502_release,
-
-       .init = jdvbt90502_init,
-       .write = _jdvbt90502_write,
-
-       .set_property = jdvbt90502_set_property,
-
-       .set_frontend = jdvbt90502_set_frontend,
-       .get_frontend = jdvbt90502_get_frontend,
-
-       .read_status = jdvbt90502_read_status,
-       .read_signal_strength = jdvbt90502_read_signal_strength,
-};
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
deleted file mode 100644 (file)
index 474a17e..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
- *
- * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
- *
- * This module is based off the the gl861 and vp702x modules.
- *
- * 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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "friio.h"
-
-/* debug */
-int dvb_usb_friio_debug;
-module_param_named(debug, dvb_usb_friio_debug, int, 0644);
-MODULE_PARM_DESC(debug,
-                "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
-                DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-/**
- * Indirect I2C access to the PLL via FE.
- * whole I2C protocol data to the PLL is sent via the FE's I2C register.
- * This is done by a control msg to the FE with the I2C data accompanied, and
- * a specific USB request number is assigned for that purpose.
- *
- * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
- * TODO: refoctored, smarter i2c functions.
- */
-static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
-                                 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u16 index = wbuf[0];    /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
-       u16 value = addr << (8 + 1);
-       int wo = (rbuf == NULL || rlen == 0);   /* write only */
-       u8 req, type;
-
-       deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
-                wbuf[1], wbuf[0], wlen - 1);
-
-       if (wo && wlen >= 2) {
-               req = GL861_REQ_I2C_DATA_CTRL_WRITE;
-               type = GL861_WRITE;
-               udelay(20);
-               return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-                                      req, type, value, index,
-                                      &wbuf[1], wlen - 1, 2000);
-       }
-
-       deb_xfer("not supported ctrl-msg, aborting.");
-       return -EINVAL;
-}
-
-/* normal I2C access (without extra data arguments).
- * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
- *  or read from the register wbuf[0].
- * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
- */
-static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u16 index;
-       u16 value = addr << (8 + 1);
-       int wo = (rbuf == NULL || rlen == 0);   /* write-only */
-       u8 req, type;
-       unsigned int pipe;
-
-       /* special case for the indirect I2C access to the PLL via FE, */
-       if (addr == friio_fe_config.demod_address &&
-           wbuf[0] == JDVBT90502_2ND_I2C_REG)
-               return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
-
-       if (wo) {
-               req = GL861_REQ_I2C_WRITE;
-               type = GL861_WRITE;
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {                /* rw */
-               req = GL861_REQ_I2C_READ;
-               type = GL861_READ;
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       switch (wlen) {
-       case 1:
-               index = wbuf[0];
-               break;
-       case 2:
-               index = wbuf[0];
-               value = value + wbuf[1];
-               break;
-       case 3:
-               /* special case for 16bit register-address */
-               index = (wbuf[2] << 8) | wbuf[0];
-               value = value + wbuf[1];
-               break;
-       default:
-               deb_xfer("wlen = %x, aborting.", wlen);
-               return -EINVAL;
-       }
-       msleep(1);
-       return usb_control_msg(d->udev, pipe, req, type,
-                              value, index, rbuf, rlen, 2000);
-}
-
-/* I2C */
-static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
-                       if (gl861_i2c_msg(d, msg[i].addr,
-                                         msg[i].buf, msg[i].len,
-                                         msg[i + 1].buf, msg[i + 1].len) < 0)
-                               break;
-                       i++;
-               } else
-                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                         msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 gl861_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static int friio_ext_ctl(struct dvb_usb_adapter *adap,
-                        u32 sat_color, int lnb_on)
-{
-       int i;
-       int ret;
-       struct i2c_msg msg;
-       u8 *buf;
-       u32 mask;
-       u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
-
-       buf = kmalloc(2, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       msg.addr = 0x00;
-       msg.flags = 0;
-       msg.len = 2;
-       msg.buf = buf;
-
-       buf[0] = 0x00;
-
-       /* send 2bit header (&B10) */
-       buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
-       ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-       buf[1] |= FRIIO_CTL_CLK;
-       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-
-       buf[1] = lnb | FRIIO_CTL_STROBE;
-       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-       buf[1] |= FRIIO_CTL_CLK;
-       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-
-       /* send 32bit(satur, R, G, B) data in serial */
-       mask = 1 << 31;
-       for (i = 0; i < 32; i++) {
-               buf[1] = lnb | FRIIO_CTL_STROBE;
-               if (sat_color & mask)
-                       buf[1] |= FRIIO_CTL_LED;
-               ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-               buf[1] |= FRIIO_CTL_CLK;
-               ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-               mask >>= 1;
-       }
-
-       /* set the strobe off */
-       buf[1] = lnb;
-       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-       buf[1] |= FRIIO_CTL_CLK;
-       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
-
-       kfree(buf);
-       return (ret == 70);
-}
-
-
-static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
-
-/* TODO: move these init cmds to the FE's init routine? */
-static u8 streaming_init_cmds[][2] = {
-       {0x33, 0x08},
-       {0x37, 0x40},
-       {0x3A, 0x1F},
-       {0x3B, 0xFF},
-       {0x3C, 0x1F},
-       {0x3D, 0xFF},
-       {0x38, 0x00},
-       {0x35, 0x00},
-       {0x39, 0x00},
-       {0x36, 0x00},
-};
-static int cmdlen = sizeof(streaming_init_cmds) / 2;
-
-/*
- * Command sequence in this init function is a replay
- *  of the captured USB commands from the Windows proprietary driver.
- */
-static int friio_initialize(struct dvb_usb_device *d)
-{
-       int ret;
-       int i;
-       int retry = 0;
-       u8 *rbuf, *wbuf;
-
-       deb_info("%s called.\n", __func__);
-
-       wbuf = kmalloc(3, GFP_KERNEL);
-       if (!wbuf)
-               return -ENOMEM;
-
-       rbuf = kmalloc(2, GFP_KERNEL);
-       if (!rbuf) {
-               kfree(wbuf);
-               return -ENOMEM;
-       }
-
-       /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
-       /* because the i2c device is not set up yet. */
-       wbuf[0] = 0x11;
-       wbuf[1] = 0x02;
-       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-       msleep(2);
-
-       wbuf[0] = 0x11;
-       wbuf[1] = 0x00;
-       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-       msleep(1);
-
-       /* following msgs should be in the FE's init code? */
-       /* cmd sequence to identify the device type? (friio black/white) */
-       wbuf[0] = 0x03;
-       wbuf[1] = 0x80;
-       /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
-       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-                             GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
-                             0x1200, 0x0100, wbuf, 2, 2000);
-       if (ret < 0)
-               goto error;
-
-       msleep(2);
-       wbuf[0] = 0x00;
-       wbuf[2] = 0x01;         /* reg.0x0100 */
-       wbuf[1] = 0x00;
-       ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
-       /* my Friio White returns 0xffff. */
-       if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
-               goto error;
-
-       msleep(2);
-       wbuf[0] = 0x03;
-       wbuf[1] = 0x80;
-       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-                             GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
-                             0x9000, 0x0100, wbuf, 2, 2000);
-       if (ret < 0)
-               goto error;
-
-       msleep(2);
-       wbuf[0] = 0x00;
-       wbuf[2] = 0x01;         /* reg.0x0100 */
-       wbuf[1] = 0x00;
-       ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
-       /* my Friio White returns 0xffff again. */
-       if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
-               goto error;
-
-       msleep(1);
-
-restart:
-       /* ============ start DEMOD init cmds ================== */
-       /* read PLL status to clear the POR bit */
-       wbuf[0] = JDVBT90502_2ND_I2C_REG;
-       wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1;    /* +1 for reading */
-       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-
-       msleep(5);
-       /* note: DEMODULATOR has 16bit register-address. */
-       wbuf[0] = 0x00;
-       wbuf[2] = 0x01;         /* reg addr: 0x0100 */
-       wbuf[1] = 0x00;         /* val: not used */
-       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
-       if (ret < 0)
-               goto error;
-/*
-       msleep(1);
-       wbuf[0] = 0x80;
-       wbuf[1] = 0x00;
-       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
-       if (ret < 0)
-               goto error;
- */
-       if (rbuf[0] & 0x80) {   /* still in PowerOnReset state? */
-               if (++retry > 3) {
-                       deb_info("failed to get the correct"
-                                " FE demod status:0x%02x\n", rbuf[0]);
-                       goto error;
-               }
-               msleep(100);
-               goto restart;
-       }
-
-       /* TODO: check return value in rbuf */
-       /* =========== end DEMOD init cmds ===================== */
-       msleep(1);
-
-       wbuf[0] = 0x30;
-       wbuf[1] = 0x04;
-       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-
-       msleep(2);
-       /* following 2 cmds unnecessary? */
-       wbuf[0] = 0x00;
-       wbuf[1] = 0x01;
-       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-
-       wbuf[0] = 0x06;
-       wbuf[1] = 0x0F;
-       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
-       if (ret < 0)
-               goto error;
-
-       /* some streaming ctl cmds (maybe) */
-       msleep(10);
-       for (i = 0; i < cmdlen; i++) {
-               ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
-                                   NULL, 0);
-               if (ret < 0)
-                       goto error;
-               msleep(1);
-       }
-       msleep(20);
-
-       /* change the LED color etc. */
-       ret = friio_streaming_ctrl(&d->adapter[0], 0);
-       if (ret < 0)
-               goto error;
-
-       return 0;
-
-error:
-       kfree(wbuf);
-       kfree(rbuf);
-       deb_info("%s:ret == %d\n", __func__, ret);
-       return -EIO;
-}
-
-/* Callbacks for DVB USB */
-
-static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-
-       deb_info("%s called.(%d)\n", __func__, onoff);
-
-       /* set the LED color and saturation (and LNB on) */
-       if (onoff)
-               ret = friio_ext_ctl(adap, 0x6400ff64, 1);
-       else
-               ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
-
-       if (ret != 1) {
-               deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int friio_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       if (friio_initialize(adap->dev) < 0)
-               return -EIO;
-
-       adap->fe_adap[0].fe = jdvbt90502_attach(adap->dev);
-       if (adap->fe_adap[0].fe == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties friio_properties;
-
-static int friio_probe(struct usb_interface *intf,
-                      const struct usb_device_id *id)
-{
-       struct dvb_usb_device *d;
-       struct usb_host_interface *alt;
-       int ret;
-
-       if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
-               return -ENODEV;
-
-       alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
-       if (alt == NULL) {
-               deb_rc("not alt found!\n");
-               return -ENODEV;
-       }
-       ret = usb_set_interface(interface_to_usbdev(intf),
-                               alt->desc.bInterfaceNumber,
-                               alt->desc.bAlternateSetting);
-       if (ret != 0) {
-               deb_rc("failed to set alt-setting!\n");
-               return ret;
-       }
-
-       ret = dvb_usb_device_init(intf, &friio_properties,
-                                 THIS_MODULE, &d, adapter_nr);
-       if (ret == 0)
-               friio_streaming_ctrl(&d->adapter[0], 1);
-
-       return ret;
-}
-
-
-struct jdvbt90502_config friio_fe_config = {
-       .demod_address = FRIIO_DEMOD_ADDR,
-       .pll_address = FRIIO_PLL_ADDR,
-};
-
-static struct i2c_algorithm gl861_i2c_algo = {
-       .master_xfer   = gl861_i2c_xfer,
-       .functionality = gl861_i2c_func,
-};
-
-static struct usb_device_id friio_table[] = {
-       { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
-       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, friio_table);
-
-
-static struct dvb_usb_device_properties friio_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = DEVICE_SPECIFIC,
-
-       .size_of_priv = 0,
-
-       .num_adapters = 1,
-       .adapter = {
-               /* caps:0 =>  no pid filter, 188B TS packet */
-               /* GL861 has a HW pid filter, but no info available. */
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps  = 0,
-
-                       .frontend_attach  = friio_frontend_attach,
-                       .streaming_ctrl = friio_streaming_ctrl,
-
-                       .stream = {
-                               .type = USB_BULK,
-                               /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
-                               .count = 8,
-                               .endpoint = 0x01,
-                               .u = {
-                                       /* GL861 has 6KB buf inside */
-                                       .bulk = {
-                                               .buffersize = 16384,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .i2c_algo = &gl861_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {
-                       .name = "774 Friio ISDB-T USB2.0",
-                       .cold_ids = { NULL },
-                       .warm_ids = { &friio_table[0], NULL },
-               },
-       }
-};
-
-static struct usb_driver friio_driver = {
-       .name           = "dvb_usb_friio",
-       .probe          = friio_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = friio_table,
-};
-
-module_usb_driver(friio_driver);
-
-MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
-MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
-MODULE_VERSION("0.2");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h
deleted file mode 100644 (file)
index 0f461ca..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
- *
- * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
- *
- * This module is based off the the gl861 and vp702x modules.
- *
- * 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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_FRIIO_H_
-#define _DVB_USB_FRIIO_H_
-
-/**
- *      Friio Components
- *       USB hub:                                AU4254
- *         USB controller(+ TS dmx & streaming): GL861
- *         Frontend:                             comtech JDVBT-90502
- *             (tuner PLL:                       tua6034, I2C addr:(0xC0 >> 1))
- *             (OFDM demodulator:                TC90502, I2C addr:(0x30 >> 1))
- *         LED x3 (+LNB) control:                PIC 16F676
- *         EEPROM:                               24C08
- *
- *        (USB smart card reader:                AU9522)
- *
- */
-
-#define DVB_USB_LOG_PREFIX "friio"
-#include "dvb-usb.h"
-
-extern int dvb_usb_friio_debug;
-#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
-#define deb_rc(args...)   dprintk(dvb_usb_friio_debug, 0x04, args)
-#define deb_fe(args...)   dprintk(dvb_usb_friio_debug, 0x08, args)
-
-/* Vendor requests */
-#define GL861_WRITE            0x40
-#define GL861_READ             0xc0
-
-/* command bytes */
-#define GL861_REQ_I2C_WRITE    0x01
-#define GL861_REQ_I2C_READ     0x02
-/* For control msg with data argument */
-/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
-#define GL861_REQ_I2C_DATA_CTRL_WRITE  0x03
-
-#define GL861_ALTSETTING_COUNT 2
-#define FRIIO_BULK_ALTSETTING  0
-#define FRIIO_ISOC_ALTSETTING  1
-
-/* LED & LNB control via PIC. */
-/* basically, it's serial control with clock and strobe. */
-/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
-/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
-#define FRIIO_CTL_LNB (1 << 0)
-#define FRIIO_CTL_STROBE (1 << 1)
-#define FRIIO_CTL_CLK (1 << 2)
-#define FRIIO_CTL_LED (1 << 3)
-
-/* Front End related */
-
-#define FRIIO_DEMOD_ADDR  (0x30 >> 1)
-#define FRIIO_PLL_ADDR  (0xC0 >> 1)
-
-#define JDVBT90502_PLL_CLK     4000000
-#define JDVBT90502_PLL_DIVIDER 28
-
-#define JDVBT90502_2ND_I2C_REG 0xFE
-
-/* byte index for pll i2c command data structure*/
-/* see datasheet for tua6034 */
-#define DEMOD_REDIRECT_REG 0
-#define ADDRESS_BYTE       1
-#define DIVIDER_BYTE1      2
-#define DIVIDER_BYTE2      3
-#define CONTROL_BYTE       4
-#define BANDSWITCH_BYTE    5
-#define AGC_CTRL_BYTE      5
-#define PLL_CMD_LEN        6
-
-/* bit masks for PLL STATUS response */
-#define PLL_STATUS_POR_MODE   0x80 /* 1: Power on Reset (test) Mode */
-#define PLL_STATUS_LOCKED     0x40 /* 1: locked */
-#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
-#define PLL_STATUS_TESTMODE   0x07 /* digital output level (5 level) */
-  /* 0.15Vcc step   0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
-
-
-struct jdvbt90502_config {
-       u8 demod_address; /* i2c addr for demodulator IC */
-       u8 pll_address;   /* PLL addr on the secondary i2c*/
-};
-extern struct jdvbt90502_config friio_fe_config;
-
-extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
-#endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
deleted file mode 100644 (file)
index 67957dd..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
- *
- * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
- * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
- *
- * Thanks to GENPIX for the sample code used to implement this module.
- *
- * This module is based off the vp7045 and vp702x modules
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "gp8psk.h"
-
-struct gp8psk_fe_state {
-       struct dvb_frontend fe;
-       struct dvb_usb_device *d;
-       u8 lock;
-       u16 snr;
-       unsigned long next_status_check;
-       unsigned long status_check_interval;
-};
-
-static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-       u8 status;
-       gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
-       return status & bmDCtuned;
-}
-
-static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
-{
-       struct gp8psk_fe_state *state = fe->demodulator_priv;
-       return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
-}
-
-static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
-{
-       u8 buf[6];
-       if (time_after(jiffies,st->next_status_check)) {
-               gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
-               gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
-               st->snr = (buf[1]) << 8 | buf[0];
-               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
-       }
-       return 0;
-}
-
-static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-       gp8psk_fe_update_status(st);
-
-       if (st->lock)
-               *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
-       else
-               *status = 0;
-
-       if (*status & FE_HAS_LOCK)
-               st->status_check_interval = 1000;
-       else
-               st->status_check_interval = 100;
-       return 0;
-}
-
-/* not supported by this Frontend */
-static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-       (void) fe;
-       *ber = 0;
-       return 0;
-}
-
-/* not supported by this Frontend */
-static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-       (void) fe;
-       *unc = 0;
-       return 0;
-}
-
-static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-       gp8psk_fe_update_status(st);
-       /* snr is reported in dBu*256 */
-       *snr = st->snr;
-       return 0;
-}
-
-static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-       gp8psk_fe_update_status(st);
-       /* snr is reported in dBu*256 */
-       /* snr / 38.4 ~= 100% strength */
-       /* snr * 17 returns 100% strength as 65535 */
-       if (st->snr > 0xf00)
-               *strength = 0xffff;
-       else
-               *strength = (st->snr << 4) + st->snr; /* snr*17 */
-       return 0;
-}
-
-static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 800;
-       return 0;
-}
-
-static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct gp8psk_fe_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 cmd[10];
-       u32 freq = c->frequency * 1000;
-       int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
-
-       deb_fe("%s()\n", __func__);
-
-       cmd[4] = freq         & 0xff;
-       cmd[5] = (freq >> 8)  & 0xff;
-       cmd[6] = (freq >> 16) & 0xff;
-       cmd[7] = (freq >> 24) & 0xff;
-
-       /* backwards compatibility: DVB-S + 8-PSK were used for Turbo-FEC */
-       if (c->delivery_system == SYS_DVBS && c->modulation == PSK_8)
-               c->delivery_system = SYS_TURBO;
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               if (c->modulation != QPSK) {
-                       deb_fe("%s: unsupported modulation selected (%d)\n",
-                               __func__, c->modulation);
-                       return -EOPNOTSUPP;
-               }
-               c->fec_inner = FEC_AUTO;
-               break;
-       case SYS_DVBS2: /* kept for backwards compatibility */
-               deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
-               break;
-       case SYS_TURBO:
-               deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
-               break;
-
-       default:
-               deb_fe("%s: unsupported delivery system selected (%d)\n",
-                       __func__, c->delivery_system);
-               return -EOPNOTSUPP;
-       }
-
-       cmd[0] =  c->symbol_rate        & 0xff;
-       cmd[1] = (c->symbol_rate >>  8) & 0xff;
-       cmd[2] = (c->symbol_rate >> 16) & 0xff;
-       cmd[3] = (c->symbol_rate >> 24) & 0xff;
-       switch (c->modulation) {
-       case QPSK:
-               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
-                       if (gp8psk_tuned_to_DCII(fe))
-                               gp8psk_bcm4500_reload(state->d);
-               switch (c->fec_inner) {
-               case FEC_1_2:
-                       cmd[9] = 0; break;
-               case FEC_2_3:
-                       cmd[9] = 1; break;
-               case FEC_3_4:
-                       cmd[9] = 2; break;
-               case FEC_5_6:
-                       cmd[9] = 3; break;
-               case FEC_7_8:
-                       cmd[9] = 4; break;
-               case FEC_AUTO:
-                       cmd[9] = 5; break;
-               default:
-                       cmd[9] = 5; break;
-               }
-               if (c->delivery_system == SYS_TURBO)
-                       cmd[8] = ADV_MOD_TURBO_QPSK;
-               else
-                       cmd[8] = ADV_MOD_DVB_QPSK;
-               break;
-       case PSK_8: /* PSK_8 is for compatibility with DN */
-               cmd[8] = ADV_MOD_TURBO_8PSK;
-               switch (c->fec_inner) {
-               case FEC_2_3:
-                       cmd[9] = 0; break;
-               case FEC_3_4:
-                       cmd[9] = 1; break;
-               case FEC_3_5:
-                       cmd[9] = 2; break;
-               case FEC_5_6:
-                       cmd[9] = 3; break;
-               case FEC_8_9:
-                       cmd[9] = 4; break;
-               default:
-                       cmd[9] = 0; break;
-               }
-               break;
-       case QAM_16: /* QAM_16 is for compatibility with DN */
-               cmd[8] = ADV_MOD_TURBO_16QAM;
-               cmd[9] = 0;
-               break;
-       default: /* Unknown modulation */
-               deb_fe("%s: unsupported modulation selected (%d)\n",
-                       __func__, c->modulation);
-               return -EOPNOTSUPP;
-       }
-
-       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
-               gp8psk_set_tuner_mode(fe, 0);
-       gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
-
-       state->lock = 0;
-       state->next_status_check = jiffies;
-       state->status_check_interval = 200;
-
-       return 0;
-}
-
-static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-
-       deb_fe("%s\n",__func__);
-
-       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
-                       m->msg, m->msg_len)) {
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
-                                   fe_sec_mini_cmd_t burst)
-{
-       struct gp8psk_fe_state *st = fe->demodulator_priv;
-       u8 cmd;
-
-       deb_fe("%s\n",__func__);
-
-       /* These commands are certainly wrong */
-       cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
-
-       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
-                       &cmd, 0)) {
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct gp8psk_fe_state* state = fe->demodulator_priv;
-
-       if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
-                (tone == SEC_TONE_ON), 0, NULL, 0)) {
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct gp8psk_fe_state* state = fe->demodulator_priv;
-
-       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
-                        voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
-{
-       struct gp8psk_fe_state* state = fe->demodulator_priv;
-       return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
-}
-
-static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
-{
-       struct gp8psk_fe_state* state = fe->demodulator_priv;
-       u8 cmd = sw_cmd & 0x7f;
-
-       if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
-                       NULL, 0)) {
-               return -EINVAL;
-       }
-       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
-                       0, NULL, 0)) {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void gp8psk_fe_release(struct dvb_frontend* fe)
-{
-       struct gp8psk_fe_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops gp8psk_fe_ops;
-
-struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
-{
-       struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
-       if (s == NULL)
-               goto error;
-
-       s->d = d;
-       memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
-       s->fe.demodulator_priv = s;
-
-       goto success;
-error:
-       return NULL;
-success:
-       return &s->fe;
-}
-
-
-static struct dvb_frontend_ops gp8psk_fe_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "Genpix DVB-S",
-               .frequency_min          = 800000,
-               .frequency_max          = 2250000,
-               .frequency_stepsize     = 100,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,  /* ppm */
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       /*
-                        * FE_CAN_QAM_16 is for compatibility
-                        * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
-                        */
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
-       },
-
-       .release = gp8psk_fe_release,
-
-       .init = NULL,
-       .sleep = NULL,
-
-       .set_frontend = gp8psk_fe_set_frontend,
-
-       .get_tune_settings = gp8psk_fe_get_tune_settings,
-
-       .read_status = gp8psk_fe_read_status,
-       .read_ber = gp8psk_fe_read_ber,
-       .read_signal_strength = gp8psk_fe_read_signal_strength,
-       .read_snr = gp8psk_fe_read_snr,
-       .read_ucblocks = gp8psk_fe_read_unc_blocks,
-
-       .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
-       .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
-       .set_tone = gp8psk_fe_set_tone,
-       .set_voltage = gp8psk_fe_set_voltage,
-       .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
-       .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
-};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
deleted file mode 100644 (file)
index 5d0384d..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
- *
- * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
- * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
- *
- * Thanks to GENPIX for the sample code used to implement this module.
- *
- * This module is based off the vp7045 and vp702x modules
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "gp8psk.h"
-
-/* debug */
-static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
-int dvb_usb_gp8psk_debug;
-module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
-{
-       return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
-}
-
-static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
-{
-       return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
-}
-
-static void gp8psk_info(struct dvb_usb_device *d)
-{
-       u8 fpga_vers, fw_vers[6];
-
-       if (!gp8psk_get_fw_version(d, fw_vers))
-               info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
-               fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
-               2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
-       else
-               info("failed to get FW version");
-
-       if (!gp8psk_get_fpga_version(d, &fpga_vers))
-               info("FPGA Version = %i", fpga_vers);
-       else
-               info("failed to get FPGA version");
-}
-
-int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
-{
-       int ret = 0,try = 0;
-
-       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
-               return ret;
-
-       while (ret >= 0 && ret != blen && try < 3) {
-               ret = usb_control_msg(d->udev,
-                       usb_rcvctrlpipe(d->udev,0),
-                       req,
-                       USB_TYPE_VENDOR | USB_DIR_IN,
-                       value,index,b,blen,
-                       2000);
-               deb_info("reading number %d (ret: %d)\n",try,ret);
-               try++;
-       }
-
-       if (ret < 0 || ret != blen) {
-               warn("usb in %d operation failed.", req);
-               ret = -EIO;
-       } else
-               ret = 0;
-
-       deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
-       debug_dump(b,blen,deb_xfer);
-
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-                            u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
-       debug_dump(b,blen,deb_xfer);
-
-       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
-               return ret;
-
-       if (usb_control_msg(d->udev,
-                       usb_sndctrlpipe(d->udev,0),
-                       req,
-                       USB_TYPE_VENDOR | USB_DIR_OUT,
-                       value,index,b,blen,
-                       2000) != blen) {
-               warn("usb out operation failed.");
-               ret = -EIO;
-       } else
-               ret = 0;
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
-{
-       int ret;
-       const struct firmware *fw = NULL;
-       const u8 *ptr;
-       u8 *buf;
-       if ((ret = request_firmware(&fw, bcm4500_firmware,
-                                       &d->udev->dev)) != 0) {
-               err("did not find the bcm4500 firmware file. (%s) "
-                       "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
-                       bcm4500_firmware,ret);
-               return ret;
-       }
-
-       ret = -EINVAL;
-
-       if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
-               goto out_rel_fw;
-
-       info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
-
-       ptr = fw->data;
-       buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto out_rel_fw;
-       }
-
-       while (ptr[0] != 0xff) {
-               u16 buflen = ptr[0] + 4;
-               if (ptr + buflen >= fw->data + fw->size) {
-                       err("failed to load bcm4500 firmware.");
-                       goto out_free;
-               }
-               memcpy(buf, ptr, buflen);
-               if (dvb_usb_generic_write(d, buf, buflen)) {
-                       err("failed to load bcm4500 firmware.");
-                       goto out_free;
-               }
-               ptr += buflen;
-       }
-
-       ret = 0;
-
-out_free:
-       kfree(buf);
-out_rel_fw:
-       release_firmware(fw);
-
-       return ret;
-}
-
-static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 status, buf;
-       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
-
-       if (onoff) {
-               gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
-               if (! (status & bm8pskStarted)) {  /* started */
-                       if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
-                               gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
-                       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
-                               return -EINVAL;
-                       gp8psk_info(d);
-               }
-
-               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
-                       if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
-                               if(gp8psk_load_bcm4500fw(d))
-                                       return -EINVAL;
-
-               if (! (status & bmIntersilOn)) /* LNB Power */
-                       if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
-                                       &buf, 1))
-                               return -EINVAL;
-
-               /* Set DVB mode to 1 */
-               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
-                       if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
-                               return -EINVAL;
-               /* Abort possible TS (if previous tune crashed) */
-               if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
-                       return -EINVAL;
-       } else {
-               /* Turn off LNB power */
-               if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
-                       return -EINVAL;
-               /* Turn off 8psk power */
-               if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
-                       return -EINVAL;
-               if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
-                       gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
-       }
-       return 0;
-}
-
-int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
-{
-       u8 buf;
-       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
-       /* Turn off 8psk power */
-       if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
-               return -EINVAL;
-       /* Turn On 8psk power */
-       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
-               return -EINVAL;
-       /* load BCM4500 firmware */
-       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
-               if (gp8psk_load_bcm4500fw(d))
-                       return -EINVAL;
-       return 0;
-}
-
-static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
-}
-
-static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
-       return 0;
-}
-
-static struct dvb_usb_device_properties gp8psk_properties;
-
-static int gp8psk_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       int ret;
-       struct usb_device *udev = interface_to_usbdev(intf);
-       ret = dvb_usb_device_init(intf, &gp8psk_properties,
-                                 THIS_MODULE, NULL, adapter_nr);
-       if (ret == 0) {
-               info("found Genpix USB device pID = %x (hex)",
-                       le16_to_cpu(udev->descriptor.idProduct));
-       }
-       return ret;
-}
-
-static struct usb_device_id gp8psk_usb_table [] = {
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
-/*         { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
-           { 0 },
-};
-MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
-
-static struct dvb_usb_device_properties gp8psk_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-gp8psk-01.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = gp8psk_streaming_ctrl,
-                       .frontend_attach  = gp8psk_frontend_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 8192,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .power_ctrl       = gp8psk_power_ctrl,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 4,
-       .devices = {
-               { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
-                 .cold_ids = { &gp8psk_usb_table[0], NULL },
-                 .warm_ids = { &gp8psk_usb_table[1], NULL },
-               },
-               { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
-                 .cold_ids = { NULL },
-                 .warm_ids = { &gp8psk_usb_table[2], NULL },
-               },
-               { .name = "Genpix SkyWalker-1 DVB-S receiver",
-                 .cold_ids = { NULL },
-                 .warm_ids = { &gp8psk_usb_table[3], NULL },
-               },
-               { .name = "Genpix SkyWalker-2 DVB-S receiver",
-                 .cold_ids = { NULL },
-                 .warm_ids = { &gp8psk_usb_table[4], NULL },
-               },
-               { NULL },
-       }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver gp8psk_usb_driver = {
-       .name           = "dvb_usb_gp8psk",
-       .probe          = gp8psk_usb_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = gp8psk_usb_table,
-};
-
-module_usb_driver(gp8psk_usb_driver);
-
-MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
-MODULE_DESCRIPTION("Driver for Genpix DVB-S");
-MODULE_VERSION("1.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
deleted file mode 100644 (file)
index ed32b9d..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
- *
- * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
- * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
- *
- * Thanks to GENPIX for the sample code used to implement this module.
- *
- * This module is based off the vp7045 and vp702x modules
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_GP8PSK_H_
-#define _DVB_USB_GP8PSK_H_
-
-#define DVB_USB_LOG_PREFIX "gp8psk"
-#include "dvb-usb.h"
-
-extern int dvb_usb_gp8psk_debug;
-#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
-#define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
-#define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
-
-/* Twinhan Vendor requests */
-#define TH_COMMAND_IN                     0xC0
-#define TH_COMMAND_OUT                    0xC1
-
-/* gp8psk commands */
-
-#define GET_8PSK_CONFIG                 0x80    /* in */
-#define SET_8PSK_CONFIG                 0x81
-#define I2C_WRITE                      0x83
-#define I2C_READ                       0x84
-#define ARM_TRANSFER                    0x85
-#define TUNE_8PSK                       0x86
-#define GET_SIGNAL_STRENGTH             0x87    /* in */
-#define LOAD_BCM4500                    0x88
-#define BOOT_8PSK                       0x89    /* in */
-#define START_INTERSIL                  0x8A    /* in */
-#define SET_LNB_VOLTAGE                 0x8B
-#define SET_22KHZ_TONE                  0x8C
-#define SEND_DISEQC_COMMAND             0x8D
-#define SET_DVB_MODE                    0x8E
-#define SET_DN_SWITCH                   0x8F
-#define GET_SIGNAL_LOCK                 0x90    /* in */
-#define GET_FW_VERS                    0x92
-#define GET_SERIAL_NUMBER               0x93    /* in */
-#define USE_EXTRA_VOLT                  0x94
-#define GET_FPGA_VERS                  0x95
-#define CW3K_INIT                      0x9d
-
-/* PSK_configuration bits */
-#define bm8pskStarted                   0x01
-#define bm8pskFW_Loaded                 0x02
-#define bmIntersilOn                    0x04
-#define bmDVBmode                       0x08
-#define bm22kHz                         0x10
-#define bmSEL18V                        0x20
-#define bmDCtuned                       0x40
-#define bmArmed                         0x80
-
-/* Satellite modulation modes */
-#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
-#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
-#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
-#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
-
-#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
-#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
-#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
-#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
-#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
-#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
-
-#define GET_USB_SPEED                     0x07
-
-#define RESET_FX2                         0x13
-
-#define FW_VERSION_READ                   0x0B
-#define VENDOR_STRING_READ                0x0C
-#define PRODUCT_STRING_READ               0x0D
-#define FW_BCD_VERSION_READ               0x14
-
-/* firmware revision id's */
-#define GP8PSK_FW_REV1                 0x020604
-#define GP8PSK_FW_REV2                 0x020704
-#define GP8PSK_FW_VERS(_fw_vers)       ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
-
-extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
-extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-                            u16 index, u8 *b, int blen);
-extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
deleted file mode 100644 (file)
index 288af29..0000000
+++ /dev/null
@@ -1,1099 +0,0 @@
-/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-
-#include "m920x.h"
-
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "qt1010.h"
-#include "tda1004x.h"
-#include "tda827x.h"
-
-#include <media/tuner.h>
-#include "tuner-simple.h"
-#include <asm/unaligned.h>
-
-/* debug */
-static int dvb_usb_m920x_debug;
-module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
-
-static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
-                            u16 index, void *data, int size)
-{
-       int ret;
-
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                             request, USB_TYPE_VENDOR | USB_DIR_IN,
-                             value, index, data, size, 2000);
-       if (ret < 0) {
-               printk(KERN_INFO "m920x_read = error: %d\n", ret);
-               return ret;
-       }
-
-       if (ret != size) {
-               deb("m920x_read = no data\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static inline int m920x_write(struct usb_device *udev, u8 request,
-                             u16 value, u16 index)
-{
-       int ret;
-
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                             request, USB_TYPE_VENDOR | USB_DIR_OUT,
-                             value, index, NULL, 0, 2000);
-
-       return ret;
-}
-
-static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
-{
-       int ret = 0, i, epi, flags = 0;
-       int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
-
-       /* Remote controller init. */
-       if (d->props.rc.legacy.rc_query) {
-               deb("Initialising remote control\n");
-               while (rc_seq->address) {
-                       if ((ret = m920x_write(d->udev, M9206_CORE,
-                                              rc_seq->data,
-                                              rc_seq->address)) != 0) {
-                               deb("Initialising remote control failed\n");
-                               return ret;
-                       }
-
-                       rc_seq++;
-               }
-
-               deb("Initialising remote control success\n");
-       }
-
-       for (i = 0; i < d->props.num_adapters; i++)
-               flags |= d->adapter[i].props.fe[0].caps;
-
-       /* Some devices(Dposh) might crash if we attempt touch at all. */
-       if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
-               for (i = 0; i < d->props.num_adapters; i++) {
-                       epi = d->adapter[i].props.fe[0].stream.endpoint - 0x81;
-
-                       if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
-                               printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
-                               return -EINVAL;
-                       }
-
-                       adap_enabled[epi] = 1;
-               }
-
-               for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
-                       if (adap_enabled[i])
-                               continue;
-
-                       if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
-                               return ret;
-
-                       if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
-                               return ret;
-               }
-       }
-
-       return ret;
-}
-
-static int m920x_init_ep(struct usb_interface *intf)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct usb_host_interface *alt;
-
-       if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
-               deb("No alt found!\n");
-               return -ENODEV;
-       }
-
-       return usb_set_interface(udev, alt->desc.bInterfaceNumber,
-                                alt->desc.bAlternateSetting);
-}
-
-static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       struct m920x_state *m = d->priv;
-       int i, ret = 0;
-       u8 *rc_state;
-
-       rc_state = kmalloc(2, GFP_KERNEL);
-       if (!rc_state)
-               return -ENOMEM;
-
-       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
-               goto out;
-
-       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
-               goto out;
-
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
-               if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
-                       *event = d->props.rc.legacy.rc_map_table[i].keycode;
-
-                       switch(rc_state[0]) {
-                       case 0x80:
-                               *state = REMOTE_NO_KEY_PRESSED;
-                               goto out;
-
-                       case 0x88: /* framing error or "invalid code" */
-                       case 0x99:
-                       case 0xc0:
-                       case 0xd8:
-                               *state = REMOTE_NO_KEY_PRESSED;
-                               m->rep_count = 0;
-                               goto out;
-
-                       case 0x93:
-                       case 0x92:
-                       case 0x83: /* pinnacle PCTV310e */
-                       case 0x82:
-                               m->rep_count = 0;
-                               *state = REMOTE_KEY_PRESSED;
-                               goto out;
-
-                       case 0x91:
-                       case 0x81: /* pinnacle PCTV310e */
-                               /* prevent immediate auto-repeat */
-                               if (++m->rep_count > 2)
-                                       *state = REMOTE_KEY_REPEAT;
-                               else
-                                       *state = REMOTE_NO_KEY_PRESSED;
-                               goto out;
-
-                       default:
-                               deb("Unexpected rc state %02x\n", rc_state[0]);
-                               *state = REMOTE_NO_KEY_PRESSED;
-                               goto out;
-                       }
-               }
-
-       if (rc_state[1] != 0)
-               deb("Unknown rc key %02x\n", rc_state[1]);
-
-       *state = REMOTE_NO_KEY_PRESSED;
-
- out:
-       kfree(rc_state);
-       return ret;
-}
-
-/* I2C */
-static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i, j;
-       int ret = 0;
-
-       if (!num)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
-                       /* For a 0 byte message, I think sending the address
-                        * to index 0x80|0x40 would be the correct thing to
-                        * do.  However, zero byte messages are only used for
-                        * probing, and since we don't know how to get the
-                        * slave's ack, we can't probe. */
-                       ret = -ENOTSUPP;
-                       goto unlock;
-               }
-               /* Send START & address/RW bit */
-               if (!(msg[i].flags & I2C_M_NOSTART)) {
-                       if ((ret = m920x_write(d->udev, M9206_I2C,
-                                       (msg[i].addr << 1) |
-                                       (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
-                               goto unlock;
-                       /* Should check for ack here, if we knew how. */
-               }
-               if (msg[i].flags & I2C_M_RD) {
-                       for (j = 0; j < msg[i].len; j++) {
-                               /* Last byte of transaction?
-                                * Send STOP, otherwise send ACK. */
-                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
-
-                               if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
-                                                     0x20 | stop,
-                                                     &msg[i].buf[j], 1)) != 0)
-                                       goto unlock;
-                       }
-               } else {
-                       for (j = 0; j < msg[i].len; j++) {
-                               /* Last byte of transaction? Then send STOP. */
-                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
-
-                               if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
-                                       goto unlock;
-                               /* Should check for ack here too. */
-                       }
-               }
-       }
-       ret = num;
-
- unlock:
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 m920x_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm m920x_i2c_algo = {
-       .master_xfer   = m920x_i2c_xfer,
-       .functionality = m920x_i2c_func,
-};
-
-/* pid filter */
-static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
-{
-       int ret = 0;
-
-       if (pid >= 0x8000)
-               return -EINVAL;
-
-       pid |= 0x8000;
-
-       if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
-               return ret;
-
-       if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
-               return ret;
-
-       return ret;
-}
-
-static int m920x_update_filters(struct dvb_usb_adapter *adap)
-{
-       struct m920x_state *m = adap->dev->priv;
-       int enabled = m->filtering_enabled[adap->id];
-       int i, ret = 0, filter = 0;
-       int ep = adap->props.fe[0].stream.endpoint;
-
-       for (i = 0; i < M9206_MAX_FILTERS; i++)
-               if (m->filters[adap->id][i] == 8192)
-                       enabled = 0;
-
-       /* Disable all filters */
-       if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
-               return ret;
-
-       for (i = 0; i < M9206_MAX_FILTERS; i++)
-               if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
-                       return ret;
-
-       /* Set */
-       if (enabled) {
-               for (i = 0; i < M9206_MAX_FILTERS; i++) {
-                       if (m->filters[adap->id][i] == 0)
-                               continue;
-
-                       if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
-                               return ret;
-
-                       filter++;
-               }
-       }
-
-       return ret;
-}
-
-static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct m920x_state *m = adap->dev->priv;
-
-       m->filtering_enabled[adap->id] = onoff ? 1 : 0;
-
-       return m920x_update_filters(adap);
-}
-
-static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
-{
-       struct m920x_state *m = adap->dev->priv;
-
-       m->filters[adap->id][index] = onoff ? pid : 0;
-
-       return m920x_update_filters(adap);
-}
-
-static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
-{
-       u16 value, index, size;
-       u8 *read, *buff;
-       int i, pass, ret = 0;
-
-       buff = kmalloc(65536, GFP_KERNEL);
-       if (buff == NULL)
-               return -ENOMEM;
-
-       read = kmalloc(4, GFP_KERNEL);
-       if (!read) {
-               kfree(buff);
-               return -ENOMEM;
-       }
-
-       if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
-               goto done;
-       deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
-
-       if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
-               goto done;
-       deb("%x\n", read[0]);
-
-       for (pass = 0; pass < 2; pass++) {
-               for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
-                       value = get_unaligned_le16(fw->data + i);
-                       i += sizeof(u16);
-
-                       index = get_unaligned_le16(fw->data + i);
-                       i += sizeof(u16);
-
-                       size = get_unaligned_le16(fw->data + i);
-                       i += sizeof(u16);
-
-                       if (pass == 1) {
-                               /* Will stall if using fw->data ... */
-                               memcpy(buff, fw->data + i, size);
-
-                               ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-                                                     M9206_FW,
-                                                     USB_TYPE_VENDOR | USB_DIR_OUT,
-                                                     value, index, buff, size, 20);
-                               if (ret != size) {
-                                       deb("error while uploading fw!\n");
-                                       ret = -EIO;
-                                       goto done;
-                               }
-                               msleep(3);
-                       }
-                       i += size;
-               }
-               if (i != fw->size) {
-                       deb("bad firmware file!\n");
-                       ret = -EINVAL;
-                       goto done;
-               }
-       }
-
-       msleep(36);
-
-       /* m920x will disconnect itself from the bus after this. */
-       (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
-       deb("firmware uploaded!\n");
-
- done:
-       kfree(read);
-       kfree(buff);
-
-       return ret;
-}
-
-/* Callbacks for DVB USB */
-static int m920x_identify_state(struct usb_device *udev,
-                               struct dvb_usb_device_properties *props,
-                               struct dvb_usb_device_description **desc,
-                               int *cold)
-{
-       struct usb_host_interface *alt;
-
-       alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
-       *cold = (alt == NULL) ? 1 : 0;
-
-       return 0;
-}
-
-/* demod configurations */
-static int m920x_mt352_demod_init(struct dvb_frontend *fe)
-{
-       int ret;
-       u8 config[] = { CONFIG, 0x3d };
-       u8 clock[] = { CLOCK_CTL, 0x30 };
-       u8 reset[] = { RESET, 0x80 };
-       u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
-       u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
-       u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
-       u8 unk1[] = { 0x93, 0x1a };
-       u8 unk2[] = { 0xb5, 0x7a };
-
-       deb("Demod init!\n");
-
-       if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
-               return ret;
-       if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
-               return ret;
-
-       return 0;
-}
-
-static struct mt352_config m920x_mt352_config = {
-       .demod_address = 0x0f,
-       .no_tuner = 1,
-       .demod_init = m920x_mt352_demod_init,
-};
-
-static struct tda1004x_config m920x_tda10046_08_config = {
-       .demod_address = 0x08,
-       .invert = 0,
-       .invert_oclk = 0,
-       .ts_mode = TDA10046_TS_SERIAL,
-       .xtal_freq = TDA10046_XTAL_16M,
-       .if_freq = TDA10046_FREQ_045,
-       .agc_config = TDA10046_AGC_TDA827X,
-       .gpio_config = TDA10046_GPTRI,
-       .request_firmware = NULL,
-};
-
-static struct tda1004x_config m920x_tda10046_0b_config = {
-       .demod_address = 0x0b,
-       .invert = 0,
-       .invert_oclk = 0,
-       .ts_mode = TDA10046_TS_SERIAL,
-       .xtal_freq = TDA10046_XTAL_16M,
-       .if_freq = TDA10046_FREQ_045,
-       .agc_config = TDA10046_AGC_TDA827X,
-       .gpio_config = TDA10046_GPTRI,
-       .request_firmware = NULL, /* uses firmware EEPROM */
-};
-
-/* tuner configurations */
-static struct qt1010_config m920x_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-/* Callbacks for DVB USB */
-static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach,
-                                        &m920x_mt352_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
-                                        &m920x_tda10046_08_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
-                                        &m920x_tda10046_0b_config,
-                                        &adap->dev->i2c_adap);
-       if ((adap->fe_adap[0].fe) == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       if (dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       deb("%s\n",__func__);
-
-       if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
-                  &adap->dev->i2c_adap, 0x61,
-                  TUNER_PHILIPS_FMD1216ME_MK3);
-       return 0;
-}
-
-/* device-specific initialization */
-static struct m920x_inits megasky_rc_init [] = {
-       { M9206_RC_INIT2, 0xa8 },
-       { M9206_RC_INIT1, 0x51 },
-       { } /* terminating entry */
-};
-
-static struct m920x_inits tvwalkertwin_rc_init [] = {
-       { M9206_RC_INIT2, 0x00 },
-       { M9206_RC_INIT1, 0xef },
-       { 0xff28,         0x00 },
-       { 0xff23,         0x00 },
-       { 0xff21,         0x30 },
-       { } /* terminating entry */
-};
-
-static struct m920x_inits pinnacle310e_init[] = {
-       /* without these the tuner don't work */
-       { 0xff20,         0x9b },
-       { 0xff22,         0x70 },
-
-       /* rc settings */
-       { 0xff50,         0x80 },
-       { M9206_RC_INIT1, 0x00 },
-       { M9206_RC_INIT2, 0xff },
-       { } /* terminating entry */
-};
-
-/* ir keymaps */
-static struct rc_map_table rc_map_megasky_table[] = {
-       { 0x0012, KEY_POWER },
-       { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
-       { 0x0002, KEY_CHANNELUP },
-       { 0x0005, KEY_CHANNELDOWN },
-       { 0x0003, KEY_VOLUMEUP },
-       { 0x0006, KEY_VOLUMEDOWN },
-       { 0x0004, KEY_MUTE },
-       { 0x0007, KEY_OK }, /* TS */
-       { 0x0008, KEY_STOP },
-       { 0x0009, KEY_MENU }, /* swap */
-       { 0x000a, KEY_REWIND },
-       { 0x001b, KEY_PAUSE },
-       { 0x001f, KEY_FASTFORWARD },
-       { 0x000c, KEY_RECORD },
-       { 0x000d, KEY_CAMERA }, /* screenshot */
-       { 0x000e, KEY_COFFEE }, /* "MTS" */
-};
-
-static struct rc_map_table rc_map_tvwalkertwin_table[] = {
-       { 0x0001, KEY_ZOOM }, /* Full Screen */
-       { 0x0002, KEY_CAMERA }, /* snapshot */
-       { 0x0003, KEY_MUTE },
-       { 0x0004, KEY_REWIND },
-       { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
-       { 0x0006, KEY_FASTFORWARD },
-       { 0x0007, KEY_RECORD },
-       { 0x0008, KEY_STOP },
-       { 0x0009, KEY_TIME }, /* Timeshift */
-       { 0x000c, KEY_COFFEE }, /* Recall */
-       { 0x000e, KEY_CHANNELUP },
-       { 0x0012, KEY_POWER },
-       { 0x0015, KEY_MENU }, /* source */
-       { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
-       { 0x001a, KEY_CHANNELDOWN },
-       { 0x001b, KEY_VOLUMEDOWN },
-       { 0x001e, KEY_VOLUMEUP },
-};
-
-static struct rc_map_table rc_map_pinnacle310e_table[] = {
-       { 0x16, KEY_POWER },
-       { 0x17, KEY_FAVORITES },
-       { 0x0f, KEY_TEXT },
-       { 0x48, KEY_PROGRAM },          /* preview */
-       { 0x1c, KEY_EPG },
-       { 0x04, KEY_LIST },             /* record list */
-       { 0x03, KEY_1 },
-       { 0x01, KEY_2 },
-       { 0x06, KEY_3 },
-       { 0x09, KEY_4 },
-       { 0x1d, KEY_5 },
-       { 0x1f, KEY_6 },
-       { 0x0d, KEY_7 },
-       { 0x19, KEY_8 },
-       { 0x1b, KEY_9 },
-       { 0x15, KEY_0 },
-       { 0x0c, KEY_CANCEL },
-       { 0x4a, KEY_CLEAR },
-       { 0x13, KEY_BACK },
-       { 0x00, KEY_TAB },
-       { 0x4b, KEY_UP },
-       { 0x4e, KEY_LEFT },
-       { 0x52, KEY_RIGHT },
-       { 0x51, KEY_DOWN },
-       { 0x4f, KEY_ENTER },            /* could also be KEY_OK */
-       { 0x1e, KEY_VOLUMEUP },
-       { 0x0a, KEY_VOLUMEDOWN },
-       { 0x05, KEY_CHANNELUP },
-       { 0x02, KEY_CHANNELDOWN },
-       { 0x11, KEY_RECORD },
-       { 0x14, KEY_PLAY },
-       { 0x4c, KEY_PAUSE },
-       { 0x1a, KEY_STOP },
-       { 0x40, KEY_REWIND },
-       { 0x12, KEY_FASTFORWARD },
-       { 0x41, KEY_PREVIOUSSONG },     /* Replay */
-       { 0x42, KEY_NEXTSONG },         /* Skip */
-       { 0x54, KEY_CAMERA },           /* Capture */
-/*     { 0x50, KEY_SAP },      */              /* Sap */
-       { 0x47, KEY_CYCLEWINDOWS },     /* Pip */
-       { 0x4d, KEY_SCREEN },           /* FullScreen */
-       { 0x08, KEY_SUBTITLE },
-       { 0x0e, KEY_MUTE },
-/*     { 0x49, KEY_LR },       */              /* L/R */
-       { 0x07, KEY_SLEEP },            /* Hibernate */
-       { 0x08, KEY_VIDEO },            /* A/V */
-       { 0x0e, KEY_MENU },             /* Recall */
-       { 0x45, KEY_ZOOMIN },
-       { 0x46, KEY_ZOOMOUT },
-       { 0x18, KEY_RED },              /* Red */
-       { 0x53, KEY_GREEN },            /* Green */
-       { 0x5e, KEY_YELLOW },           /* Yellow */
-       { 0x5f, KEY_BLUE },             /* Blue */
-};
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties megasky_properties;
-static struct dvb_usb_device_properties digivox_mini_ii_properties;
-static struct dvb_usb_device_properties tvwalkertwin_properties;
-static struct dvb_usb_device_properties dposh_properties;
-static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
-
-static int m920x_probe(struct usb_interface *intf,
-                      const struct usb_device_id *id)
-{
-       struct dvb_usb_device *d = NULL;
-       int ret;
-       struct m920x_inits *rc_init_seq = NULL;
-       int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
-
-       deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
-
-       if (bInterfaceNumber == 0) {
-               /* Single-tuner device, or first interface on
-                * multi-tuner device
-                */
-
-               ret = dvb_usb_device_init(intf, &megasky_properties,
-                                         THIS_MODULE, &d, adapter_nr);
-               if (ret == 0) {
-                       rc_init_seq = megasky_rc_init;
-                       goto found;
-               }
-
-               ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
-                                         THIS_MODULE, &d, adapter_nr);
-               if (ret == 0) {
-                       /* No remote control, so no rc_init_seq */
-                       goto found;
-               }
-
-               /* This configures both tuners on the TV Walker Twin */
-               ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
-                                         THIS_MODULE, &d, adapter_nr);
-               if (ret == 0) {
-                       rc_init_seq = tvwalkertwin_rc_init;
-                       goto found;
-               }
-
-               ret = dvb_usb_device_init(intf, &dposh_properties,
-                                         THIS_MODULE, &d, adapter_nr);
-               if (ret == 0) {
-                       /* Remote controller not supported yet. */
-                       goto found;
-               }
-
-               ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
-                                         THIS_MODULE, &d, adapter_nr);
-               if (ret == 0) {
-                       rc_init_seq = pinnacle310e_init;
-                       goto found;
-               }
-
-               return ret;
-       } else {
-               /* Another interface on a multi-tuner device */
-
-               /* The LifeView TV Walker Twin gets here, but struct
-                * tvwalkertwin_properties already configured both
-                * tuners, so there is nothing for us to do here
-                */
-       }
-
- found:
-       if ((ret = m920x_init_ep(intf)) < 0)
-               return ret;
-
-       if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
-               return ret;
-
-       return ret;
-}
-
-static struct usb_device_id m920x_table [] = {
-               { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
-               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
-                            USB_PID_MSI_DIGI_VOX_MINI_II) },
-               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
-                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
-               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
-                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
-               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
-               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
-               { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
-               { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, m920x_table);
-
-static struct dvb_usb_device_properties megasky_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-megasky-02.fw",
-       .download_firmware = m920x_firmware_download,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_megasky_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_megasky_table),
-               .rc_query         = m920x_rc_query,
-       },
-
-       .size_of_priv     = sizeof(struct m920x_state),
-
-       .identify_state   = m920x_identify_state,
-       .num_adapters = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-
-               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
-               .pid_filter_count = 8,
-               .pid_filter       = m920x_pid_filter,
-               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
-
-               .frontend_attach  = m920x_mt352_frontend_attach,
-               .tuner_attach     = m920x_qt1010_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x81,
-                       .u = {
-                               .bulk = {
-                                       .buffersize = 512,
-                               }
-                       }
-               },
-               }},
-       }},
-       .i2c_algo         = &m920x_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "MSI Mega Sky 580 DVB-T USB2.0",
-                       { &m920x_table[0], NULL },
-                       { NULL },
-               }
-       }
-};
-
-static struct dvb_usb_device_properties digivox_mini_ii_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-digivox-02.fw",
-       .download_firmware = m920x_firmware_download,
-
-       .size_of_priv     = sizeof(struct m920x_state),
-
-       .identify_state   = m920x_identify_state,
-       .num_adapters = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-
-               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
-               .pid_filter_count = 8,
-               .pid_filter       = m920x_pid_filter,
-               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
-
-               .frontend_attach  = m920x_tda10046_08_frontend_attach,
-               .tuner_attach     = m920x_tda8275_60_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x81,
-                       .u = {
-                               .bulk = {
-                                       .buffersize = 0x4000,
-                               }
-                       }
-               },
-               }},
-       }},
-       .i2c_algo         = &m920x_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "MSI DIGI VOX mini II DVB-T USB2.0",
-                       { &m920x_table[1], NULL },
-                       { NULL },
-               },
-       }
-};
-
-/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
- *
- * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
- * TDA10046 #0 is located at i2c address 0x08
- * TDA10046 #1 is located at i2c address 0x0b
- * TDA8275A #0 is located at i2c address 0x60
- * TDA8275A #1 is located at i2c address 0x61
- */
-static struct dvb_usb_device_properties tvwalkertwin_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-tvwalkert.fw",
-       .download_firmware = m920x_firmware_download,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_tvwalkertwin_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_tvwalkertwin_table),
-               .rc_query         = m920x_rc_query,
-       },
-
-       .size_of_priv     = sizeof(struct m920x_state),
-
-       .identify_state   = m920x_identify_state,
-       .num_adapters = 2,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-
-               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
-               .pid_filter_count = 8,
-               .pid_filter       = m920x_pid_filter,
-               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
-
-               .frontend_attach  = m920x_tda10046_08_frontend_attach,
-               .tuner_attach     = m920x_tda8275_60_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x81,
-                       .u = {
-                                .bulk = {
-                                        .buffersize = 512,
-                                }
-                       }
-               }},
-               }},{
-               .num_frontends = 1,
-               .fe = {{
-
-               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
-               .pid_filter_count = 8,
-               .pid_filter       = m920x_pid_filter,
-               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
-
-               .frontend_attach  = m920x_tda10046_0b_frontend_attach,
-               .tuner_attach     = m920x_tda8275_61_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x82,
-                       .u = {
-                                .bulk = {
-                                        .buffersize = 512,
-                                }
-                       }
-               }},
-               },
-       }},
-       .i2c_algo         = &m920x_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   .name = "LifeView TV Walker Twin DVB-T USB2.0",
-                   .cold_ids = { &m920x_table[2], NULL },
-                   .warm_ids = { &m920x_table[3], NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties dposh_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .firmware = "dvb-usb-dposh-01.fw",
-       .download_firmware = m920x_firmware_download,
-
-       .size_of_priv     = sizeof(struct m920x_state),
-
-       .identify_state   = m920x_identify_state,
-       .num_adapters = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-               /* Hardware pid filters don't work with this device/firmware */
-
-               .frontend_attach  = m920x_mt352_frontend_attach,
-               .tuner_attach     = m920x_qt1010_tuner_attach,
-
-               .stream = {
-                       .type = USB_BULK,
-                       .count = 8,
-                       .endpoint = 0x81,
-                       .u = {
-                                .bulk = {
-                                        .buffersize = 512,
-                                }
-                       }
-               },
-               }},
-       }},
-       .i2c_algo         = &m920x_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-                {   .name = "Dposh DVB-T USB2.0",
-                    .cold_ids = { &m920x_table[4], NULL },
-                    .warm_ids = { &m920x_table[5], NULL },
-                },
-        }
-};
-
-static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = DEVICE_SPECIFIC,
-       .download_firmware = NULL,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_pinnacle310e_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_pinnacle310e_table),
-               .rc_query         = m920x_rc_query,
-       },
-
-       .size_of_priv     = sizeof(struct m920x_state),
-
-       .identify_state   = m920x_identify_state,
-       .num_adapters = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-
-               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
-               .pid_filter_count = 8,
-               .pid_filter       = m920x_pid_filter,
-               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
-
-               .frontend_attach  = m920x_mt352_frontend_attach,
-               .tuner_attach     = m920x_fmd1216me_tuner_attach,
-
-               .stream = {
-                       .type = USB_ISOC,
-                       .count = 5,
-                       .endpoint = 0x84,
-                       .u = {
-                               .isoc = {
-                                       .framesperurb = 128,
-                                       .framesize = 564,
-                                       .interval = 1,
-                               }
-                       }
-               },
-               }},
-       } },
-       .i2c_algo         = &m920x_i2c_algo,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Pinnacle PCTV 310e",
-                       { &m920x_table[6], NULL },
-                       { NULL },
-               }
-       }
-};
-
-static struct usb_driver m920x_driver = {
-       .name           = "dvb_usb_m920x",
-       .probe          = m920x_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = m920x_table,
-};
-
-module_usb_driver(m920x_driver);
-
-MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_DESCRIPTION("DVB Driver for ULI M920x");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h
deleted file mode 100644 (file)
index 3c06151..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef _DVB_USB_M920X_H_
-#define _DVB_USB_M920X_H_
-
-#define DVB_USB_LOG_PREFIX "m920x"
-#include "dvb-usb.h"
-
-#define deb(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
-
-#define M9206_CORE     0x22
-#define M9206_RC_STATE 0xff51
-#define M9206_RC_KEY   0xff52
-#define M9206_RC_INIT1 0xff54
-#define M9206_RC_INIT2 0xff55
-#define M9206_FW_GO    0xff69
-
-#define M9206_I2C      0x23
-#define M9206_FILTER   0x25
-#define M9206_FW       0x30
-
-#define M9206_MAX_FILTERS 8
-#define M9206_MAX_ADAPTERS 4
-
-/*
-sequences found in logs:
-[index value]
-0x80 write addr
-(0x00 out byte)*
-0x40 out byte
-
-0x80 write addr
-(0x00 out byte)*
-0x80 read addr
-(0x21 in byte)*
-0x60 in byte
-
-this sequence works:
-0x80 read addr
-(0x21 in byte)*
-0x60 in byte
-
-Guess at API of the I2C function:
-I2C operation is done one byte at a time with USB control messages.  The
-index the messages is sent to is made up of a set of flags that control
-the I2C bus state:
-0x80:  Send START condition.  After a START condition, one would normally
-       always send the 7-bit slave I2C address as the 7 MSB, followed by
-       the read/write bit as the LSB.
-0x40:  Send STOP condition.  This should be set on the last byte of an
-       I2C transaction.
-0x20:  Read a byte from the slave.  As opposed to writing a byte to the
-       slave.  The slave will normally not produce any data unless you
-       set the R/W bit to 1 when sending the slave's address after the
-       START condition.
-0x01:  Respond with ACK, as opposed to a NACK.  For a multi-byte read,
-       the master should send an ACK, that is pull SDA low during the 9th
-       clock cycle, after every byte but the last.  This flags only makes
-       sense when bit 0x20 is set, indicating a read.
-
-What any other bits might mean, or how to get the slave's ACK/NACK
-response to a write, is unknown.
-*/
-
-struct m920x_state {
-       u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS];
-       int filtering_enabled[M9206_MAX_ADAPTERS];
-       int rep_count;
-};
-
-/* Initialisation data for the m920x
- */
-
-struct m920x_inits {
-       u16 address;
-       u8  data;
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
deleted file mode 100644 (file)
index 6c55384..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
- * DVB-T receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_rc(args...) dprintk(debug,0x01,args)
-#define deb_ee(args...) dprintk(debug,0x02,args)
-
-/* Hauppauge NOVA-T USB2 keys */
-static struct rc_map_table rc_map_haupp_table[] = {
-       { 0x1e00, KEY_0 },
-       { 0x1e01, KEY_1 },
-       { 0x1e02, KEY_2 },
-       { 0x1e03, KEY_3 },
-       { 0x1e04, KEY_4 },
-       { 0x1e05, KEY_5 },
-       { 0x1e06, KEY_6 },
-       { 0x1e07, KEY_7 },
-       { 0x1e08, KEY_8 },
-       { 0x1e09, KEY_9 },
-       { 0x1e0a, KEY_KPASTERISK },
-       { 0x1e0b, KEY_RED },
-       { 0x1e0c, KEY_RADIO },
-       { 0x1e0d, KEY_MENU },
-       { 0x1e0e, KEY_GRAVE }, /* # */
-       { 0x1e0f, KEY_MUTE },
-       { 0x1e10, KEY_VOLUMEUP },
-       { 0x1e11, KEY_VOLUMEDOWN },
-       { 0x1e12, KEY_CHANNEL },
-       { 0x1e14, KEY_UP },
-       { 0x1e15, KEY_DOWN },
-       { 0x1e16, KEY_LEFT },
-       { 0x1e17, KEY_RIGHT },
-       { 0x1e18, KEY_VIDEO },
-       { 0x1e19, KEY_AUDIO },
-       { 0x1e1a, KEY_IMAGES },
-       { 0x1e1b, KEY_EPG },
-       { 0x1e1c, KEY_TV },
-       { 0x1e1e, KEY_NEXT },
-       { 0x1e1f, KEY_BACK },
-       { 0x1e20, KEY_CHANNELUP },
-       { 0x1e21, KEY_CHANNELDOWN },
-       { 0x1e24, KEY_LAST }, /* Skip backwards */
-       { 0x1e25, KEY_OK },
-       { 0x1e29, KEY_BLUE},
-       { 0x1e2e, KEY_GREEN },
-       { 0x1e30, KEY_PAUSE },
-       { 0x1e32, KEY_REWIND },
-       { 0x1e34, KEY_FASTFORWARD },
-       { 0x1e35, KEY_PLAY },
-       { 0x1e36, KEY_STOP },
-       { 0x1e37, KEY_RECORD },
-       { 0x1e38, KEY_YELLOW },
-       { 0x1e3b, KEY_GOTO },
-       { 0x1e3d, KEY_POWER },
-};
-
-/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
- * is delivered. No workaround yet, maybe a new firmware.
- */
-static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
-       u16 raw;
-       int i;
-       struct dibusb_device_state *st = d->priv;
-
-       dvb_usb_generic_rw(d,cmd,2,key,5,0);
-
-       *state = REMOTE_NO_KEY_PRESSED;
-       switch (key[0]) {
-               case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
-                       raw = ((key[1] << 8) | key[2]) >> 3;
-                       toggle = !!(raw & 0x800);
-                       data = raw & 0x3f;
-                       custom = (raw >> 6) & 0x1f;
-
-                       deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
-
-                       for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
-                               if (rc5_data(&rc_map_haupp_table[i]) == data &&
-                                       rc5_custom(&rc_map_haupp_table[i]) == custom) {
-
-                                       deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
-                                                                rc5_custom(&rc_map_haupp_table[i]));
-
-                                       *event = rc_map_haupp_table[i].keycode;
-                                       *state = REMOTE_KEY_PRESSED;
-                                       if (st->old_toggle == toggle) {
-                                               if (st->last_repeat_count++ < 2)
-                                                       *state = REMOTE_NO_KEY_PRESSED;
-                                       } else {
-                                               st->last_repeat_count = 0;
-                                               st->old_toggle = toggle;
-                                       }
-                                       break;
-                               }
-                       }
-
-                       break;
-               case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
-               default:
-                       break;
-       }
-
-       return 0;
-}
-
-static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
-{
-       int i;
-       u8 b;
-
-       mac[0] = 0x00;
-       mac[1] = 0x0d;
-       mac[2] = 0xfe;
-
-       /* this is a complete guess, but works for my box */
-       for (i = 136; i < 139; i++) {
-               dibusb_read_eeprom_byte(d,i, &b);
-
-               mac[5 - (i - 136)] = b;
-       }
-
-       return 0;
-}
-
-/* USB Driver stuff */
-static struct dvb_usb_device_properties nova_t_properties;
-
-static int nova_t_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &nova_t_properties,
-                                  THIS_MODULE, NULL, adapter_nr);
-}
-
-/* do not change the order of the ID table */
-static struct usb_device_id nova_t_table [] = {
-/* 00 */       { USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_COLD) },
-/* 01 */       { USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_WARM) },
-                       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, nova_t_table);
-
-static struct dvb_usb_device_properties nova_t_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-nova-t-usb2-02.fw",
-
-       .num_adapters     = 1,
-       .adapter          = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .pid_filter       = dibusb_pid_filter,
-                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
-                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                                       .stream = {
-                                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-       .size_of_priv     = sizeof(struct dibusb_device_state),
-
-       .power_ctrl       = dibusb2_0_power_ctrl,
-       .read_mac_address = nova_t_read_mac_address,
-
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_haupp_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_haupp_table),
-               .rc_query         = nova_t_rc_query,
-       },
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Hauppauge WinTV-NOVA-T usb2",
-                       { &nova_t_table[0], NULL },
-                       { &nova_t_table[1], NULL },
-               },
-               { NULL },
-       }
-};
-
-static struct usb_driver nova_t_driver = {
-       .name           = "dvb_usb_nova_t_usb2",
-       .probe          = nova_t_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = nova_t_table,
-};
-
-module_usb_driver(nova_t_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
deleted file mode 100644 (file)
index c8a9504..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
-*
-* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
-* Copyright (C) 2006 Marco Gittler (g.marco@freenet.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, version 2.
-*
-* see Documentation/dvb/README.dvb-usb for more information
-*/
-
-#define DVB_USB_LOG_PREFIX "opera"
-
-#include "dvb-usb.h"
-#include "stv0299.h"
-
-#define OPERA_READ_MSG 0
-#define OPERA_WRITE_MSG 1
-#define OPERA_I2C_TUNER 0xd1
-
-#define READ_FX2_REG_REQ  0xba
-#define READ_MAC_ADDR 0x08
-#define OPERA_WRITE_FX2 0xbb
-#define OPERA_TUNER_REQ 0xb1
-#define REG_1F_SYMBOLRATE_BYTE0 0x1f
-#define REG_20_SYMBOLRATE_BYTE1 0x20
-#define REG_21_SYMBOLRATE_BYTE2 0x21
-
-#define ADDR_B600_VOLTAGE_13V (0x02)
-#define ADDR_B601_VOLTAGE_18V (0x03)
-#define ADDR_B1A6_STREAM_CTRL (0x04)
-#define ADDR_B880_READ_REMOTE (0x05)
-
-struct opera1_state {
-       u32 last_key_pressed;
-};
-struct rc_map_opera_table {
-       u32 keycode;
-       u32 event;
-};
-
-static int dvb_usb_opera1_debug;
-module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
-MODULE_PARM_DESC(debug,
-                "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
-                DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-
-static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
-                           u8 * data, u16 len, int flags)
-{
-       int ret;
-       u8 tmp;
-       u8 *buf;
-       unsigned int pipe = (flags == OPERA_READ_MSG) ?
-               usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
-       u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
-
-       buf = kmalloc(len, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
-       if (flags == OPERA_WRITE_MSG)
-               memcpy(buf, data, len);
-       ret = usb_control_msg(dev, pipe, request,
-                       request_type | USB_TYPE_VENDOR, value, 0x0,
-                       buf, len, 2000);
-
-       if (request == OPERA_TUNER_REQ) {
-               tmp = buf[0];
-               if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                           OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
-                           0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
-                       ret = 0;
-                       goto out;
-               }
-               buf[0] = tmp;
-       }
-       if (flags == OPERA_READ_MSG)
-               memcpy(data, buf, len);
-out:
-       kfree(buf);
-       return ret;
-}
-
-/* I2C */
-
-static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
-                                 u8 * buf, u16 len)
-{
-       int ret = 0;
-       u8 request;
-       u16 value;
-
-       if (!dev) {
-               info("no usb_device");
-               return -EINVAL;
-       }
-       if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
-               return -EAGAIN;
-
-       switch (addr>>1){
-               case ADDR_B600_VOLTAGE_13V:
-                       request=0xb6;
-                       value=0x00;
-                       break;
-               case ADDR_B601_VOLTAGE_18V:
-                       request=0xb6;
-                       value=0x01;
-                       break;
-               case ADDR_B1A6_STREAM_CTRL:
-                       request=0xb1;
-                       value=0xa6;
-                       break;
-               case ADDR_B880_READ_REMOTE:
-                       request=0xb8;
-                       value=0x80;
-                       break;
-               default:
-                       request=0xb1;
-                       value=addr;
-       }
-       ret = opera1_xilinx_rw(dev->udev, request,
-               value, buf, len,
-               addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
-
-       mutex_unlock(&dev->usb_mutex);
-       return ret;
-}
-
-static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                          int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i = 0, tmp = 0;
-
-       if (!d)
-               return -ENODEV;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               if ((tmp = opera1_usb_i2c_msgxfer(d,
-                                       (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
-                                       msg[i].buf,
-                                       msg[i].len
-                                       )) != msg[i].len) {
-                       break;
-               }
-               if (dvb_usb_opera1_debug & 0x10)
-                       info("sending i2c mesage %d %d", tmp, msg[i].len);
-       }
-       mutex_unlock(&d->i2c_mutex);
-       return num;
-}
-
-static u32 opera1_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm opera1_i2c_algo = {
-       .master_xfer = opera1_i2c_xfer,
-       .functionality = opera1_i2c_func,
-};
-
-static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       static u8 command_13v[1]={0x00};
-       static u8 command_18v[1]={0x01};
-       struct i2c_msg msg[] = {
-               {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
-       };
-       struct dvb_usb_adapter *udev_adap =
-           (struct dvb_usb_adapter *)(fe->dvb->priv);
-       if (voltage == SEC_VOLTAGE_18) {
-               msg[0].addr = ADDR_B601_VOLTAGE_18V;
-               msg[0].buf = command_18v;
-       }
-       i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
-       return 0;
-}
-
-static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
-                                         u32 ratio)
-{
-       stv0299_writereg(fe, 0x13, 0x98);
-       stv0299_writereg(fe, 0x14, 0x95);
-       stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
-       return 0;
-
-}
-static u8 opera1_inittab[] = {
-       0x00, 0xa1,
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,
-       0x05, 0x05,
-       0x06, 0x02,
-       0x07, 0x00,
-       0x0b, 0x00,
-       0x0c, 0x01,
-       0x0d, 0x81,
-       0x0e, 0x44,
-       0x0f, 0x19,
-       0x10, 0x3f,
-       0x11, 0x84,
-       0x12, 0xda,
-       0x13, 0x98,
-       0x14, 0x95,
-       0x15, 0xc9,
-       0x16, 0xeb,
-       0x17, 0x00,
-       0x18, 0x19,
-       0x19, 0x8b,
-       0x1a, 0x00,
-       0x1b, 0x82,
-       0x1c, 0x7f,
-       0x1d, 0x00,
-       0x1e, 0x00,
-       REG_1F_SYMBOLRATE_BYTE0, 0x06,
-       REG_20_SYMBOLRATE_BYTE1, 0x50,
-       REG_21_SYMBOLRATE_BYTE2, 0x10,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x24, 0x37,
-       0x25, 0xbc,
-       0x26, 0x00,
-       0x27, 0x00,
-       0x28, 0x00,
-       0x29, 0x1e,
-       0x2a, 0x14,
-       0x2b, 0x1f,
-       0x2c, 0x09,
-       0x2d, 0x0a,
-       0x2e, 0x00,
-       0x2f, 0x00,
-       0x30, 0x00,
-       0x31, 0x1f,
-       0x32, 0x19,
-       0x33, 0xfc,
-       0x34, 0x13,
-       0xff, 0xff,
-};
-
-static struct stv0299_config opera1_stv0299_config = {
-       .demod_address = 0xd0>>1,
-       .min_delay_ms = 100,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_0,
-       .volt13_op0_op1 = STV0299_VOLT13_OP0,
-       .inittab = opera1_inittab,
-       .set_symbol_rate = opera1_stv0299_set_symbol_rate,
-};
-
-static int opera1_frontend_attach(struct dvb_usb_adapter *d)
-{
-       d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
-                                     &d->dev->i2c_adap);
-       if ((d->fe_adap[0].fe) != NULL) {
-               d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage;
-               return 0;
-       }
-       info("not attached stv0299");
-       return -EIO;
-}
-
-static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       dvb_attach(
-               dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1,
-               &adap->dev->i2c_adap, DVB_PLL_OPERA1
-       );
-       return 0;
-}
-
-static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 val = onoff ? 0x01 : 0x00;
-
-       if (dvb_usb_opera1_debug)
-               info("power %s", onoff ? "on" : "off");
-       return opera1_xilinx_rw(d->udev, 0xb7, val,
-                               &val, 1, OPERA_WRITE_MSG);
-}
-
-static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       static u8 buf_start[2] = { 0xff, 0x03 };
-       static u8 buf_stop[2] = { 0xff, 0x00 };
-       struct i2c_msg start_tuner[] = {
-               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
-       };
-       if (dvb_usb_opera1_debug)
-               info("streaming %s", onoff ? "on" : "off");
-       i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
-       return 0;
-}
-
-static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-                            int onoff)
-{
-       u8 b_pid[3];
-       struct i2c_msg msg[] = {
-               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
-       };
-       if (dvb_usb_opera1_debug)
-               info("pidfilter index: %d pid: %d %s", index, pid,
-                       onoff ? "on" : "off");
-       b_pid[0] = (2 * index) + 4;
-       b_pid[1] = onoff ? (pid & 0xff) : (0x00);
-       b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
-       i2c_transfer(&adap->dev->i2c_adap, msg, 1);
-       return 0;
-}
-
-static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
-{
-       int u = 0x04;
-       u8 b_pid[3];
-       struct i2c_msg msg[] = {
-               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
-       };
-       if (dvb_usb_opera1_debug)
-               info("%s hw-pidfilter", onoff ? "enable" : "disable");
-       for (; u < 0x7e; u += 2) {
-               b_pid[0] = u;
-               b_pid[1] = 0;
-               b_pid[2] = 0x80;
-               i2c_transfer(&adap->dev->i2c_adap, msg, 1);
-       }
-       return 0;
-}
-
-static struct rc_map_table rc_map_opera1_table[] = {
-       {0x5fa0, KEY_1},
-       {0x51af, KEY_2},
-       {0x5da2, KEY_3},
-       {0x41be, KEY_4},
-       {0x0bf5, KEY_5},
-       {0x43bd, KEY_6},
-       {0x47b8, KEY_7},
-       {0x49b6, KEY_8},
-       {0x05fa, KEY_9},
-       {0x45ba, KEY_0},
-       {0x09f6, KEY_CHANNELUP},        /*chanup */
-       {0x1be5, KEY_CHANNELDOWN},      /*chandown */
-       {0x5da3, KEY_VOLUMEDOWN},       /*voldown */
-       {0x5fa1, KEY_VOLUMEUP},         /*volup */
-       {0x07f8, KEY_SPACE},            /*tab */
-       {0x1fe1, KEY_OK},               /*play ok */
-       {0x1be4, KEY_ZOOM},             /*zoom */
-       {0x59a6, KEY_MUTE},             /*mute */
-       {0x5ba5, KEY_RADIO},            /*tv/f */
-       {0x19e7, KEY_RECORD},           /*rec */
-       {0x01fe, KEY_STOP},             /*Stop */
-       {0x03fd, KEY_PAUSE},            /*pause */
-       {0x03fc, KEY_SCREEN},           /*<- -> */
-       {0x07f9, KEY_CAMERA},           /*capture */
-       {0x47b9, KEY_ESC},              /*exit */
-       {0x43bc, KEY_POWER2},           /*power */
-};
-
-static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
-{
-       struct opera1_state *opst = dev->priv;
-       u8 rcbuffer[32];
-       const u16 startmarker1 = 0x10ed;
-       const u16 startmarker2 = 0x11ec;
-       struct i2c_msg read_remote[] = {
-               {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
-       };
-       int i = 0;
-       u32 send_key = 0;
-
-       if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
-               for (i = 0; i < 32; i++) {
-                       if (rcbuffer[i])
-                               send_key |= 1;
-                       if (i < 31)
-                               send_key = send_key << 1;
-               }
-               if (send_key & 0x8000)
-                       send_key = (send_key << 1) | (send_key >> 15 & 0x01);
-
-               if (send_key == 0xffff && opst->last_key_pressed != 0) {
-                       *state = REMOTE_KEY_REPEAT;
-                       *event = opst->last_key_pressed;
-                       return 0;
-               }
-               for (; send_key != 0;) {
-                       if (send_key >> 16 == startmarker2) {
-                               break;
-                       } else if (send_key >> 16 == startmarker1) {
-                               send_key =
-                                       (send_key & 0xfffeffff) | (startmarker1 << 16);
-                               break;
-                       } else
-                               send_key >>= 1;
-               }
-
-               if (send_key == 0)
-                       return 0;
-
-               send_key = (send_key & 0xffff) | 0x0100;
-
-               for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
-                       if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
-                               *state = REMOTE_KEY_PRESSED;
-                               *event = rc_map_opera1_table[i].keycode;
-                               opst->last_key_pressed =
-                                       rc_map_opera1_table[i].keycode;
-                               break;
-                       }
-                       opst->last_key_pressed = 0;
-               }
-       } else
-               *state = REMOTE_NO_KEY_PRESSED;
-       return 0;
-}
-
-static struct usb_device_id opera1_table[] = {
-       {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
-       {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
-       {}
-};
-
-MODULE_DEVICE_TABLE(usb, opera1_table);
-
-static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-{
-       u8 command[] = { READ_MAC_ADDR };
-       opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
-       opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
-       return 0;
-}
-static int opera1_xilinx_load_firmware(struct usb_device *dev,
-                                      const char *filename)
-{
-       const struct firmware *fw = NULL;
-       u8 *b, *p;
-       int ret = 0, i,fpgasize=40;
-       u8 testval;
-       info("start downloading fpga firmware %s",filename);
-
-       if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
-               err("did not find the firmware file. (%s) "
-                       "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
-                       filename);
-               return ret;
-       } else {
-               p = kmalloc(fw->size, GFP_KERNEL);
-               opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
-               if (p != NULL && testval != 0x67) {
-
-                       u8 reset = 0, fpga_command = 0;
-                       memcpy(p, fw->data, fw->size);
-                       /* clear fpga ? */
-                       opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
-                                        OPERA_WRITE_MSG);
-                       for (i = 0; i < fw->size;) {
-                               if ( (fw->size - i) <fpgasize){
-                                   fpgasize=fw->size-i;
-                               }
-                               b = (u8 *) p + i;
-                               if (opera1_xilinx_rw
-                                       (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
-                                               OPERA_WRITE_MSG) != fpgasize
-                                       ) {
-                                       err("error while transferring firmware");
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                               i = i + fpgasize;
-                       }
-                       /* restart the CPU */
-                       if (ret || opera1_xilinx_rw
-                                       (dev, 0xa0, 0xe600, &reset, 1,
-                                       OPERA_WRITE_MSG) != 1) {
-                               err("could not restart the USB controller CPU.");
-                               ret = -EINVAL;
-                       }
-               }
-       }
-       kfree(p);
-       release_firmware(fw);
-       return ret;
-}
-
-static struct dvb_usb_device_properties opera1_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-opera-01.fw",
-       .size_of_priv = sizeof(struct opera1_state),
-
-       .power_ctrl = opera1_power_ctrl,
-       .i2c_algo = &opera1_i2c_algo,
-
-       .rc.legacy = {
-               .rc_map_table = rc_map_opera1_table,
-               .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
-               .rc_interval = 200,
-               .rc_query = opera1_rc_query,
-       },
-       .read_mac_address = opera1_read_mac_address,
-       .generic_bulk_ctrl_endpoint = 0x00,
-       /* parameter for the MPEG2-data transfer */
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = opera1_frontend_attach,
-                       .streaming_ctrl = opera1_streaming_ctrl,
-                       .tuner_attach = opera1_tuner_attach,
-                       .caps =
-                               DVB_USB_ADAP_HAS_PID_FILTER |
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter = opera1_pid_filter,
-                       .pid_filter_ctrl = opera1_pid_filter_control,
-                       .pid_filter_count = 252,
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 10,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .num_device_descs = 1,
-       .devices = {
-               {"Opera1 DVB-S USB2.0",
-                       {&opera1_table[0], NULL},
-                       {&opera1_table[1], NULL},
-               },
-       }
-};
-
-static int opera1_probe(struct usb_interface *intf,
-                       const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-
-       if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
-               udev->descriptor.idVendor == USB_VID_OPERA1 &&
-               opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
-           ) {
-               return -EINVAL;
-       }
-
-       if (0 != dvb_usb_device_init(intf, &opera1_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return -EINVAL;
-       return 0;
-}
-
-static struct usb_driver opera1_driver = {
-       .name = "opera1",
-       .probe = opera1_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table = opera1_table,
-};
-
-module_usb_driver(opera1_driver);
-
-MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
-MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
-MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/pctv452e.c b/drivers/media/dvb/dvb-usb/pctv452e.c
deleted file mode 100644 (file)
index 02e8785..0000000
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- * PCTV 452e DVB driver
- *
- * Copyright (c) 2006-2008 Dominik Kuhlen <dkuhlen@gmx.net>
- *
- * TT connect S2-3650-CI Common Interface support, MAC readout
- * Copyright (C) 2008 Michael H. Schimek <mschimek@gmx.at>
- *
- * 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.
- */
-
-/* dvb usb framework */
-#define DVB_USB_LOG_PREFIX "pctv452e"
-#include "dvb-usb.h"
-
-/* Demodulator */
-#include "stb0899_drv.h"
-#include "stb0899_reg.h"
-#include "stb0899_cfg.h"
-/* Tuner */
-#include "stb6100.h"
-#include "stb6100_cfg.h"
-/* FE Power */
-#include "lnbp22.h"
-
-#include "dvb_ca_en50221.h"
-#include "ttpci-eeprom.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 ISOC_INTERFACE_ALTERNATIVE 3
-
-#define SYNC_BYTE_OUT 0xaa
-#define SYNC_BYTE_IN  0x55
-
-/* guessed: (copied from ttusb-budget) */
-#define PCTV_CMD_RESET 0x15
-/* command to poll IR receiver */
-#define PCTV_CMD_IR    0x1b
-/* command to send I2C  */
-#define PCTV_CMD_I2C   0x31
-
-#define I2C_ADDR_STB0899 (0xd0 >> 1)
-#define I2C_ADDR_STB6100 (0xc0 >> 1)
-#define I2C_ADDR_LNBP22  (0x10 >> 1)
-#define I2C_ADDR_24C16   (0xa0 >> 1)
-#define I2C_ADDR_24C64   (0xa2 >> 1)
-
-
-/* pctv452e sends us this amount of data for each issued usb-command */
-#define PCTV_ANSWER_LEN 64
-/* Wait up to 1000ms for device  */
-#define PCTV_TIMEOUT 1000
-
-
-#define PCTV_LED_GPIO   STB0899_GPIO01
-#define PCTV_LED_GREEN  0x82
-#define PCTV_LED_ORANGE 0x02
-
-#define ci_dbg(format, arg...)                         \
-do {                                                   \
-       if (0)                                          \
-               printk(KERN_DEBUG DVB_USB_LOG_PREFIX    \
-                       ": " format "\n" , ## arg);     \
-} while (0)
-
-enum {
-       TT3650_CMD_CI_TEST = 0x40,
-       TT3650_CMD_CI_RD_CTRL,
-       TT3650_CMD_CI_WR_CTRL,
-       TT3650_CMD_CI_RD_ATTR,
-       TT3650_CMD_CI_WR_ATTR,
-       TT3650_CMD_CI_RESET,
-       TT3650_CMD_CI_SET_VIDEO_PORT
-};
-
-
-static struct stb0899_postproc pctv45e_postproc[] = {
-       { PCTV_LED_GPIO, STB0899_GPIOPULLUP },
-       { 0, 0 }
-};
-
-/*
- * stores all private variables for communication with the PCTV452e DVB-S2
- */
-struct pctv452e_state {
-       struct dvb_ca_en50221 ca;
-       struct mutex ca_mutex;
-
-       u8 c;      /* transaction counter, wraps around...  */
-       u8 initialized; /* set to 1 if 0x15 has been sent */
-       u16 last_rc_key;
-};
-
-static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
-                        unsigned int write_len, unsigned int read_len)
-{
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       u8 buf[64];
-       u8 id;
-       unsigned int rlen;
-       int ret;
-
-       BUG_ON(NULL == data && 0 != (write_len | read_len));
-       BUG_ON(write_len > 64 - 4);
-       BUG_ON(read_len > 64 - 4);
-
-       id = state->c++;
-
-       buf[0] = SYNC_BYTE_OUT;
-       buf[1] = id;
-       buf[2] = cmd;
-       buf[3] = write_len;
-
-       memcpy(buf + 4, data, write_len);
-
-       rlen = (read_len > 0) ? 64 : 0;
-       ret = dvb_usb_generic_rw(d, buf, 4 + write_len,
-                                 buf, rlen, /* delay_ms */ 0);
-       if (0 != ret)
-               goto failed;
-
-       ret = -EIO;
-       if (SYNC_BYTE_IN != buf[0] || id != buf[1])
-               goto failed;
-
-       memcpy(data, buf + 4, read_len);
-
-       return 0;
-
-failed:
-       err("CI error %d; %02X %02X %02X -> %*ph.",
-            ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
-
-       return ret;
-}
-
-static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca,
-                               u8 cmd, u8 *data, unsigned int write_len,
-                               unsigned int read_len)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       int ret;
-
-       mutex_lock(&state->ca_mutex);
-       ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
-       mutex_unlock(&state->ca_mutex);
-
-       return ret;
-}
-
-static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
-                                int slot, int address)
-{
-       u8 buf[3];
-       int ret;
-
-       if (0 != slot)
-               return -EINVAL;
-
-       buf[0] = (address >> 8) & 0x0F;
-       buf[1] = address;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
-
-       ci_dbg("%s %04x -> %d 0x%02x",
-               __func__, address, ret, buf[2]);
-
-       if (ret < 0)
-               return ret;
-
-       return buf[2];
-}
-
-static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
-                                int slot, int address, u8 value)
-{
-       u8 buf[3];
-
-       ci_dbg("%s %d 0x%04x 0x%02x",
-               __func__, slot, address, value);
-
-       if (0 != slot)
-               return -EINVAL;
-
-       buf[0] = (address >> 8) & 0x0F;
-       buf[1] = address;
-       buf[2] = value;
-
-       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
-}
-
-static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca,
-                                int                    slot,
-                                u8                     address)
-{
-       u8 buf[2];
-       int ret;
-
-       if (0 != slot)
-               return -EINVAL;
-
-       buf[0] = address & 3;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
-
-       ci_dbg("%s 0x%02x -> %d 0x%02x",
-               __func__, address, ret, buf[1]);
-
-       if (ret < 0)
-               return ret;
-
-       return buf[1];
-}
-
-static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca,
-                                int                    slot,
-                                u8                     address,
-                                u8                     value)
-{
-       u8 buf[2];
-
-       ci_dbg("%s %d 0x%02x 0x%02x",
-               __func__, slot, address, value);
-
-       if (0 != slot)
-               return -EINVAL;
-
-       buf[0] = address;
-       buf[1] = value;
-
-       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
-}
-
-static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca,
-                                int                    slot,
-                                int                    enable)
-{
-       u8 buf[1];
-       int ret;
-
-       ci_dbg("%s %d %d", __func__, slot, enable);
-
-       if (0 != slot)
-               return -EINVAL;
-
-       enable = !!enable;
-       buf[0] = enable;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
-       if (ret < 0)
-               return ret;
-
-       if (enable != buf[0]) {
-               err("CI not %sabled.", enable ? "en" : "dis");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       return tt3650_ci_set_video_port(ca, slot, /* enable */ 0);
-}
-
-static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       return tt3650_ci_set_video_port(ca, slot, /* enable */ 1);
-}
-
-static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       u8 buf[1];
-       int ret;
-
-       ci_dbg("%s %d", __func__, slot);
-
-       if (0 != slot)
-               return -EINVAL;
-
-       buf[0] = 0;
-
-       mutex_lock(&state->ca_mutex);
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
-       if (0 != ret)
-               goto failed;
-
-       msleep(500);
-
-       buf[0] = 1;
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
-       if (0 != ret)
-               goto failed;
-
-       msleep(500);
-
-       buf[0] = 0; /* FTA */
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
-
- failed:
-       mutex_unlock(&state->ca_mutex);
-
-       return ret;
-}
-
-static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca,
-                                int                    slot,
-                                int                    open)
-{
-       u8 buf[1];
-       int ret;
-
-       if (0 != slot)
-               return -EINVAL;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
-       if (0 != ret)
-               return ret;
-
-       if (1 == buf[0])
-               return DVB_CA_EN50221_POLL_CAM_PRESENT |
-                       DVB_CA_EN50221_POLL_CAM_READY;
-
-       return 0;
-
-}
-
-static void tt3650_ci_uninit(struct dvb_usb_device *d)
-{
-       struct pctv452e_state *state;
-
-       ci_dbg("%s", __func__);
-
-       if (NULL == d)
-               return;
-
-       state = (struct pctv452e_state *)d->priv;
-       if (NULL == state)
-               return;
-
-       if (NULL == state->ca.data)
-               return;
-
-       /* Error ignored. */
-       tt3650_ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0);
-
-       dvb_ca_en50221_release(&state->ca);
-
-       memset(&state->ca, 0, sizeof(state->ca));
-}
-
-static int tt3650_ci_init(struct dvb_usb_adapter *a)
-{
-       struct dvb_usb_device *d = a->dev;
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       int ret;
-
-       ci_dbg("%s", __func__);
-
-       mutex_init(&state->ca_mutex);
-
-       state->ca.owner = THIS_MODULE;
-       state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
-       state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
-       state->ca.read_cam_control = tt3650_ci_read_cam_control;
-       state->ca.write_cam_control = tt3650_ci_write_cam_control;
-       state->ca.slot_reset = tt3650_ci_slot_reset;
-       state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
-       state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
-       state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
-       state->ca.data = d;
-
-       ret = dvb_ca_en50221_init(&a->dvb_adap,
-                                  &state->ca,
-                                  /* flags */ 0,
-                                  /* n_slots */ 1);
-       if (0 != ret) {
-               err("Cannot initialize CI: Error %d.", ret);
-               memset(&state->ca, 0, sizeof(state->ca));
-               return ret;
-       }
-
-       info("CI initialized.");
-
-       return 0;
-}
-
-#define CMD_BUFFER_SIZE 0x28
-static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                               const u8 *snd_buf, u8 snd_len,
-                               u8 *rcv_buf, u8 rcv_len)
-{
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       u8 buf[64];
-       u8 id;
-       int ret;
-
-       id = state->c++;
-
-       ret = -EINVAL;
-       if (snd_len > 64 - 7 || rcv_len > 64 - 7)
-               goto failed;
-
-       buf[0] = SYNC_BYTE_OUT;
-       buf[1] = id;
-       buf[2] = PCTV_CMD_I2C;
-       buf[3] = snd_len + 3;
-       buf[4] = addr << 1;
-       buf[5] = snd_len;
-       buf[6] = rcv_len;
-
-       memcpy(buf + 7, snd_buf, snd_len);
-
-       ret = dvb_usb_generic_rw(d, buf, 7 + snd_len,
-                                 buf, /* rcv_len */ 64,
-                                 /* delay_ms */ 0);
-       if (ret < 0)
-               goto failed;
-
-       /* TT USB protocol error. */
-       ret = -EIO;
-       if (SYNC_BYTE_IN != buf[0] || id != buf[1])
-               goto failed;
-
-       /* I2C device didn't respond as expected. */
-       ret = -EREMOTEIO;
-       if (buf[5] < snd_len || buf[6] < rcv_len)
-               goto failed;
-
-       memcpy(rcv_buf, buf + 7, rcv_len);
-
-       return rcv_len;
-
-failed:
-       err("I2C error %d; %02X %02X  %02X %02X %02X -> "
-            "%02X %02X  %02X %02X %02X.",
-            ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len,
-            buf[0], buf[1], buf[4], buf[5], buf[6]);
-
-       return ret;
-}
-
-static int pctv452e_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg,
-                               int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adapter);
-       int i;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
-               int ret;
-
-               if (msg[i].flags & I2C_M_RD) {
-                       addr = msg[i].addr;
-                       snd_buf = NULL;
-                       snd_len = 0;
-                       rcv_buf = msg[i].buf;
-                       rcv_len = msg[i].len;
-               } else {
-                       addr = msg[i].addr;
-                       snd_buf = msg[i].buf;
-                       snd_len = msg[i].len;
-                       rcv_buf = NULL;
-                       rcv_len = 0;
-               }
-
-               ret = pctv452e_i2c_msg(d, addr, snd_buf, snd_len, rcv_buf,
-                                       rcv_len);
-               if (ret < rcv_len)
-                       break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 pctv452e_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
-{
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 };
-       u8 rx[PCTV_ANSWER_LEN];
-       int ret;
-
-       info("%s: %d\n", __func__, i);
-
-       if (!i)
-               return 0;
-
-       if (state->initialized)
-               return 0;
-
-       /* hmm where shoud this should go? */
-       ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
-       if (ret != 0)
-               info("%s: Warning set interface returned: %d\n",
-                       __func__, ret);
-
-       /* this is a one-time initialization, dont know where to put */
-       b0[1] = state->c++;
-       /* reset board */
-       ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
-       if (ret)
-               return ret;
-
-       b0[1] = state->c++;
-       b0[4] = 1;
-       /* reset board (again?) */
-       ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
-       if (ret)
-               return ret;
-
-       state->initialized = 1;
-
-       return 0;
-}
-
-static int pctv452e_rc_query(struct dvb_usb_device *d)
-{
-       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-       u8 b[CMD_BUFFER_SIZE];
-       u8 rx[PCTV_ANSWER_LEN];
-       int ret, i;
-       u8 id = state->c++;
-
-       /* prepare command header  */
-       b[0] = SYNC_BYTE_OUT;
-       b[1] = id;
-       b[2] = PCTV_CMD_IR;
-       b[3] = 0;
-
-       /* send ir request */
-       ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
-       if (ret != 0)
-               return ret;
-
-       if (debug > 3) {
-               info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
-               for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
-                       info(" %02x", rx[i+3]);
-
-               info("\n");
-       }
-
-       if ((rx[3] == 9) &&  (rx[12] & 0x01)) {
-               /* got a "press" event */
-               state->last_rc_key = (rx[7] << 8) | rx[6];
-               if (debug > 2)
-                       info("%s: cmd=0x%02x sys=0x%02x\n",
-                               __func__, rx[6], rx[7]);
-
-               rc_keydown(d->rc_dev, state->last_rc_key, 0);
-       } else if (state->last_rc_key) {
-               rc_keyup(d->rc_dev);
-               state->last_rc_key = 0;
-       }
-
-       return 0;
-}
-
-static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-{
-       const u8 mem_addr[] = { 0x1f, 0xcc };
-       u8 encoded_mac[20];
-       int ret;
-
-       ret = -EAGAIN;
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               goto failed;
-
-       ret = pctv452e_i2c_msg(d, I2C_ADDR_24C16,
-                               mem_addr + 1, /* snd_len */ 1,
-                               encoded_mac, /* rcv_len */ 20);
-       if (-EREMOTEIO == ret)
-               /* Caution! A 24C16 interprets 0xA2 0x1F 0xCC as a
-                  byte write if /WC is low. */
-               ret = pctv452e_i2c_msg(d, I2C_ADDR_24C64,
-                                       mem_addr, 2,
-                                       encoded_mac, 20);
-
-       mutex_unlock(&d->i2c_mutex);
-
-       if (20 != ret)
-               goto failed;
-
-       ret = ttpci_eeprom_decode_mac(mac, encoded_mac);
-       if (0 != ret)
-               goto failed;
-
-       return 0;
-
-failed:
-       memset(mac, 0, 6);
-
-       return ret;
-}
-
-static const struct stb0899_s1_reg pctv452e_init_dev[] = {
-       { STB0899_DISCNTRL1,    0x26 },
-       { STB0899_DISCNTRL2,    0x80 },
-       { STB0899_DISRX_ST0,    0x04 },
-       { STB0899_DISRX_ST1,    0x20 },
-       { STB0899_DISPARITY,    0x00 },
-       { STB0899_DISFIFO,      0x00 },
-       { STB0899_DISF22,       0x99 },
-       { STB0899_DISF22RX,     0x85 }, /* 0xa8 */
-       { STB0899_ACRPRESC,     0x11 },
-       { STB0899_ACRDIV1,      0x0a },
-       { STB0899_ACRDIV2,      0x05 },
-       { STB0899_DACR1 ,       0x00 },
-       { STB0899_DACR2 ,       0x00 },
-       { STB0899_OUTCFG,       0x00 },
-       { STB0899_MODECFG,      0x00 }, /* Inversion */
-       { STB0899_IRQMSK_3,     0xf3 },
-       { STB0899_IRQMSK_2,     0xfc },
-       { STB0899_IRQMSK_1,     0xff },
-       { STB0899_IRQMSK_0,     0xff },
-       { STB0899_I2CCFG,       0x88 },
-       { STB0899_I2CRPT,       0x58 },
-       { STB0899_GPIO00CFG,    0x82 },
-       { STB0899_GPIO01CFG,    0x82 }, /* LED: 0x02 green, 0x82 orange */
-       { 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 DVB-S; 0x1c DVB-S2 (1c, rjkm) */
-       { STB0899_GPIO22,       0x82 },
-       { STB0899_GPIO21,       0x91 },
-       { STB0899_DIRCLKCFG,    0x82 },
-       { STB0899_CLKOUT27CFG,  0x7e },
-       { STB0899_STDBYCFG,     0x82 },
-       { STB0899_CS0CFG,       0x82 },
-       { STB0899_CS1CFG,       0x82 },
-       { STB0899_DISEQCOCFG,   0x20 },
-       { STB0899_NCOARSE,      0x15 }, /* 0x15 27Mhz, F/3 198MHz, F/6 108MHz */
-       { STB0899_SYNTCTRL,     0x00 }, /* 0x00 CLKI, 0x02 XTALI */
-       { STB0899_FILTCTRL,     0x00 },
-       { STB0899_SYSCTRL,      0x00 },
-       { STB0899_STOPCLK1,     0x20 }, /* orig: 0x00 budget-ci: 0x20 */
-       { STB0899_STOPCLK2,     0x00 },
-       { STB0899_INTBUFCTRL,   0x0a },
-       { STB0899_AGC2I1,       0x00 },
-       { STB0899_AGC2I2,       0x00 },
-       { STB0899_AGCIQIN,      0x00 },
-       { STB0899_TSTRES,       0x40 }, /* rjkm */
-       { 0xffff,               0xff },
-};
-
-static const struct stb0899_s1_reg pctv452e_init_s1_demod[] = {
-       { 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 },
-};
-
-static struct stb0899_config stb0899_config = {
-       .init_dev       = pctv452e_init_dev,
-       .init_s2_demod  = stb0899_s2_init_2,
-       .init_s1_demod  = pctv452e_init_s1_demod,
-       .init_s2_fec    = stb0899_s2_init_4,
-       .init_tst       = stb0899_s1_init_5,
-
-       .demod_address   = I2C_ADDR_STB0899, /* I2C Address */
-       .block_sync_mode = STB0899_SYNC_FORCED, /* ? */
-
-       .xtal_freq       = 27000000,     /* Assume Hz ? */
-       .inversion       = IQ_SWAP_ON,       /* ? */
-
-       .lo_clk   = 76500000,
-       .hi_clk   = 99000000,
-
-       .ts_output_mode  = 0,   /* Use parallel mode */
-       .clock_polarity  = 0,
-       .data_clk_parity = 0,
-       .fec_mode       = 0,
-
-       .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,
-
-       /* helper for switching LED green/orange */
-       .postproc = pctv45e_postproc
-};
-
-static struct stb6100_config stb6100_config = {
-       .tuner_address = I2C_ADDR_STB6100,
-       .refclock      = 27000000
-};
-
-
-static struct i2c_algorithm pctv452e_i2c_algo = {
-       .master_xfer   = pctv452e_i2c_xfer,
-       .functionality = pctv452e_i2c_func
-};
-
-static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
-{
-       struct usb_device_id *id;
-
-       a->fe_adap[0].fe = dvb_attach(stb0899_attach, &stb0899_config,
-                                               &a->dev->i2c_adap);
-       if (!a->fe_adap[0].fe)
-               return -ENODEV;
-       if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
-                                       &a->dev->i2c_adap)) == 0)
-               err("Cannot attach lnbp22\n");
-
-       id = a->dev->desc->warm_ids[0];
-       if (USB_VID_TECHNOTREND == id->idVendor
-           && USB_PID_TECHNOTREND_CONNECT_S2_3650_CI == id->idProduct)
-               /* Error ignored. */
-               tt3650_ci_init(a);
-
-       return 0;
-}
-
-static int pctv452e_tuner_attach(struct dvb_usb_adapter *a)
-{
-       if (!a->fe_adap[0].fe)
-               return -ENODEV;
-       if (dvb_attach(stb6100_attach, a->fe_adap[0].fe, &stb6100_config,
-                                       &a->dev->i2c_adap) == 0) {
-               err("%s failed\n", __func__);
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static struct usb_device_id pctv452e_usb_table[] = {
-       {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_452E)},
-       {USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2_3600)},
-       {USB_DEVICE(USB_VID_TECHNOTREND,
-                               USB_PID_TECHNOTREND_CONNECT_S2_3650_CI)},
-       {}
-};
-MODULE_DEVICE_TABLE(usb, pctv452e_usb_table);
-
-static struct dvb_usb_device_properties pctv452e_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
-       .usb_ctrl = DEVICE_SPECIFIC,
-
-       .size_of_priv     = sizeof(struct pctv452e_state),
-
-       .power_ctrl       = pctv452e_power_ctrl,
-
-       .rc.core = {
-               .rc_codes       = RC_MAP_DIB0700_RC5_TABLE,
-               .allowed_protos = RC_TYPE_UNKNOWN,
-               .rc_query       = pctv452e_rc_query,
-               .rc_interval    = 100,
-       },
-
-       .num_adapters     = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach  = pctv452e_frontend_attach,
-                       .tuner_attach     = pctv452e_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type     = USB_ISOC,
-                               .count    = 4,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize    = 940,
-                                               .interval     = 1
-                                       }
-                               }
-                       },
-               } },
-       } },
-
-       .i2c_algo = &pctv452e_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 1, /* allow generice rw function */
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "PCTV HDTV USB",
-                 .cold_ids = { NULL, NULL }, /* this is a warm only device */
-                 .warm_ids = { &pctv452e_usb_table[0], NULL }
-               },
-               { 0 },
-       }
-};
-
-static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
-       .usb_ctrl = DEVICE_SPECIFIC,
-
-       .size_of_priv           = sizeof(struct pctv452e_state),
-
-       .power_ctrl             = pctv452e_power_ctrl,
-       .read_mac_address       = pctv452e_read_mac_address,
-
-       .rc.core = {
-               .rc_codes       = RC_MAP_TT_1500,
-               .allowed_protos = RC_TYPE_UNKNOWN,
-               .rc_query       = pctv452e_rc_query,
-               .rc_interval    = 100,
-       },
-
-       .num_adapters           = 1,
-       .adapter = {{
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach = pctv452e_frontend_attach,
-                       .tuner_attach = pctv452e_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize = 940,
-                                               .interval = 1
-                                       }
-                               }
-                       },
-
-               } },
-       } },
-
-       .i2c_algo = &pctv452e_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 1, /* allow generic rw function*/
-
-       .num_device_descs = 2,
-       .devices = {
-               { .name = "Technotrend TT Connect S2-3600",
-                 .cold_ids = { NULL, NULL }, /* this is a warm only device */
-                 .warm_ids = { &pctv452e_usb_table[1], NULL }
-               },
-               { .name = "Technotrend TT Connect S2-3650-CI",
-                 .cold_ids = { NULL, NULL },
-                 .warm_ids = { &pctv452e_usb_table[2], NULL }
-               },
-               { 0 },
-       }
-};
-
-static void pctv452e_usb_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-
-       tt3650_ci_uninit(d);
-       dvb_usb_device_exit(intf);
-}
-
-static int pctv452e_usb_probe(struct usb_interface *intf,
-                               const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &pctv452e_properties,
-                                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &tt_connect_s2_3600_properties,
-                                       THIS_MODULE, NULL, adapter_nr))
-               return 0;
-
-       return -ENODEV;
-}
-
-static struct usb_driver pctv452e_usb_driver = {
-       .name       = "pctv452e",
-       .probe      = pctv452e_usb_probe,
-       .disconnect = pctv452e_usb_disconnect,
-       .id_table   = pctv452e_usb_table,
-};
-
-module_usb_driver(pctv452e_usb_driver);
-
-MODULE_AUTHOR("Dominik Kuhlen <dkuhlen@gmx.net>");
-MODULE_AUTHOR("Andre Weidemann <Andre.Weidemann@web.de>");
-MODULE_AUTHOR("Michael H. Schimek <mschimek@gmx.at>");
-MODULE_DESCRIPTION("Pinnacle PCTV HDTV USB DVB / TT connect S2-3600 Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c
deleted file mode 100644 (file)
index acefaa8..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Linux driver for Technisat DVB-S/S2 USB 2.0 device
- *
- * Copyright (C) 2010 Patrick Boettcher,
- *                    Kernel Labs Inc. PO Box 745, St James, NY 11780
- *
- * Development was sponsored by Technisat Digital UK Limited, whose
- * registered office is Witan Gate House 500 - 600 Witan Gate West,
- * Milton Keynes, MK9 1SH
- *
- * 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.
- *
- *
- * 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.
- *
- * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
- * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
- * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE.  NEITHER THE COPYRIGHT HOLDER
- * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
- * GNU General Public License for more details.
- */
-
-#define DVB_USB_LOG_PREFIX "technisat-usb2"
-#include "dvb-usb.h"
-
-#include "stv6110x.h"
-#include "stv090x.h"
-
-/* module parameters */
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,
-               "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
-               DVB_USB_DEBUG_STATUS);
-
-/* disables all LED control command and
- * also does not start the signal polling thread */
-static int disable_led_control;
-module_param(disable_led_control, int, 0444);
-MODULE_PARM_DESC(disable_led_control,
-               "disable LED control of the device "
-               "(default: 0 - LED control is active).");
-
-/* device private data */
-struct technisat_usb2_state {
-       struct dvb_usb_device *dev;
-       struct delayed_work green_led_work;
-       u8 power_state;
-
-       u16 last_scan_code;
-};
-
-/* debug print helpers */
-#define deb_info(args...)    dprintk(debug, 0x01, args)
-#define deb_eeprom(args...)  dprintk(debug, 0x02, args)
-#define deb_i2c(args...)     dprintk(debug, 0x04, args)
-#define deb_rc(args...)      dprintk(debug, 0x08, args)
-
-/* vendor requests */
-#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
-#define SET_FRONT_END_RESET_VENDOR_REQUEST         0xB4
-#define GET_VERSION_INFO_VENDOR_REQUEST            0xB5
-#define SET_GREEN_LED_VENDOR_REQUEST               0xB6
-#define SET_RED_LED_VENDOR_REQUEST                 0xB7
-#define GET_IR_DATA_VENDOR_REQUEST                 0xB8
-#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST       0xB9
-#define SET_USB_REENUMERATION                      0xBA
-
-/* i2c-access methods */
-#define I2C_SPEED_100KHZ_BIT 0x40
-
-#define I2C_STATUS_NAK 7
-#define I2C_STATUS_OK 8
-
-static int technisat_usb2_i2c_access(struct usb_device *udev,
-               u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
-{
-       u8 b[64];
-       int ret, actual_length;
-
-       deb_i2c("i2c-access: %02x, tx: ", device_addr);
-       debug_dump(tx, txlen, deb_i2c);
-       deb_i2c(" ");
-
-       if (txlen > 62) {
-               err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
-                               device_addr);
-               txlen = 62;
-       }
-       if (rxlen > 62) {
-               err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
-                               device_addr);
-               txlen = 62;
-       }
-
-       b[0] = I2C_SPEED_100KHZ_BIT;
-       b[1] = device_addr << 1;
-
-       if (rx != NULL) {
-               b[0] |= rxlen;
-               b[1] |= 1;
-       }
-
-       memcpy(&b[2], tx, txlen);
-       ret = usb_bulk_msg(udev,
-                       usb_sndbulkpipe(udev, 0x01),
-                       b, 2 + txlen,
-                       NULL, 1000);
-
-       if (ret < 0) {
-               err("i2c-error: out failed %02x = %d", device_addr, ret);
-               return -ENODEV;
-       }
-
-       ret = usb_bulk_msg(udev,
-                       usb_rcvbulkpipe(udev, 0x01),
-                       b, 64, &actual_length, 1000);
-       if (ret < 0) {
-               err("i2c-error: in failed %02x = %d", device_addr, ret);
-               return -ENODEV;
-       }
-
-       if (b[0] != I2C_STATUS_OK) {
-               err("i2c-error: %02x = %d", device_addr, b[0]);
-               /* handle tuner-i2c-nak */
-               if (!(b[0] == I2C_STATUS_NAK &&
-                               device_addr == 0x60
-                               /* && device_is_technisat_usb2 */))
-                       return -ENODEV;
-       }
-
-       deb_i2c("status: %d, ", b[0]);
-
-       if (rx != NULL) {
-               memcpy(rx, &b[2], rxlen);
-
-               deb_i2c("rx (%d): ", rxlen);
-               debug_dump(rx, rxlen, deb_i2c);
-       }
-
-       deb_i2c("\n");
-
-       return 0;
-}
-
-static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
-                               int num)
-{
-       int ret = 0, i;
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
-       /* Ensure nobody else hits the i2c bus while we're sending our
-          sequence of messages, (such as the remote control thread) */
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
-                       ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
-                                               msg[i].buf, msg[i].len,
-                                               msg[i+1].buf, msg[i+1].len);
-                       if (ret != 0)
-                               break;
-                       i++;
-               } else {
-                       ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
-                                               msg[i].buf, msg[i].len,
-                                               NULL, 0);
-                       if (ret != 0)
-                               break;
-               }
-       }
-
-       if (ret == 0)
-               ret = i;
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm technisat_usb2_i2c_algo = {
-       .master_xfer   = technisat_usb2_i2c_xfer,
-       .functionality = technisat_usb2_i2c_func,
-};
-
-#if 0
-static void technisat_usb2_frontend_reset(struct usb_device *udev)
-{
-       usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                       SET_FRONT_END_RESET_VENDOR_REQUEST,
-                       USB_TYPE_VENDOR | USB_DIR_OUT,
-                       10, 0,
-                       NULL, 0, 500);
-}
-#endif
-
-/* LED control */
-enum technisat_usb2_led_state {
-       LED_OFF,
-       LED_BLINK,
-       LED_ON,
-       LED_UNDEFINED
-};
-
-static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
-{
-       int ret;
-
-       u8 led[8] = {
-               red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
-               0
-       };
-
-       if (disable_led_control && state != LED_OFF)
-               return 0;
-
-       switch (state) {
-       case LED_ON:
-               led[1] = 0x82;
-               break;
-       case LED_BLINK:
-               led[1] = 0x82;
-               if (red) {
-                       led[2] = 0x02;
-                       led[3] = 10;
-                       led[4] = 10;
-               } else {
-                       led[2] = 0xff;
-                       led[3] = 50;
-                       led[4] = 50;
-               }
-               led[5] = 1;
-               break;
-
-       default:
-       case LED_OFF:
-               led[1] = 0x80;
-               break;
-       }
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-               red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
-               USB_TYPE_VENDOR | USB_DIR_OUT,
-               0, 0,
-               led, sizeof(led), 500);
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret;
-}
-
-static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
-{
-       int ret;
-       u8 b = 0;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-               SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
-               USB_TYPE_VENDOR | USB_DIR_OUT,
-               (red << 8) | green, 0,
-               &b, 1, 500);
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static void technisat_usb2_green_led_control(struct work_struct *work)
-{
-       struct technisat_usb2_state *state =
-               container_of(work, struct technisat_usb2_state, green_led_work.work);
-       struct dvb_frontend *fe = state->dev->adapter[0].fe_adap[0].fe;
-
-       if (state->power_state == 0)
-               goto schedule;
-
-       if (fe != NULL) {
-               enum fe_status status;
-
-               if (fe->ops.read_status(fe, &status) != 0)
-                       goto schedule;
-
-               if (status & FE_HAS_LOCK) {
-                       u32 ber;
-
-                       if (fe->ops.read_ber(fe, &ber) != 0)
-                               goto schedule;
-
-                       if (ber > 1000)
-                               technisat_usb2_set_led(state->dev, 0, LED_BLINK);
-                       else
-                               technisat_usb2_set_led(state->dev, 0, LED_ON);
-               } else
-                       technisat_usb2_set_led(state->dev, 0, LED_OFF);
-       }
-
-schedule:
-       schedule_delayed_work(&state->green_led_work,
-                       msecs_to_jiffies(500));
-}
-
-/* method to find out whether the firmware has to be downloaded or not */
-static int technisat_usb2_identify_state(struct usb_device *udev,
-               struct dvb_usb_device_properties *props,
-               struct dvb_usb_device_description **desc, int *cold)
-{
-       int ret;
-       u8 version[3];
-
-       /* first select the interface */
-       if (usb_set_interface(udev, 0, 1) != 0)
-               err("could not set alternate setting to 0");
-       else
-               info("set alternate setting");
-
-       *cold = 0; /* by default do not download a firmware - just in case something is wrong */
-
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-               GET_VERSION_INFO_VENDOR_REQUEST,
-               USB_TYPE_VENDOR | USB_DIR_IN,
-               0, 0,
-               version, sizeof(version), 500);
-
-       if (ret < 0)
-               *cold = 1;
-       else {
-               info("firmware version: %d.%d", version[1], version[2]);
-               *cold = 0;
-       }
-
-       return 0;
-}
-
-/* power control */
-static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
-{
-       struct technisat_usb2_state *state = d->priv;
-
-       state->power_state = level;
-
-       if (disable_led_control)
-               return 0;
-
-       /* green led is turned off in any case - will be turned on when tuning */
-       technisat_usb2_set_led(d, 0, LED_OFF);
-       /* red led is turned on all the time */
-       technisat_usb2_set_led(d, 1, LED_ON);
-       return 0;
-}
-
-/* mac address reading - from the eeprom */
-#if 0
-static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
-{
-       u8 reg;
-       u8 b[16];
-       int i, j;
-
-       /* full EEPROM dump */
-       for (j = 0; j < 256 * 4; j += 16) {
-               reg = j;
-               if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
-                       break;
-
-               deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
-               for (i = 0; i < 16; i++)
-                       deb_eeprom("%02x ", b[i]);
-               deb_eeprom("\n");
-       }
-}
-#endif
-
-static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
-{
-       u8 lrc = 0;
-       while (--length)
-               lrc ^= *b++;
-       return lrc;
-}
-
-static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
-       u16 offset, u8 *b, u16 length, u8 tries)
-{
-       u8 bo = offset & 0xff;
-       struct i2c_msg msg[] = {
-               {
-                       .addr = 0x50 | ((offset >> 8) & 0x3),
-                       .buf = &bo,
-                       .len = 1
-               }, {
-                       .addr = 0x50 | ((offset >> 8) & 0x3),
-                       .flags  = I2C_M_RD,
-                       .buf = b,
-                       .len = length
-               }
-       };
-
-       while (tries--) {
-               int status;
-
-               if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
-                       break;
-
-               status =
-                       technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
-
-               if (status)
-                       return 0;
-       }
-
-       return -EREMOTEIO;
-}
-
-#define EEPROM_MAC_START 0x3f8
-#define EEPROM_MAC_TOTAL 8
-static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
-               u8 mac[])
-{
-       u8 buf[EEPROM_MAC_TOTAL];
-
-       if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
-                               buf, EEPROM_MAC_TOTAL, 4) != 0)
-               return -ENODEV;
-
-       memcpy(mac, buf, 6);
-       return 0;
-}
-
-/* frontend attach */
-static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
-               fe_sec_voltage_t voltage)
-{
-       int i;
-       u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
-
-       gpio[2] = 1; /* high - voltage ? */
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               gpio[0] = 1;
-               break;
-       case SEC_VOLTAGE_18:
-               gpio[0] = 1;
-               gpio[1] = 1;
-               break;
-       default:
-       case SEC_VOLTAGE_OFF:
-               break;
-       }
-
-       for (i = 0; i < 3; i++)
-               if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
-                       return -EREMOTEIO;
-       return 0;
-}
-
-static struct stv090x_config technisat_usb2_stv090x_config = {
-       .device         = STV0903,
-       .demod_mode     = STV090x_SINGLE,
-       .clk_mode       = STV090x_CLK_EXT,
-
-       .xtal           = 8000000,
-       .address        = 0x68,
-
-       .ts1_mode       = STV090x_TSMODE_DVBCI,
-       .ts1_clk        = 13400000,
-       .ts1_tei        = 1,
-
-       .repeater_level = STV090x_RPTLEVEL_64,
-
-       .tuner_bbgain   = 6,
-};
-
-static struct stv6110x_config technisat_usb2_stv6110x_config = {
-       .addr           = 0x60,
-       .refclk         = 16000000,
-       .clk_div        = 2,
-};
-
-static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
-{
-       struct usb_device *udev = a->dev->udev;
-       int ret;
-
-       a->fe_adap[0].fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
-                       &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
-
-       if (a->fe_adap[0].fe) {
-               struct stv6110x_devctl *ctl;
-
-               ctl = dvb_attach(stv6110x_attach,
-                               a->fe_adap[0].fe,
-                               &technisat_usb2_stv6110x_config,
-                               &a->dev->i2c_adap);
-
-               if (ctl) {
-                       technisat_usb2_stv090x_config.tuner_init          = ctl->tuner_init;
-                       technisat_usb2_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
-                       technisat_usb2_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
-                       technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
-                       technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
-                       technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
-                       technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
-                       technisat_usb2_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
-                       technisat_usb2_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
-                       technisat_usb2_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
-                       technisat_usb2_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 (a->fe_adap[0].fe->ops.init)
-                               a->fe_adap[0].fe->ops.init(a->fe_adap[0].fe);
-
-                       if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
-                               return -EAGAIN;
-
-                       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                                       SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
-                                       USB_TYPE_VENDOR | USB_DIR_OUT,
-                                       0, 0,
-                                       NULL, 0, 500);
-                       mutex_unlock(&a->dev->i2c_mutex);
-
-                       if (ret != 0)
-                               err("could not set IF_CLK to external");
-
-                       a->fe_adap[0].fe->ops.set_voltage = technisat_usb2_set_voltage;
-
-                       /* if everything was successful assign a nice name to the frontend */
-                       strlcpy(a->fe_adap[0].fe->ops.info.name, a->dev->desc->name,
-                                       sizeof(a->fe_adap[0].fe->ops.info.name));
-               } else {
-                       dvb_frontend_detach(a->fe_adap[0].fe);
-                       a->fe_adap[0].fe = NULL;
-               }
-       }
-
-       technisat_usb2_set_led_timer(a->dev, 1, 1);
-
-       return a->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-/* Remote control */
-
-/* the device is giving providing raw IR-signals to the host mapping
- * it only to one remote control is just the default implementation
- */
-#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
-#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
-
-#define FIRMWARE_CLOCK_TICK 83333
-#define FIRMWARE_CLOCK_DIVISOR 256
-
-#define IR_PERCENT_TOLERANCE 15
-
-#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
-#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
-
-#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
-#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
-
-#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
-#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
-
-#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
-#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
-
-static int technisat_usb2_get_ir(struct dvb_usb_device *d)
-{
-       u8 buf[62], *b;
-       int ret;
-       struct ir_raw_event ev;
-
-       buf[0] = GET_IR_DATA_VENDOR_REQUEST;
-       buf[1] = 0x08;
-       buf[2] = 0x8f;
-       buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
-       buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
-                       GET_IR_DATA_VENDOR_REQUEST,
-                       USB_TYPE_VENDOR | USB_DIR_OUT,
-                       0, 0,
-                       buf, 5, 500);
-       if (ret < 0)
-               goto unlock;
-
-       buf[1] = 0;
-       buf[2] = 0;
-       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-                       GET_IR_DATA_VENDOR_REQUEST,
-                       USB_TYPE_VENDOR | USB_DIR_IN,
-                       0x8080, 0,
-                       buf, sizeof(buf), 500);
-
-unlock:
-       mutex_unlock(&d->i2c_mutex);
-
-       if (ret < 0)
-               return ret;
-
-       if (ret == 1)
-               return 0; /* no key pressed */
-
-       /* decoding */
-       b = buf+1;
-
-#if 0
-       deb_rc("RC: %d ", ret);
-       debug_dump(b, ret, deb_rc);
-#endif
-
-       ev.pulse = 0;
-       while (1) {
-               ev.pulse = !ev.pulse;
-               ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
-               ir_raw_event_store(d->rc_dev, &ev);
-
-               b++;
-               if (*b == 0xff) {
-                       ev.pulse = 0;
-                       ev.duration = 888888*2;
-                       ir_raw_event_store(d->rc_dev, &ev);
-                       break;
-               }
-       }
-
-       ir_raw_event_handle(d->rc_dev);
-
-       return 1;
-}
-
-static int technisat_usb2_rc_query(struct dvb_usb_device *d)
-{
-       int ret = technisat_usb2_get_ir(d);
-
-       if (ret < 0)
-               return ret;
-
-       if (ret == 0)
-               return 0;
-
-       if (!disable_led_control)
-               technisat_usb2_set_led(d, 1, LED_BLINK);
-
-       return 0;
-}
-
-/* DVB-USB and USB stuff follows */
-static struct usb_device_id technisat_usb2_id_table[] = {
-       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
-       { 0 }           /* Terminating entry */
-};
-
-/* device description */
-static struct dvb_usb_device_properties technisat_usb2_devices = {
-       .caps              = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl          = CYPRESS_FX2,
-
-       .identify_state    = technisat_usb2_identify_state,
-       .firmware          = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
-
-       .size_of_priv      = sizeof(struct technisat_usb2_state),
-
-       .i2c_algo          = &technisat_usb2_i2c_algo,
-
-       .power_ctrl        = technisat_usb2_power_ctrl,
-       .read_mac_address  = technisat_usb2_read_mac_address,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach  = technisat_usb2_frontend_attach,
-
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 8,
-                               .endpoint = 0x2,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 32,
-                                               .framesize = 2048,
-                                               .interval = 3,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv = 0,
-               },
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Technisat SkyStar USB HD (DVB-S/S2)",
-                       { &technisat_usb2_id_table[0], NULL },
-                       { NULL },
-               },
-       },
-
-       .rc.core = {
-               .rc_interval = 100,
-               .rc_codes    = RC_MAP_TECHNISAT_USB2,
-               .module_name = "technisat-usb2",
-               .rc_query    = technisat_usb2_rc_query,
-               .allowed_protos = RC_TYPE_ALL,
-               .driver_type    = RC_DRIVER_IR_RAW,
-       }
-};
-
-static int technisat_usb2_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct dvb_usb_device *dev;
-
-       if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
-                               &dev, adapter_nr) != 0)
-               return -ENODEV;
-
-       if (dev) {
-               struct technisat_usb2_state *state = dev->priv;
-               state->dev = dev;
-
-               if (!disable_led_control) {
-                       INIT_DELAYED_WORK(&state->green_led_work,
-                                       technisat_usb2_green_led_control);
-                       schedule_delayed_work(&state->green_led_work,
-                                       msecs_to_jiffies(500));
-               }
-       }
-
-       return 0;
-}
-
-static void technisat_usb2_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *dev = usb_get_intfdata(intf);
-
-       /* work and stuff was only created when the device is is hot-state */
-       if (dev != NULL) {
-               struct technisat_usb2_state *state = dev->priv;
-               if (state != NULL)
-                       cancel_delayed_work_sync(&state->green_led_work);
-       }
-
-       dvb_usb_device_exit(intf);
-}
-
-static struct usb_driver technisat_usb2_driver = {
-       .name       = "dvb_usb_technisat_usb2",
-       .probe      = technisat_usb2_probe,
-       .disconnect = technisat_usb2_disconnect,
-       .id_table   = technisat_usb2_id_table,
-};
-
-module_usb_driver(technisat_usb2_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
-MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
deleted file mode 100644 (file)
index e53a106..0000000
+++ /dev/null
@@ -1,820 +0,0 @@
-/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
- * (e.g. Pinnacle 400e DVB-S USB2.0).
- *
- * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
- *
- * TDA8263 + TDA10086
- *
- * I2C addresses:
- * 0x08 - LNBP21PD   - LNB power supply
- * 0x0e - TDA10086   - Demodulator
- * 0x50 - FX2 eeprom
- * 0x60 - TDA8263    - Tuner
- * 0x78 ???
- *
- * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
- * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#define DVB_USB_LOG_PREFIX "ttusb2"
-#include "dvb-usb.h"
-
-#include "ttusb2.h"
-
-#include "tda826x.h"
-#include "tda10086.h"
-#include "tda1002x.h"
-#include "tda10048.h"
-#include "tda827x.h"
-#include "lnbp21.h"
-/* CA */
-#include "dvb_ca_en50221.h"
-
-/* debug */
-static int dvb_usb_ttusb2_debug;
-#define deb_info(args...)   dprintk(dvb_usb_ttusb2_debug,0x01,args)
-module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
-static int dvb_usb_ttusb2_debug_ci;
-module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644);
-MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define ci_dbg(format, arg...)                \
-do {                                          \
-       if (dvb_usb_ttusb2_debug_ci)                                    \
-               printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
-                       ": %s " format "\n" , __func__, ## arg);       \
-} while (0)
-
-enum {
-       TT3650_CMD_CI_TEST = 0x40,
-       TT3650_CMD_CI_RD_CTRL,
-       TT3650_CMD_CI_WR_CTRL,
-       TT3650_CMD_CI_RD_ATTR,
-       TT3650_CMD_CI_WR_ATTR,
-       TT3650_CMD_CI_RESET,
-       TT3650_CMD_CI_SET_VIDEO_PORT
-};
-
-struct ttusb2_state {
-       struct dvb_ca_en50221 ca;
-       struct mutex ca_mutex;
-       u8 id;
-       u16 last_rc_key;
-};
-
-static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
-               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       struct ttusb2_state *st = d->priv;
-       u8 *s, *r = NULL;
-       int ret = 0;
-
-       s = kzalloc(wlen+4, GFP_KERNEL);
-       if (!s)
-               return -ENOMEM;
-
-       r = kzalloc(64, GFP_KERNEL);
-       if (!r) {
-               kfree(s);
-               return -ENOMEM;
-       }
-
-       s[0] = 0xaa;
-       s[1] = ++st->id;
-       s[2] = cmd;
-       s[3] = wlen;
-       memcpy(&s[4],wbuf,wlen);
-
-       ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
-
-       if (ret  != 0 ||
-               r[0] != 0x55 ||
-               r[1] != s[1] ||
-               r[2] != cmd ||
-               (rlen > 0 && r[3] != rlen)) {
-               warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
-               kfree(s);
-               kfree(r);
-               return -EIO;
-       }
-
-       if (rlen > 0)
-               memcpy(rbuf, &r[4], rlen);
-
-       kfree(s);
-       kfree(r);
-
-       return 0;
-}
-
-/* ci */
-static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
-{
-       int ret;
-       u8 rx[60];/* (64 -4) */
-       ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
-       if (!ret)
-               memcpy(data, rx, read_len);
-       return ret;
-}
-
-static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
-{
-       struct dvb_usb_device *d = ca->data;
-       struct ttusb2_state *state = d->priv;
-       int ret;
-
-       mutex_lock(&state->ca_mutex);
-       ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
-       mutex_unlock(&state->ca_mutex);
-
-       return ret;
-}
-
-static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
-{
-       u8 buf[3];
-       int ret = 0;
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = (address >> 8) & 0x0F;
-       buf[1] = address;
-
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
-
-       ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]);
-
-       if (ret < 0)
-               return ret;
-
-       return buf[2];
-}
-
-static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
-{
-       u8 buf[3];
-
-       ci_dbg("%d 0x%04x 0x%02x", slot, address, value);
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = (address >> 8) & 0x0F;
-       buf[1] = address;
-       buf[2] = value;
-
-       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
-}
-
-static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
-{
-       u8 buf[2];
-       int ret;
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = address & 3;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
-
-       ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]);
-
-       if (ret < 0)
-               return ret;
-
-       return buf[1];
-}
-
-static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
-{
-       u8 buf[2];
-
-       ci_dbg("%d 0x%02x 0x%02x", slot, address, value);
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = address;
-       buf[1] = value;
-
-       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
-}
-
-static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable)
-{
-       u8 buf[1];
-       int ret;
-
-       ci_dbg("%d %d", slot, enable);
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = enable;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
-       if (ret < 0)
-               return ret;
-
-       if (enable != buf[0]) {
-               err("CI not %sabled.", enable ? "en" : "dis");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-       return tt3650_ci_set_video_port(ca, slot, 0);
-}
-
-static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-       return tt3650_ci_set_video_port(ca, slot, 1);
-}
-
-static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-       struct dvb_usb_device *d = ca->data;
-       struct ttusb2_state *state = d->priv;
-       u8 buf[1];
-       int ret;
-
-       ci_dbg("%d", slot);
-
-       if (slot)
-               return -EINVAL;
-
-       buf[0] = 0;
-
-       mutex_lock(&state->ca_mutex);
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
-       if (ret)
-               goto failed;
-
-       msleep(500);
-
-       buf[0] = 1;
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
-       if (ret)
-               goto failed;
-
-       msleep(500);
-
-       buf[0] = 0; /* FTA */
-
-       ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
-
-       msleep(1100);
-
- failed:
-       mutex_unlock(&state->ca_mutex);
-
-       return ret;
-}
-
-static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-       u8 buf[1];
-       int ret;
-
-       if (slot)
-               return -EINVAL;
-
-       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
-       if (ret)
-               return ret;
-
-       if (1 == buf[0]) {
-               return DVB_CA_EN50221_POLL_CAM_PRESENT |
-                       DVB_CA_EN50221_POLL_CAM_READY;
-       }
-       return 0;
-}
-
-static void tt3650_ci_uninit(struct dvb_usb_device *d)
-{
-       struct ttusb2_state *state;
-
-       ci_dbg("");
-
-       if (NULL == d)
-               return;
-
-       state = d->priv;
-       if (NULL == state)
-               return;
-
-       if (NULL == state->ca.data)
-               return;
-
-       dvb_ca_en50221_release(&state->ca);
-
-       memset(&state->ca, 0, sizeof(state->ca));
-}
-
-static int tt3650_ci_init(struct dvb_usb_adapter *a)
-{
-       struct dvb_usb_device *d = a->dev;
-       struct ttusb2_state *state = d->priv;
-       int ret;
-
-       ci_dbg("");
-
-       mutex_init(&state->ca_mutex);
-
-       state->ca.owner = THIS_MODULE;
-       state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
-       state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
-       state->ca.read_cam_control = tt3650_ci_read_cam_control;
-       state->ca.write_cam_control = tt3650_ci_write_cam_control;
-       state->ca.slot_reset = tt3650_ci_slot_reset;
-       state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
-       state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
-       state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
-       state->ca.data = d;
-
-       ret = dvb_ca_en50221_init(&a->dvb_adap,
-                                 &state->ca,
-                                 /* flags */ 0,
-                                 /* n_slots */ 1);
-       if (ret) {
-               err("Cannot initialize CI: Error %d.", ret);
-               memset(&state->ca, 0, sizeof(state->ca));
-               return ret;
-       }
-
-       info("CI initialized.");
-
-       return 0;
-}
-
-static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       static u8 obuf[60], ibuf[60];
-       int i, write_read, read;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       if (num > 2)
-               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
-       for (i = 0; i < num; i++) {
-               write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
-               read = msg[i].flags & I2C_M_RD;
-
-               obuf[0] = (msg[i].addr << 1) | (write_read | read);
-               if (read)
-                       obuf[1] = 0;
-               else
-                       obuf[1] = msg[i].len;
-
-               /* read request */
-               if (write_read)
-                       obuf[2] = msg[i+1].len;
-               else if (read)
-                       obuf[2] = msg[i].len;
-               else
-                       obuf[2] = 0;
-
-               memcpy(&obuf[3], msg[i].buf, msg[i].len);
-
-               if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
-                       err("i2c transfer failed.");
-                       break;
-               }
-
-               if (write_read) {
-                       memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len);
-                       i++;
-               } else if (read)
-                       memcpy(msg[i].buf, &ibuf[3], msg[i].len);
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm ttusb2_i2c_algo = {
-       .master_xfer   = ttusb2_i2c_xfer,
-       .functionality = ttusb2_i2c_func,
-};
-
-/* command to poll IR receiver (copied from pctv452e.c) */
-#define CMD_GET_IR_CODE     0x1b
-
-/* IR */
-static int tt3650_rc_query(struct dvb_usb_device *d)
-{
-       int ret;
-       u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
-       struct ttusb2_state *st = d->priv;
-       ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
-       if (ret != 0)
-               return ret;
-
-       if (rx[8] & 0x01) {
-               /* got a "press" event */
-               st->last_rc_key = (rx[3] << 8) | rx[2];
-               deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
-               rc_keydown(d->rc_dev, st->last_rc_key, 0);
-       } else if (st->last_rc_key) {
-               rc_keyup(d->rc_dev);
-               st->last_rc_key = 0;
-       }
-
-       return 0;
-}
-
-
-/* Callbacks for DVB USB */
-static int ttusb2_identify_state (struct usb_device *udev, struct
-               dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
-               int *cold)
-{
-       *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
-       return 0;
-}
-
-static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 b = onoff;
-       ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
-       return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
-}
-
-
-static struct tda10086_config tda10086_config = {
-       .demod_address = 0x0e,
-       .invert = 0,
-       .diseqc_tone = 1,
-       .xtal_freq = TDA10086_XTAL_16M,
-};
-
-static struct tda10023_config tda10023_config = {
-       .demod_address = 0x0c,
-       .invert = 0,
-       .xtal = 16000000,
-       .pll_m = 11,
-       .pll_p = 3,
-       .pll_n = 1,
-       .deltaf = 0xa511,
-};
-
-static struct tda10048_config tda10048_config = {
-       .demod_address    = 0x10 >> 1,
-       .output_mode      = TDA10048_PARALLEL_OUTPUT,
-       .inversion        = TDA10048_INVERSION_ON,
-       .dtv6_if_freq_khz = TDA10048_IF_4000,
-       .dtv7_if_freq_khz = TDA10048_IF_4500,
-       .dtv8_if_freq_khz = TDA10048_IF_5000,
-       .clk_freq_khz     = TDA10048_CLK_16000,
-       .no_firmware      = 1,
-       .set_pll          = true ,
-       .pll_m            = 5,
-       .pll_n            = 3,
-       .pll_p            = 0,
-};
-
-static struct tda827x_config tda827x_config = {
-       .config = 0,
-};
-
-static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev,0,3) < 0)
-               err("set interface to alts=3 failed");
-
-       if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
-               deb_info("TDA10086 attach failed\n");
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-
-       return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
-}
-
-static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
-{
-       if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
-               err("set interface to alts=3 failed");
-
-       if (adap->fe_adap[0].fe == NULL) {
-               /* FE 0 DVB-C */
-               adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
-                       &tda10023_config, &adap->dev->i2c_adap, 0x48);
-
-               if (adap->fe_adap[0].fe == NULL) {
-                       deb_info("TDA10023 attach failed\n");
-                       return -ENODEV;
-               }
-               tt3650_ci_init(adap);
-       } else {
-               adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
-                       &tda10048_config, &adap->dev->i2c_adap);
-
-               if (adap->fe_adap[1].fe == NULL) {
-                       deb_info("TDA10048 attach failed\n");
-                       return -ENODEV;
-               }
-
-               /* tuner is behind TDA10023 I2C-gate */
-               adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
-
-       }
-
-       return 0;
-}
-
-static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_frontend *fe;
-
-       /* MFE: select correct FE to attach tuner since that's called twice */
-       if (adap->fe_adap[1].fe == NULL)
-               fe = adap->fe_adap[0].fe;
-       else
-               fe = adap->fe_adap[1].fe;
-
-       /* attach tuner */
-       if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
-               printk(KERN_ERR "%s: No tda827x found!\n", __func__);
-               return -ENODEV;
-       }
-       return 0;
-}
-
-static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
-{
-       if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
-               deb_info("TDA8263 attach failed\n");
-               return -ENODEV;
-       }
-
-       if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
-               deb_info("LNBP21 attach failed\n");
-               return -ENODEV;
-       }
-       return 0;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties ttusb2_properties;
-static struct dvb_usb_device_properties ttusb2_properties_s2400;
-static struct dvb_usb_device_properties ttusb2_properties_ct3650;
-
-static void ttusb2_usb_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-
-       tt3650_ci_uninit(d);
-       dvb_usb_device_exit(intf);
-}
-
-static int ttusb2_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
-                                    THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-       return -ENODEV;
-}
-
-static struct usb_device_id ttusb2_table [] = {
-       { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
-       { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
-       { USB_DEVICE(USB_VID_TECHNOTREND,
-               USB_PID_TECHNOTREND_CONNECT_S2400) },
-       { USB_DEVICE(USB_VID_TECHNOTREND,
-               USB_PID_TECHNOTREND_CONNECT_CT3650) },
-       {}              /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, ttusb2_table);
-
-static struct dvb_usb_device_properties ttusb2_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-pctv-400e-01.fw",
-
-       .size_of_priv = sizeof(struct ttusb2_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = NULL, // ttusb2_streaming_ctrl,
-
-                       .frontend_attach  = ttusb2_frontend_tda10086_attach,
-                       .tuner_attach     = ttusb2_tuner_tda826x_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize = 940,
-                                               .interval = 1,
-                                       }
-                               }
-                       }
-               }},
-               }
-       },
-
-       .power_ctrl       = ttusb2_power_ctrl,
-       .identify_state   = ttusb2_identify_state,
-
-       .i2c_algo         = &ttusb2_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 2,
-       .devices = {
-               {   "Pinnacle 400e DVB-S USB2.0",
-                       { &ttusb2_table[0], NULL },
-                       { NULL },
-               },
-               {   "Pinnacle 450e DVB-S USB2.0",
-                       { &ttusb2_table[1], NULL },
-                       { NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-tt-s2400-01.fw",
-
-       .size_of_priv = sizeof(struct ttusb2_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = NULL,
-
-                       .frontend_attach  = ttusb2_frontend_tda10086_attach,
-                       .tuner_attach     = ttusb2_tuner_tda826x_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize = 940,
-                                               .interval = 1,
-                                       }
-                               }
-                       }
-               }},
-               }
-       },
-
-       .power_ctrl       = ttusb2_power_ctrl,
-       .identify_state   = ttusb2_identify_state,
-
-       .i2c_algo         = &ttusb2_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Technotrend TT-connect S-2400",
-                       { &ttusb2_table[2], NULL },
-                       { NULL },
-               },
-       }
-};
-
-static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-
-       .size_of_priv = sizeof(struct ttusb2_state),
-
-       .rc.core = {
-               .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
-               .rc_codes         = RC_MAP_TT_1500,
-               .rc_query         = tt3650_rc_query,
-               .allowed_protos   = RC_TYPE_UNKNOWN,
-       },
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 2,
-               .fe = {{
-                       .streaming_ctrl   = NULL,
-
-                       .frontend_attach  = ttusb2_frontend_tda10023_attach,
-                       .tuner_attach = ttusb2_tuner_tda827x_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize = 940,
-                                               .interval = 1,
-                                       }
-                               }
-                       }
-               }, {
-                       .streaming_ctrl   = NULL,
-
-                       .frontend_attach  = ttusb2_frontend_tda10023_attach,
-                       .tuner_attach = ttusb2_tuner_tda827x_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_ISOC,
-                               .count = 5,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .isoc = {
-                                               .framesperurb = 4,
-                                               .framesize = 940,
-                                               .interval = 1,
-                                       }
-                               }
-                       }
-               }},
-               },
-       },
-
-       .power_ctrl       = ttusb2_power_ctrl,
-       .identify_state   = ttusb2_identify_state,
-
-       .i2c_algo         = &ttusb2_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {   "Technotrend TT-connect CT-3650",
-                       .warm_ids = { &ttusb2_table[3], NULL },
-               },
-       }
-};
-
-static struct usb_driver ttusb2_driver = {
-       .name           = "dvb_usb_ttusb2",
-       .probe          = ttusb2_probe,
-       .disconnect     = ttusb2_usb_disconnect,
-       .id_table       = ttusb2_table,
-};
-
-module_usb_driver(ttusb2_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.h b/drivers/media/dvb/dvb-usb/ttusb2.h
deleted file mode 100644 (file)
index 52a63af..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
- * (e.g. Pinnacle 400e DVB-S USB2.0).
- *
- * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
- * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_TTUSB2_H_
-#define _DVB_USB_TTUSB2_H_
-
-/* TTUSB protocol
- *
- * always to messages (out/in)
- * out message:
- * 0xaa <id> <cmdbyte> <datalen> <data...>
- *
- * in message (complete block is always 0x40 bytes long)
- * 0x55 <id> <cmdbyte> <datalen> <data...>
- *
- * id is incremented for each transaction
- */
-
-#define CMD_DSP_DOWNLOAD    0x13
-/* out data: <byte>[28]
- * last block must be empty */
-
-#define CMD_DSP_BOOT        0x14
-/* out data: nothing */
-
-#define CMD_POWER           0x15
-/* out data: <on=1/off=0> */
-
-#define CMD_LNB             0x16
-/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */
-
-#define CMD_GET_VERSION     0x17
-/* in  data: <version_byte>[5] */
-
-#define CMD_DISEQC          0x18
-/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */
-
-#define CMD_PID_ENABLE      0x22
-/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */
-
-#define CMD_PID_DISABLE     0x23
-/* out data: <index> */
-
-#define CMD_FILTER_ENABLE   0x24
-/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */
-
-#define CMD_FILTER_DISABLE  0x25
-/* out data: <index> */
-
-#define CMD_GET_DSP_VERSION 0x26
-/* in  data: <version_byte>[28] */
-
-#define CMD_I2C_XFER        0x31
-/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen]
- * in  data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */
-
-#define CMD_I2C_BITRATE     0x32
-/* out data: <default=0> */
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
deleted file mode 100644 (file)
index 9b04229..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
- * DVB-T receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "dibusb.h"
-
-#include "mt352.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int umt_mt352_demod_init(struct dvb_frontend *fe)
-{
-       static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
-       static u8 mt352_reset[] = { 0x50, 0x80 };
-       static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
-       static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
-       static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
-
-       static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
-       static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
-       static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
-       static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
-       static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
-
-       static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
-       static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
-
-       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-       udelay(2000);
-       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-       mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
-
-       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_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
-       mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
-       mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
-       mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
-       mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
-
-       mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
-       mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
-
-       return 0;
-}
-
-static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct mt352_config umt_config;
-
-       memset(&umt_config,0,sizeof(struct mt352_config));
-       umt_config.demod_init = umt_mt352_demod_init;
-       umt_config.demod_address = 0xf;
-
-       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
-
-       return 0;
-}
-
-static int umt_tuner_attach (struct dvb_usb_adapter *adap)
-{
-       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_TUA6034);
-       return 0;
-}
-
-/* USB Driver stuff */
-static struct dvb_usb_device_properties umt_properties;
-
-static int umt_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       if (0 == dvb_usb_device_init(intf, &umt_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-       return -EINVAL;
-}
-
-/* do not change the order of the ID table */
-static struct usb_device_id umt_table [] = {
-/* 00 */       { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
-/* 01 */       { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
-                       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, umt_table);
-
-static struct dvb_usb_device_properties umt_properties = {
-       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-umt-010-02.fw",
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-                       .frontend_attach  = umt_mt352_frontend_attach,
-                       .tuner_attach     = umt_tuner_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = MAX_NO_URBS_FOR_DATA_STREAM,
-                               .endpoint = 0x06,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 512,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct dibusb_state),
-               }
-       },
-       .power_ctrl       = dibusb_power_ctrl,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
-       .num_device_descs = 1,
-       .devices = {
-               {       "Hanftek UMT-010 DVB-T USB2.0",
-                       { &umt_table[0], NULL },
-                       { &umt_table[1], NULL },
-               },
-       }
-};
-
-static struct usb_driver umt_driver = {
-       .name           = "dvb_usb_umt_010",
-       .probe          = umt_probe,
-       .disconnect = dvb_usb_device_exit,
-       .id_table       = umt_table,
-};
-
-module_usb_driver(umt_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
deleted file mode 100644 (file)
index d62ee0f..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/* usb-urb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file keeps functions for initializing and handling the
- * BULK and ISOC USB data transfers in a generic way.
- * Can be used for DVB-only and also, that's the plan, for
- * Hybrid USB devices (analog and DVB).
- */
-#include "dvb-usb-common.h"
-
-/* URB stuff for streaming */
-static void usb_urb_complete(struct urb *urb)
-{
-       struct usb_data_stream *stream = urb->context;
-       int ptype = usb_pipetype(urb->pipe);
-       int i;
-       u8 *b;
-
-       deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
-               ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
-               urb->status,urb->actual_length,urb->transfer_buffer_length,
-               urb->number_of_packets,urb->error_count);
-
-       switch (urb->status) {
-               case 0:         /* success */
-               case -ETIMEDOUT:    /* NAK */
-                       break;
-               case -ECONNRESET:   /* kill */
-               case -ENOENT:
-               case -ESHUTDOWN:
-                       return;
-               default:        /* error */
-                       deb_ts("urb completition error %d.\n", urb->status);
-                       break;
-       }
-
-       b = (u8 *) urb->transfer_buffer;
-       switch (ptype) {
-               case PIPE_ISOCHRONOUS:
-                       for (i = 0; i < urb->number_of_packets; i++) {
-
-                               if (urb->iso_frame_desc[i].status != 0)
-                                       deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
-                               else if (urb->iso_frame_desc[i].actual_length > 0)
-                                       stream->complete(stream, b + 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;
-                       }
-                       debug_dump(b,20,deb_uxfer);
-                       break;
-               case PIPE_BULK:
-                       if (urb->actual_length > 0)
-                               stream->complete(stream, b, urb->actual_length);
-                       break;
-               default:
-                       err("unknown endpoint type in completition handler.");
-                       return;
-       }
-       usb_submit_urb(urb,GFP_ATOMIC);
-}
-
-int usb_urb_kill(struct usb_data_stream *stream)
-{
-       int i;
-       for (i = 0; i < stream->urbs_submitted; i++) {
-               deb_ts("killing URB no. %d.\n",i);
-
-               /* stop the URB */
-               usb_kill_urb(stream->urb_list[i]);
-       }
-       stream->urbs_submitted = 0;
-       return 0;
-}
-
-int usb_urb_submit(struct usb_data_stream *stream)
-{
-       int i,ret;
-       for (i = 0; i < stream->urbs_initialized; i++) {
-               deb_ts("submitting URB no. %d\n",i);
-               if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
-                       err("could not submit URB no. %d - get them all back",i);
-                       usb_urb_kill(stream);
-                       return ret;
-               }
-               stream->urbs_submitted++;
-       }
-       return 0;
-}
-
-static int usb_free_stream_buffers(struct usb_data_stream *stream)
-{
-       if (stream->state & USB_STATE_URB_BUF) {
-               while (stream->buf_num) {
-                       stream->buf_num--;
-                       deb_mem("freeing buffer %d\n",stream->buf_num);
-                       usb_free_coherent(stream->udev, stream->buf_size,
-                                         stream->buf_list[stream->buf_num],
-                                         stream->dma_addr[stream->buf_num]);
-               }
-       }
-
-       stream->state &= ~USB_STATE_URB_BUF;
-
-       return 0;
-}
-
-static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
-{
-       stream->buf_num = 0;
-       stream->buf_size = size;
-
-       deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
-
-       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
-               deb_mem("allocating buffer %d\n",stream->buf_num);
-               if (( stream->buf_list[stream->buf_num] =
-                                       usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
-                                       &stream->dma_addr[stream->buf_num]) ) == NULL) {
-                       deb_mem("not enough memory for urb-buffer allocation.\n");
-                       usb_free_stream_buffers(stream);
-                       return -ENOMEM;
-               }
-               deb_mem("buffer %d: %p (dma: %Lu)\n",
-                       stream->buf_num,
-stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]);
-               memset(stream->buf_list[stream->buf_num],0,size);
-               stream->state |= USB_STATE_URB_BUF;
-       }
-       deb_mem("allocation successful\n");
-
-       return 0;
-}
-
-static int usb_bulk_urb_init(struct usb_data_stream *stream)
-{
-       int i, j;
-
-       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
-                                       stream->props.u.bulk.buffersize)) < 0)
-               return i;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       deb_mem("not enough memory for urb_alloc_urb!.\n");
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-               usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
-                               usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
-                               stream->buf_list[i],
-                               stream->props.u.bulk.buffersize,
-                               usb_urb_complete, stream);
-
-               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-static int usb_isoc_urb_init(struct usb_data_stream *stream)
-{
-       int i,j;
-
-       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
-                                       stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
-               return i;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               struct urb *urb;
-               int frame_offset = 0;
-
-               stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       deb_mem("not enough memory for urb_alloc_urb!\n");
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-
-               urb = stream->urb_list[i];
-
-               urb->dev = stream->udev;
-               urb->context = stream;
-               urb->complete = usb_urb_complete;
-               urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
-               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-               urb->interval = stream->props.u.isoc.interval;
-               urb->number_of_packets = stream->props.u.isoc.framesperurb;
-               urb->transfer_buffer_length = stream->buf_size;
-               urb->transfer_buffer = stream->buf_list[i];
-               urb->transfer_dma = stream->dma_addr[i];
-
-               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
-                       frame_offset += stream->props.u.isoc.framesize;
-               }
-
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
-{
-       if (stream == NULL || props == NULL)
-               return -EINVAL;
-
-       memcpy(&stream->props, props, sizeof(*props));
-
-       usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
-
-       if (stream->complete == NULL) {
-               err("there is no data callback - this doesn't make sense.");
-               return -EINVAL;
-       }
-
-       switch (stream->props.type) {
-               case USB_BULK:
-                       return usb_bulk_urb_init(stream);
-               case USB_ISOC:
-                       return usb_isoc_urb_init(stream);
-               default:
-                       err("unknown URB-type for data transfer.");
-                       return -EINVAL;
-       }
-}
-
-int usb_urb_exit(struct usb_data_stream *stream)
-{
-       int i;
-
-       usb_urb_kill(stream);
-
-       for (i = 0; i < stream->urbs_initialized; i++) {
-               if (stream->urb_list[i] != NULL) {
-                       deb_mem("freeing URB no. %d.\n",i);
-                       /* free the URBs */
-                       usb_free_urb(stream->urb_list[i]);
-               }
-       }
-       stream->urbs_initialized = 0;
-
-       usb_free_stream_buffers(stream);
-       return 0;
-}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
deleted file mode 100644 (file)
index 5eab468..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
- * DVB-S receiver.
- *
- * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
- *                    Metzler Brothers Systementwicklung GbR
- *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * Thanks to Twinhan who kindly provided hardware and information.
- *
- * This file can be removed soon, after the DST-driver is rewritten to provice
- * the frontend-controlling separately.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- */
-#include "vp702x.h"
-
-struct vp702x_fe_state {
-       struct dvb_frontend fe;
-       struct dvb_usb_device *d;
-
-       struct dvb_frontend_ops ops;
-
-       fe_sec_voltage_t voltage;
-       fe_sec_tone_mode_t tone_mode;
-
-       u8 lnb_buf[8];
-
-       u8 lock;
-       u8 sig;
-       u8 snr;
-
-       unsigned long next_status_check;
-       unsigned long status_check_interval;
-};
-
-static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
-{
-       struct vp702x_device_state *dst = st->d->priv;
-       u8 *buf;
-
-       if (time_after(jiffies, st->next_status_check)) {
-               mutex_lock(&dst->buf_mutex);
-               buf = dst->buf;
-
-               vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
-               st->lock = buf[4];
-
-               vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
-               st->snr = buf[0];
-
-               vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
-               st->sig = buf[0];
-
-               mutex_unlock(&dst->buf_mutex);
-               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
-       }
-       return 0;
-}
-
-static u8 vp702x_chksum(u8 *buf,int f, int count)
-{
-       u8 s = 0;
-       int i;
-       for (i = f; i < f+count; i++)
-               s += buf[i];
-       return ~s+1;
-}
-
-static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       vp702x_fe_refresh_state(st);
-       deb_fe("%s\n",__func__);
-
-       if (st->lock == 0)
-               *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
-       else
-               *status = 0;
-
-       if (*status & FE_HAS_LOCK)
-               st->status_check_interval = 1000;
-       else
-               st->status_check_interval = 250;
-       return 0;
-}
-
-/* not supported by this Frontend */
-static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       vp702x_fe_refresh_state(st);
-       *ber = 0;
-       return 0;
-}
-
-/* not supported by this Frontend */
-static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       vp702x_fe_refresh_state(st);
-       *unc = 0;
-       return 0;
-}
-
-static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       vp702x_fe_refresh_state(st);
-
-       *strength = (st->sig << 8) | st->sig;
-       return 0;
-}
-
-static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       u8 _snr;
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       vp702x_fe_refresh_state(st);
-
-       _snr = (st->snr & 0x1f) * 0xff / 0x1f;
-       *snr = (_snr << 8) | _snr;
-       return 0;
-}
-
-static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       deb_fe("%s\n",__func__);
-       tune->min_delay_ms = 2000;
-       return 0;
-}
-
-static int vp702x_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       struct vp702x_device_state *dst = st->d->priv;
-       u32 freq = fep->frequency/1000;
-       /*CalFrequency*/
-/*     u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
-       u64 sr;
-       u8 *cmd;
-
-       mutex_lock(&dst->buf_mutex);
-
-       cmd = dst->buf;
-       memset(cmd, 0, 10);
-
-       cmd[0] = (freq >> 8) & 0x7f;
-       cmd[1] =  freq       & 0xff;
-       cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
-
-       sr = (u64) (fep->symbol_rate/1000) << 20;
-       do_div(sr,88000);
-       cmd[3] = (sr >> 12) & 0xff;
-       cmd[4] = (sr >> 4)  & 0xff;
-       cmd[5] = (sr << 4)  & 0xf0;
-
-       deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n",
-                       fep->frequency, freq, freq, fep->symbol_rate,
-                       (unsigned long) sr, (unsigned long) sr);
-
-/*     if (fep->inversion == INVERSION_ON)
-               cmd[6] |= 0x80; */
-
-       if (st->voltage == SEC_VOLTAGE_18)
-               cmd[6] |= 0x40;
-
-/*     if (fep->symbol_rate > 8000000)
-               cmd[6] |= 0x20;
-
-       if (fep->frequency < 1531000)
-               cmd[6] |= 0x04;
-
-       if (st->tone_mode == SEC_TONE_ON)
-               cmd[6] |= 0x01;*/
-
-       cmd[7] = vp702x_chksum(cmd,0,7);
-
-       st->status_check_interval = 250;
-       st->next_status_check = jiffies;
-
-       vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
-
-       if (cmd[2] == 0 && cmd[3] == 0)
-               deb_fe("tuning failed.\n");
-       else
-               deb_fe("tuning succeeded.\n");
-
-       mutex_unlock(&dst->buf_mutex);
-
-       return 0;
-}
-
-static int vp702x_fe_init(struct dvb_frontend *fe)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       deb_fe("%s\n",__func__);
-       vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
-       return 0;
-}
-
-static int vp702x_fe_sleep(struct dvb_frontend *fe)
-{
-       deb_fe("%s\n",__func__);
-       return 0;
-}
-
-static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       u8 *cmd;
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       struct vp702x_device_state *dst = st->d->priv;
-
-       deb_fe("%s\n",__func__);
-
-       if (m->msg_len > 4)
-               return -EINVAL;
-
-       mutex_lock(&dst->buf_mutex);
-
-       cmd = dst->buf;
-       cmd[1] = SET_DISEQC_CMD;
-       cmd[2] = m->msg_len;
-       memcpy(&cmd[3], m->msg, m->msg_len);
-       cmd[7] = vp702x_chksum(cmd, 0, 7);
-
-       vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
-
-       if (cmd[2] == 0 && cmd[3] == 0)
-               deb_fe("diseqc cmd failed.\n");
-       else
-               deb_fe("diseqc cmd succeeded.\n");
-
-       mutex_unlock(&dst->buf_mutex);
-
-       return 0;
-}
-
-static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
-{
-       deb_fe("%s\n",__func__);
-       return 0;
-}
-
-static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       struct vp702x_device_state *dst = st->d->priv;
-       u8 *buf;
-
-       deb_fe("%s\n",__func__);
-
-       st->tone_mode = tone;
-
-       if (tone == SEC_TONE_ON)
-               st->lnb_buf[2] = 0x02;
-       else
-               st->lnb_buf[2] = 0x00;
-
-       st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
-
-       mutex_lock(&dst->buf_mutex);
-
-       buf = dst->buf;
-       memcpy(buf, st->lnb_buf, 8);
-
-       vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
-       if (buf[2] == 0 && buf[3] == 0)
-               deb_fe("set_tone cmd failed.\n");
-       else
-               deb_fe("set_tone cmd succeeded.\n");
-
-       mutex_unlock(&dst->buf_mutex);
-
-       return 0;
-}
-
-static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
-               voltage)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       struct vp702x_device_state *dst = st->d->priv;
-       u8 *buf;
-       deb_fe("%s\n",__func__);
-
-       st->voltage = voltage;
-
-       if (voltage != SEC_VOLTAGE_OFF)
-               st->lnb_buf[4] = 0x01;
-       else
-               st->lnb_buf[4] = 0x00;
-
-       st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
-
-       mutex_lock(&dst->buf_mutex);
-
-       buf = dst->buf;
-       memcpy(buf, st->lnb_buf, 8);
-
-       vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
-       if (buf[2] == 0 && buf[3] == 0)
-               deb_fe("set_voltage cmd failed.\n");
-       else
-               deb_fe("set_voltage cmd succeeded.\n");
-
-       mutex_unlock(&dst->buf_mutex);
-       return 0;
-}
-
-static void vp702x_fe_release(struct dvb_frontend* fe)
-{
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       kfree(st);
-}
-
-static struct dvb_frontend_ops vp702x_fe_ops;
-
-struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
-{
-       struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
-       if (s == NULL)
-               goto error;
-
-       s->d = d;
-
-       memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
-       s->fe.demodulator_priv = s;
-
-       s->lnb_buf[1] = SET_LNB_POWER;
-       s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
-
-       return &s->fe;
-error:
-       return NULL;
-}
-
-
-static struct dvb_frontend_ops vp702x_fe_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name           = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
-               .frequency_min       = 950000,
-               .frequency_max       = 2150000,
-               .frequency_stepsize  = 1000,   /* kHz for QPSK frontends */
-               .frequency_tolerance = 0,
-               .symbol_rate_min     = 1000000,
-               .symbol_rate_max     = 45000000,
-               .symbol_rate_tolerance = 500,  /* ppm */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-               FE_CAN_QPSK |
-               FE_CAN_FEC_AUTO
-       },
-       .release = vp702x_fe_release,
-
-       .init  = vp702x_fe_init,
-       .sleep = vp702x_fe_sleep,
-
-       .set_frontend = vp702x_fe_set_frontend,
-       .get_tune_settings = vp702x_fe_get_tune_settings,
-
-       .read_status = vp702x_fe_read_status,
-       .read_ber = vp702x_fe_read_ber,
-       .read_signal_strength = vp702x_fe_read_signal_strength,
-       .read_snr = vp702x_fe_read_snr,
-       .read_ucblocks = vp702x_fe_read_unc_blocks,
-
-       .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
-       .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
-       .set_tone = vp702x_fe_set_tone,
-       .set_voltage = vp702x_fe_set_voltage,
-};
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
deleted file mode 100644 (file)
index 07c673a..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
- * receiver.
- *
- * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
- *                    Metzler Brothers Systementwicklung GbR
- *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * Thanks to Twinhan who kindly provided hardware and information.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "vp702x.h"
-#include <linux/mutex.h>
-
-/* debug */
-int dvb_usb_vp702x_debug;
-module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct vp702x_adapter_state {
-       int pid_filter_count;
-       int pid_filter_can_bypass;
-       u8  pid_filter_state;
-};
-
-static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
-                                    u16 value, u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       ret = usb_control_msg(d->udev,
-               usb_rcvctrlpipe(d->udev, 0),
-               req,
-               USB_TYPE_VENDOR | USB_DIR_IN,
-               value, index, b, blen,
-               2000);
-
-       if (ret < 0) {
-               warn("usb in operation failed. (%d)", ret);
-               ret = -EIO;
-       } else
-               ret = 0;
-
-
-       deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
-       debug_dump(b,blen,deb_xfer);
-
-       return ret;
-}
-
-int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
-                           u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       mutex_lock(&d->usb_mutex);
-       ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
-                                     u16 index, u8 *b, int blen)
-{
-       int ret;
-       deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
-       debug_dump(b,blen,deb_xfer);
-
-       if ((ret = usb_control_msg(d->udev,
-                       usb_sndctrlpipe(d->udev,0),
-                       req,
-                       USB_TYPE_VENDOR | USB_DIR_OUT,
-                       value,index,b,blen,
-                       2000)) != blen) {
-               warn("usb out operation failed. (%d)",ret);
-               return -EIO;
-       } else
-               return 0;
-}
-
-int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-                            u16 index, u8 *b, int blen)
-{
-       int ret;
-
-       mutex_lock(&d->usb_mutex);
-       ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
-{
-       int ret;
-
-       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
-               return ret;
-
-       ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
-       msleep(msec);
-       ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-
-static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
-                               int olen, u8 *i, int ilen, int msec)
-{
-       struct vp702x_device_state *st = d->priv;
-       int ret = 0;
-       u8 *buf;
-       int buflen = max(olen + 2, ilen + 1);
-
-       ret = mutex_lock_interruptible(&st->buf_mutex);
-       if (ret < 0)
-               return ret;
-
-       if (buflen > st->buf_len) {
-               buf = kmalloc(buflen, GFP_KERNEL);
-               if (!buf) {
-                       mutex_unlock(&st->buf_mutex);
-                       return -ENOMEM;
-               }
-               info("successfully reallocated a bigger buffer");
-               kfree(st->buf);
-               st->buf = buf;
-               st->buf_len = buflen;
-       } else {
-               buf = st->buf;
-       }
-
-       buf[0] = 0x00;
-       buf[1] = cmd;
-       memcpy(&buf[2], o, olen);
-
-       ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
-
-       if (ret == 0)
-               memcpy(i, &buf[1], ilen);
-       mutex_unlock(&st->buf_mutex);
-
-       return ret;
-}
-
-static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
-{
-       int ret;
-       struct vp702x_device_state *st = adap->dev->priv;
-       u8 *buf;
-
-       mutex_lock(&st->buf_mutex);
-
-       buf = st->buf;
-       memset(buf, 0, 16);
-
-       ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
-                       0, buf, 16);
-       mutex_unlock(&st->buf_mutex);
-       return ret;
-}
-
-static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
-{
-       int ret;
-       struct vp702x_device_state *st = adap->dev->priv;
-       u8 *buf;
-
-       mutex_lock(&st->buf_mutex);
-
-       buf = st->buf;
-       memset(buf, 0, 16);
-       ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
-                       0, buf, 16);
-
-       mutex_unlock(&st->buf_mutex);
-
-       return ret;
-}
-
-static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
-{
-       struct vp702x_adapter_state *st = adap->priv;
-       struct vp702x_device_state *dst = adap->dev->priv;
-       u8 *buf;
-
-       if (onoff)
-               st->pid_filter_state |=  (1 << id);
-       else {
-               st->pid_filter_state &= ~(1 << id);
-               pid = 0xffff;
-       }
-
-       id = 0x10 + id*2;
-
-       vp702x_set_pld_state(adap, st->pid_filter_state);
-
-       mutex_lock(&dst->buf_mutex);
-
-       buf = dst->buf;
-       memset(buf, 0, 16);
-       vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
-       vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
-
-       mutex_unlock(&dst->buf_mutex);
-
-       return 0;
-}
-
-
-static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
-{
-       struct vp702x_adapter_state *st = adap->priv;
-       struct vp702x_device_state *dst = adap->dev->priv;
-       int i;
-       u8 *b;
-
-       st->pid_filter_count = 8;
-       st->pid_filter_can_bypass = 1;
-       st->pid_filter_state = 0x00;
-
-       vp702x_set_pld_mode(adap, 1); /* bypass */
-
-       for (i = 0; i < st->pid_filter_count; i++)
-               vp702x_set_pid(adap, 0xffff, i, 1);
-
-       mutex_lock(&dst->buf_mutex);
-       b = dst->buf;
-       memset(b, 0, 10);
-       vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
-       vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
-       vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
-       mutex_unlock(&dst->buf_mutex);
-       /*vp702x_set_pld_mode(d, 0); // filter */
-
-       return 0;
-}
-
-static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       return 0;
-}
-
-/* keys for the enclosed remote control */
-static struct rc_map_table rc_map_vp702x_table[] = {
-       { 0x0001, KEY_1 },
-       { 0x0002, KEY_2 },
-};
-
-/* remote control stuff (does not work with my box) */
-static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       u8 *key;
-       int i;
-
-/* remove the following return to enabled remote querying */
-       return 0;
-
-       key = kmalloc(10, GFP_KERNEL);
-       if (!key)
-               return -ENOMEM;
-
-       vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
-
-       deb_rc("remote query key: %x %d\n",key[1],key[1]);
-
-       if (key[1] == 0x44) {
-               *state = REMOTE_NO_KEY_PRESSED;
-               kfree(key);
-               return 0;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
-               if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
-                       *state = REMOTE_KEY_PRESSED;
-                       *event = rc_map_vp702x_table[i].keycode;
-                       break;
-               }
-       kfree(key);
-       return 0;
-}
-
-
-static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
-{
-       u8 i, *buf;
-       struct vp702x_device_state *st = d->priv;
-
-       mutex_lock(&st->buf_mutex);
-       buf = st->buf;
-       for (i = 6; i < 12; i++)
-               vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
-
-       memcpy(mac, buf, 6);
-       mutex_unlock(&st->buf_mutex);
-       return 0;
-}
-
-static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       u8 buf[10] = { 0 };
-
-       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
-
-       if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
-                                  buf, 10, 10))
-               return -EIO;
-
-       buf[9] = '\0';
-       info("system string: %s",&buf[1]);
-
-       vp702x_init_pid_filter(adap);
-
-       adap->fe_adap[0].fe = vp702x_fe_attach(adap->dev);
-       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
-
-       return 0;
-}
-
-static struct dvb_usb_device_properties vp702x_properties;
-
-static int vp702x_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct dvb_usb_device *d;
-       struct vp702x_device_state *st;
-       int ret;
-
-       ret = dvb_usb_device_init(intf, &vp702x_properties,
-                                  THIS_MODULE, &d, adapter_nr);
-       if (ret)
-               goto out;
-
-       st = d->priv;
-       st->buf_len = 16;
-       st->buf = kmalloc(st->buf_len, GFP_KERNEL);
-       if (!st->buf) {
-               ret = -ENOMEM;
-               dvb_usb_device_exit(intf);
-               goto out;
-       }
-       mutex_init(&st->buf_mutex);
-
-out:
-       return ret;
-
-}
-
-static void vp702x_usb_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       struct vp702x_device_state *st = d->priv;
-       mutex_lock(&st->buf_mutex);
-       kfree(st->buf);
-       mutex_unlock(&st->buf_mutex);
-       dvb_usb_device_exit(intf);
-}
-
-static struct usb_device_id vp702x_usb_table [] = {
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
-//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
-//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
-           { 0 },
-};
-MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
-
-static struct dvb_usb_device_properties vp702x_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware            = "dvb-usb-vp702x-02.fw",
-       .no_reconnect        = 1,
-
-       .size_of_priv     = sizeof(struct vp702x_device_state),
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .caps             = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
-
-                       .streaming_ctrl   = vp702x_streaming_ctrl,
-                       .frontend_attach  = vp702x_frontend_attach,
-
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 10,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-                       .size_of_priv     = sizeof(struct vp702x_adapter_state),
-               }
-       },
-       .read_mac_address = vp702x_read_mac_addr,
-
-       .rc.legacy = {
-               .rc_map_table       = rc_map_vp702x_table,
-               .rc_map_size  = ARRAY_SIZE(rc_map_vp702x_table),
-               .rc_interval      = 400,
-               .rc_query         = vp702x_rc_query,
-       },
-
-       .num_device_descs = 1,
-       .devices = {
-               { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
-                 .cold_ids = { &vp702x_usb_table[0], NULL },
-                 .warm_ids = { NULL },
-               },
-/*             { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
-                 .cold_ids = { &vp702x_usb_table[2], NULL },
-                 .warm_ids = { &vp702x_usb_table[3], NULL },
-               },
-*/             { NULL },
-       }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver vp702x_usb_driver = {
-       .name           = "dvb_usb_vp702x",
-       .probe          = vp702x_usb_probe,
-       .disconnect     = vp702x_usb_disconnect,
-       .id_table       = vp702x_usb_table,
-};
-
-module_usb_driver(vp702x_usb_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
deleted file mode 100644 (file)
index 20b9005..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef _DVB_USB_VP7021_H_
-#define _DVB_USB_VP7021_H_
-
-#define DVB_USB_LOG_PREFIX "vp702x"
-#include "dvb-usb.h"
-
-extern int dvb_usb_vp702x_debug;
-#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
-#define deb_rc(args...)   dprintk(dvb_usb_vp702x_debug,0x04,args)
-#define deb_fe(args...)   dprintk(dvb_usb_vp702x_debug,0x08,args)
-
-/* commands are read and written with USB control messages */
-
-/* consecutive read/write operation */
-#define REQUEST_OUT            0xB2
-#define REQUEST_IN             0xB3
-
-/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
- * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
- * the returning buffer looks as follows
- * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
-
-#define GET_TUNER_STATUS       0x05
-/* additional in buffer:
- * 0   1   2    3              4   5   6               7       8
- * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
-
-#define GET_SYSTEM_STRING      0x06
-/* additional in buffer:
- * 0   1   2   3   4   5   6   7   8
- * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
-
-#define SET_DISEQC_CMD         0x08
-/* additional out buffer:
- * 0    1  2  3  4
- * len  X1 X2 X3 X4
- * additional in buffer:
- * 0   1 2
- * N/A 0 0   b[1] == b[2] == 0 -> success, failure otherwise */
-
-#define SET_LNB_POWER          0x09
-/* additional out buffer:
- * 0    1    2
- * 0x00 0xff 1 = on, 0 = off
- * additional in buffer:
- * 0   1 2
- * N/A 0 0   b[1] == b[2] == 0 -> success failure otherwise */
-
-#define GET_MAC_ADDRESS                0x0A
-/* #define GET_MAC_ADDRESS   0x0B */
-/* additional in buffer:
- * 0   1   2            3    4    5    6    7    8
- * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
-
-#define SET_PID_FILTER         0x11
-/* additional in buffer:
- * 0        1        ... 14       15       16
- * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
-
-/* request: 0xB2; i: 0; v: 0;
- * b[0] != 0 -> tune and lock a channel
- * 0     1     2       3      4      5      6    7
- * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
- */
-
-/* one direction requests */
-#define READ_REMOTE_REQ                0xB4
-/* IN  i: 0; v: 0; b[0] == request, b[1] == key */
-
-#define READ_PID_NUMBER_REQ    0xB5
-/* IN  i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
-
-#define WRITE_EEPROM_REQ       0xB6
-/* OUT i: offset; v: value to write; no extra buffer */
-
-#define READ_EEPROM_REQ                0xB7
-/* IN  i: bufferlen; v: offset; buffer with bufferlen bytes */
-
-#define READ_STATUS            0xB8
-/* IN  i: 0; v: 0; bufferlen 10 */
-
-#define READ_TUNER_REG_REQ     0xB9
-/* IN  i: 0; v: register; b[0] = value */
-
-#define READ_FX2_REG_REQ       0xBA
-/* IN  i: offset; v: 0; b[0] = value */
-
-#define WRITE_FX2_REG_REQ      0xBB
-/* OUT i: offset; v: value to write; 1 byte extra buffer */
-
-#define SET_TUNER_POWER_REQ    0xBC
-/* IN  i: 0 = power off, 1 = power on */
-
-#define WRITE_TUNER_REG_REQ    0xBD
-/* IN  i: register, v: value to write, no extra buffer */
-
-#define RESET_TUNER            0xBE
-/* IN  i: 0, v: 0, no extra buffer */
-
-struct vp702x_device_state {
-       struct mutex buf_mutex;
-       int buf_len;
-       u8 *buf;
-};
-
-
-extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
-
-extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
-extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
deleted file mode 100644 (file)
index b8825b1..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
- * DVB-T receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * Thanks to Twinhan who kindly provided hardware and information.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- */
-#include "vp7045.h"
-
-/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
- *
- * Programming is hidden inside the firmware, so set_frontend is very easy.
- * Even though there is a Firmware command that one can use to access the demod
- * via its registers. This is used for status information.
- */
-
-struct vp7045_fe_state {
-       struct dvb_frontend fe;
-       struct dvb_usb_device *d;
-};
-
-static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       u8 s0 = vp7045_read_reg(state->d,0x00),
-          s1 = vp7045_read_reg(state->d,0x01),
-          s3 = vp7045_read_reg(state->d,0x03);
-
-       *status = 0;
-       if (s0 & (1 << 4))
-               *status |= FE_HAS_CARRIER;
-       if (s0 & (1 << 1))
-               *status |= FE_HAS_VITERBI;
-       if (s0 & (1 << 5))
-               *status |= FE_HAS_LOCK;
-       if (s1 & (1 << 1))
-               *status |= FE_HAS_SYNC;
-       if (s3 & (1 << 6))
-               *status |= FE_HAS_SIGNAL;
-
-       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
-                       (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
-               *status &= ~FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
-              (vp7045_read_reg(state->d, 0x0E) << 8) |
-               vp7045_read_reg(state->d, 0x0F);
-       return 0;
-}
-
-static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
-                   vp7045_read_reg(state->d, 0x11);
-       return 0;
-}
-
-static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
-               vp7045_read_reg(state->d, 0x15);
-
-       *strength = ~signal;
-       return 0;
-}
-
-static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       u8 _snr = vp7045_read_reg(state->d, 0x09);
-       *snr = (_snr << 8) | _snr;
-       return 0;
-}
-
-static int vp7045_fe_init(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int vp7045_fe_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 800;
-       return 0;
-}
-
-static int vp7045_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       u8 buf[5];
-       u32 freq = fep->frequency / 1000;
-
-       buf[0] = (freq >> 16) & 0xff;
-       buf[1] = (freq >>  8) & 0xff;
-       buf[2] =  freq        & 0xff;
-       buf[3] = 0;
-
-       switch (fep->bandwidth_hz) {
-       case 8000000:
-               buf[4] = 8;
-               break;
-       case 7000000:
-               buf[4] = 7;
-               break;
-       case 6000000:
-               buf[4] = 6;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
-       return 0;
-}
-
-static void vp7045_fe_release(struct dvb_frontend* fe)
-{
-       struct vp7045_fe_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops vp7045_fe_ops;
-
-struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
-{
-       struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
-       if (s == NULL)
-               goto error;
-
-       s->d = d;
-       memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
-       s->fe.demodulator_priv = s;
-
-       return &s->fe;
-error:
-       return NULL;
-}
-
-
-static struct dvb_frontend_ops vp7045_fe_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Twinhan VP7045/46 USB DVB-T",
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 1000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                               FE_CAN_TRANSMISSION_MODE_AUTO |
-                               FE_CAN_GUARD_INTERVAL_AUTO |
-                               FE_CAN_RECOVER |
-                               FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = vp7045_fe_release,
-
-       .init = vp7045_fe_init,
-       .sleep = vp7045_fe_sleep,
-
-       .set_frontend = vp7045_fe_set_frontend,
-       .get_tune_settings = vp7045_fe_get_tune_settings,
-
-       .read_status = vp7045_fe_read_status,
-       .read_ber = vp7045_fe_read_ber,
-       .read_signal_strength = vp7045_fe_read_signal_strength,
-       .read_snr = vp7045_fe_read_snr,
-       .read_ucblocks = vp7045_fe_read_unc_blocks,
-};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
deleted file mode 100644 (file)
index d750724..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* DVB USB compliant Linux driver for the
- *  - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
- *  - DigitalNow TinyUSB2 DVB-t receiver
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * Thanks to Twinhan who kindly provided hardware and information.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#include "vp7045.h"
-
-/* debug */
-static int dvb_usb_vp7045_debug;
-module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
-#define deb_rc(args...)   dprintk(dvb_usb_vp7045_debug,0x04,args)
-
-int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
-{
-       int ret = 0;
-       u8 *buf = d->priv;
-
-       buf[0] = cmd;
-
-       if (outlen > 19)
-               outlen = 19;
-
-       if (inlen > 11)
-               inlen = 11;
-
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-       if (ret)
-               return ret;
-
-       if (out != NULL && outlen > 0)
-               memcpy(&buf[1], out, outlen);
-
-       deb_xfer("out buffer: ");
-       debug_dump(buf, outlen+1, deb_xfer);
-
-
-       if (usb_control_msg(d->udev,
-                       usb_sndctrlpipe(d->udev,0),
-                       TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
-                       buf, 20, 2000) != 20) {
-               err("USB control message 'out' went wrong.");
-               ret = -EIO;
-               goto unlock;
-       }
-
-       msleep(msec);
-
-       if (usb_control_msg(d->udev,
-                       usb_rcvctrlpipe(d->udev,0),
-                       TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-                       buf, 12, 2000) != 12) {
-               err("USB control message 'in' went wrong.");
-               ret = -EIO;
-               goto unlock;
-       }
-
-       deb_xfer("in buffer: ");
-       debug_dump(buf, 12, deb_xfer);
-
-       if (in != NULL && inlen > 0)
-               memcpy(in, &buf[1], inlen);
-
-unlock:
-       mutex_unlock(&d->usb_mutex);
-
-       return ret;
-}
-
-u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
-{
-       u8 obuf[2] = { 0 },v;
-       obuf[1] = reg;
-
-       vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
-
-       return v;
-}
-
-static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       u8 v = onoff;
-       return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
-}
-
-/* remote control stuff */
-
-/* The keymapping struct. Somehow this should be loaded to the driver, but
- * currently it is hardcoded. */
-static struct rc_map_table rc_map_vp7045_table[] = {
-       { 0x0016, KEY_POWER },
-       { 0x0010, KEY_MUTE },
-       { 0x0003, KEY_1 },
-       { 0x0001, KEY_2 },
-       { 0x0006, KEY_3 },
-       { 0x0009, KEY_4 },
-       { 0x001d, KEY_5 },
-       { 0x001f, KEY_6 },
-       { 0x000d, KEY_7 },
-       { 0x0019, KEY_8 },
-       { 0x001b, KEY_9 },
-       { 0x0015, KEY_0 },
-       { 0x0005, KEY_CHANNELUP },
-       { 0x0002, KEY_CHANNELDOWN },
-       { 0x001e, KEY_VOLUMEUP },
-       { 0x000a, KEY_VOLUMEDOWN },
-       { 0x0011, KEY_RECORD },
-       { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
-       { 0x0014, KEY_PLAY },
-       { 0x001a, KEY_STOP },
-       { 0x0040, KEY_REWIND },
-       { 0x0012, KEY_FASTFORWARD },
-       { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
-       { 0x004c, KEY_PAUSE },
-       { 0x004d, KEY_SCREEN }, /* Full screen mode. */
-       { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
-       { 0x000c, KEY_CANCEL }, /* Cancel */
-       { 0x001c, KEY_EPG }, /* EPG */
-       { 0x0000, KEY_TAB }, /* Tab */
-       { 0x0048, KEY_INFO }, /* Preview */
-       { 0x0004, KEY_LIST }, /* RecordList */
-       { 0x000f, KEY_TEXT }, /* Teletext */
-       { 0x0041, KEY_PREVIOUSSONG },
-       { 0x0042, KEY_NEXTSONG },
-       { 0x004b, KEY_UP },
-       { 0x0051, KEY_DOWN },
-       { 0x004e, KEY_LEFT },
-       { 0x0052, KEY_RIGHT },
-       { 0x004f, KEY_ENTER },
-       { 0x0013, KEY_CANCEL },
-       { 0x004a, KEY_CLEAR },
-       { 0x0054, KEY_PRINT }, /* Capture */
-       { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
-       { 0x0008, KEY_VIDEO }, /* A/V */
-       { 0x0007, KEY_SLEEP }, /* Hibernate */
-       { 0x0045, KEY_ZOOM }, /* Zoom+ */
-       { 0x0018, KEY_RED},
-       { 0x0053, KEY_GREEN},
-       { 0x005e, KEY_YELLOW},
-       { 0x005f, KEY_BLUE}
-};
-
-static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
-{
-       u8 key;
-       int i;
-       vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
-
-       deb_rc("remote query key: %x %d\n",key,key);
-
-       if (key == 0x44) {
-               *state = REMOTE_NO_KEY_PRESSED;
-               return 0;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
-               if (rc5_data(&rc_map_vp7045_table[i]) == key) {
-                       *state = REMOTE_KEY_PRESSED;
-                       *event = rc_map_vp7045_table[i].keycode;
-                       break;
-               }
-       return 0;
-}
-
-static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
-{
-       int i = 0;
-       u8 v,br[2];
-       for (i=0; i < len; i++) {
-               v = offset + i;
-               vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
-               buf[i] = br[1];
-       }
-       deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
-       debug_dump(buf,i,deb_info);
-       return 0;
-}
-
-static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
-{
-       return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
-}
-
-static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       u8 buf[255] = { 0 };
-
-       vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
-       buf[10] = '\0';
-       deb_info("firmware says: %s ",buf);
-
-       vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
-       buf[10] = '\0';
-       deb_info("%s ",buf);
-
-       vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
-       buf[10] = '\0';
-       deb_info("v%s\n",buf);
-
-/*     Dump the EEPROM */
-/*     vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
-
-       adap->fe_adap[0].fe = vp7045_fe_attach(adap->dev);
-
-       return 0;
-}
-
-static struct dvb_usb_device_properties vp7045_properties;
-
-static int vp7045_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       return dvb_usb_device_init(intf, &vp7045_properties,
-                                  THIS_MODULE, NULL, adapter_nr);
-}
-
-static struct usb_device_id vp7045_usb_table [] = {
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
-           { 0 },
-};
-MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
-
-static struct dvb_usb_device_properties vp7045_properties = {
-       .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-vp7045-01.fw",
-       .size_of_priv = 20,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-               .num_frontends = 1,
-               .fe = {{
-                       .frontend_attach  = vp7045_frontend_attach,
-                       /* parameter for the MPEG2-data transfer */
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 7,
-                               .endpoint = 0x02,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = 4096,
-                                       }
-                               }
-                       },
-               }},
-               }
-       },
-       .power_ctrl       = vp7045_power_ctrl,
-       .read_mac_address = vp7045_read_mac_addr,
-
-       .rc.legacy = {
-               .rc_interval      = 400,
-               .rc_map_table       = rc_map_vp7045_table,
-               .rc_map_size  = ARRAY_SIZE(rc_map_vp7045_table),
-               .rc_query         = vp7045_rc_query,
-       },
-
-       .num_device_descs = 2,
-       .devices = {
-               { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
-                 .cold_ids = { &vp7045_usb_table[0], NULL },
-                 .warm_ids = { &vp7045_usb_table[1], NULL },
-               },
-               { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
-                 .cold_ids = { &vp7045_usb_table[2], NULL },
-                 .warm_ids = { &vp7045_usb_table[3], NULL },
-               },
-               { NULL },
-       }
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver vp7045_usb_driver = {
-       .name           = "dvb_usb_vp7045",
-       .probe          = vp7045_usb_probe,
-       .disconnect     = dvb_usb_device_exit,
-       .id_table       = vp7045_usb_table,
-};
-
-module_usb_driver(vp7045_usb_driver);
-
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
deleted file mode 100644 (file)
index cf5ec46..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
- * USB2.0 DVB-T receiver.
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * Thanks to Twinhan who kindly provided hardware and information.
- *
- *     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, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-#ifndef _DVB_USB_VP7045_H_
-#define _DVB_USB_VP7045_H_
-
-#define DVB_USB_LOG_PREFIX "vp7045"
-#include "dvb-usb.h"
-
-/* vp7045 commands */
-
-/* Twinhan Vendor requests */
-#define TH_COMMAND_IN                     0xC0
-#define TH_COMMAND_OUT                    0xC1
-
-/* command bytes */
-#define TUNER_REG_READ                    0x03
-#define TUNER_REG_WRITE                   0x04
-
-#define RC_VAL_READ                       0x05
- #define RC_NO_KEY                        0x44
-
-#define SET_TUNER_POWER                   0x06
-#define CHECK_TUNER_POWER                 0x12
- #define Tuner_Power_ON                   1
- #define Tuner_Power_OFF                  0
-
-#define GET_USB_SPEED                     0x07
-
-#define LOCK_TUNER_COMMAND                0x09
-
-#define TUNER_SIGNAL_READ                 0x0A
-
-/* FX2 eeprom */
-#define SET_EE_VALUE                      0x10
-#define GET_EE_VALUE                      0x11
- #define FX2_ID_ADDR                      0x00
- #define VID_MSB_ADDR                     0x02
- #define VID_LSB_ADDR                     0x01
- #define PID_MSB_ADDR                     0x04
- #define PID_LSB_ADDR                     0x03
- #define MAC_0_ADDR                       0x07
- #define MAC_1_ADDR                       0x08
- #define MAC_2_ADDR                       0x09
- #define MAC_3_ADDR                       0x0a
- #define MAC_4_ADDR                       0x0b
- #define MAC_5_ADDR                       0x0c
-
-#define RESET_FX2                         0x13
-
-#define FW_VERSION_READ                   0x0B
-#define VENDOR_STRING_READ                0x0C
-#define PRODUCT_STRING_READ               0x0D
-#define FW_BCD_VERSION_READ               0x14
-
-extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
-extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
-extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
-
-#endif
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
deleted file mode 100644 (file)
index bc6456e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Siano Mobile Silicon Digital TV device configuration
-#
-
-config SMS_SIANO_MDTV
-       tristate "Siano SMS1xxx based MDTV receiver"
-       depends on DVB_CORE && RC_CORE && HAS_DMA
-       ---help---
-         Choose Y or M here if you have MDTV receiver with a Siano chipset.
-
-         To compile this driver as a module, choose M here
-         (The module will be called smsmdtv).
-
-         Further documentation on this driver can be found on the WWW
-         at http://www.siano-ms.com/
-
-if SMS_SIANO_MDTV
-menu "Siano module components"
-
-# Hardware interfaces support
-
-config SMS_USB_DRV
-       tristate "USB interface support"
-       depends on DVB_CORE && USB
-       ---help---
-         Choose if you would like to have Siano's support for USB interface
-
-config SMS_SDIO_DRV
-       tristate "SDIO interface support"
-       depends on DVB_CORE && MMC
-       ---help---
-         Choose if you would like to have Siano's support for SDIO interface
-endmenu
-endif # SMS_SIANO_MDTV
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
deleted file mode 100644 (file)
index 14756bd..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-
-smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
-
-obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
-obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
-obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
-
-ccflags-y += -Idrivers/media/dvb-core
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
-
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
deleted file mode 100644 (file)
index 680c781..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- *  Card-specific functions for the Siano SMS1xxx USB dongle
- *
- *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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 "sms-cards.h"
-#include "smsir.h"
-#include <linux/module.h>
-
-static int sms_dbg;
-module_param_named(cards_dbg, sms_dbg, int, 0644);
-MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
-
-static struct sms_board sms_boards[] = {
-       [SMS_BOARD_UNKNOWN] = {
-               .name   = "Unknown board",
-       },
-       [SMS1XXX_BOARD_SIANO_STELLAR] = {
-               .name   = "Siano Stellar Digital Receiver",
-               .type   = SMS_STELLAR,
-       },
-       [SMS1XXX_BOARD_SIANO_NOVA_A] = {
-               .name   = "Siano Nova A Digital Receiver",
-               .type   = SMS_NOVA_A0,
-       },
-       [SMS1XXX_BOARD_SIANO_NOVA_B] = {
-               .name   = "Siano Nova B Digital Receiver",
-               .type   = SMS_NOVA_B0,
-       },
-       [SMS1XXX_BOARD_SIANO_VEGA] = {
-               .name   = "Siano Vega Digital Receiver",
-               .type   = SMS_VEGA,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
-               .name   = "Hauppauge Catamount",
-               .type   = SMS_STELLAR,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
-               .name   = "Hauppauge Okemo-A",
-               .type   = SMS_NOVA_A0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
-               .name   = "Hauppauge Okemo-B",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
-               .name   = "Hauppauge WinTV MiniStick",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .rc_codes = RC_MAP_HAUPPAUGE,
-               .board_cfg.leds_power = 26,
-               .board_cfg.led0 = 27,
-               .board_cfg.led1 = 28,
-               .board_cfg.ir = 9,
-               .led_power = 26,
-               .led_lo    = 27,
-               .led_hi    = 28,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
-               .name   = "Hauppauge WinTV MiniCard",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .lna_ctrl  = 29,
-               .board_cfg.foreign_lna0_ctrl = 29,
-               .rf_switch = 17,
-               .board_cfg.rf_switch_uhf = 17,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
-               .name   = "Hauppauge WinTV MiniCard",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .lna_ctrl  = -1,
-       },
-       [SMS1XXX_BOARD_SIANO_NICE] = {
-       /* 11 */
-               .name = "Siano Nice Digital Receiver",
-               .type = SMS_NOVA_B0,
-       },
-       [SMS1XXX_BOARD_SIANO_VENICE] = {
-       /* 12 */
-               .name = "Siano Venice Digital Receiver",
-               .type = SMS_VEGA,
-       },
-};
-
-struct sms_board *sms_get_board(unsigned id)
-{
-       BUG_ON(id >= ARRAY_SIZE(sms_boards));
-
-       return &sms_boards[id];
-}
-EXPORT_SYMBOL_GPL(sms_get_board);
-static inline void sms_gpio_assign_11xx_default_led_config(
-               struct smscore_gpio_config *pGpioConfig) {
-       pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
-       pGpioConfig->InputCharacteristics =
-               SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
-       pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
-       pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
-       pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
-}
-
-int sms_board_event(struct smscore_device_t *coredev,
-               enum SMS_BOARD_EVENTS gevent) {
-       struct smscore_gpio_config MyGpioConfig;
-
-       sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
-
-       switch (gevent) {
-       case BOARD_EVENT_POWER_INIT: /* including hotplug */
-               break; /* BOARD_EVENT_BIND */
-
-       case BOARD_EVENT_POWER_SUSPEND:
-               break; /* BOARD_EVENT_POWER_SUSPEND */
-
-       case BOARD_EVENT_POWER_RESUME:
-               break; /* BOARD_EVENT_POWER_RESUME */
-
-       case BOARD_EVENT_BIND:
-               break; /* BOARD_EVENT_BIND */
-
-       case BOARD_EVENT_SCAN_PROG:
-               break; /* BOARD_EVENT_SCAN_PROG */
-       case BOARD_EVENT_SCAN_COMP:
-               break; /* BOARD_EVENT_SCAN_COMP */
-       case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
-               break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
-       case BOARD_EVENT_FE_LOCK:
-               break; /* BOARD_EVENT_FE_LOCK */
-       case BOARD_EVENT_FE_UNLOCK:
-               break; /* BOARD_EVENT_FE_UNLOCK */
-       case BOARD_EVENT_DEMOD_LOCK:
-               break; /* BOARD_EVENT_DEMOD_LOCK */
-       case BOARD_EVENT_DEMOD_UNLOCK:
-               break; /* BOARD_EVENT_DEMOD_UNLOCK */
-       case BOARD_EVENT_RECEPTION_MAX_4:
-               break; /* BOARD_EVENT_RECEPTION_MAX_4 */
-       case BOARD_EVENT_RECEPTION_3:
-               break; /* BOARD_EVENT_RECEPTION_3 */
-       case BOARD_EVENT_RECEPTION_2:
-               break; /* BOARD_EVENT_RECEPTION_2 */
-       case BOARD_EVENT_RECEPTION_1:
-               break; /* BOARD_EVENT_RECEPTION_1 */
-       case BOARD_EVENT_RECEPTION_LOST_0:
-               break; /* BOARD_EVENT_RECEPTION_LOST_0 */
-       case BOARD_EVENT_MULTIPLEX_OK:
-               break; /* BOARD_EVENT_MULTIPLEX_OK */
-       case BOARD_EVENT_MULTIPLEX_ERRORS:
-               break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
-
-       default:
-               sms_err("Unknown SMS board event");
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_event);
-
-static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
-{
-       int lvl, ret;
-       u32 gpio;
-       struct smscore_config_gpio gpioconfig = {
-               .direction            = SMS_GPIO_DIRECTION_OUTPUT,
-               .pullupdown           = SMS_GPIO_PULLUPDOWN_NONE,
-               .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
-               .outputslewrate       = SMS_GPIO_OUTPUTSLEWRATE_FAST,
-               .outputdriving        = SMS_GPIO_OUTPUTDRIVING_4mA,
-       };
-
-       if (pin == 0)
-               return -EINVAL;
-
-       if (pin < 0) {
-               /* inverted gpio */
-               gpio = pin * -1;
-               lvl = enable ? 0 : 1;
-       } else {
-               gpio = pin;
-               lvl = enable ? 1 : 0;
-       }
-
-       ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
-       if (ret < 0)
-               return ret;
-
-       return smscore_set_gpio(coredev, gpio, lvl);
-}
-
-int sms_board_setup(struct smscore_device_t *coredev)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               /* turn off all LEDs */
-               sms_set_gpio(coredev, board->led_power, 0);
-               sms_set_gpio(coredev, board->led_hi, 0);
-               sms_set_gpio(coredev, board->led_lo, 0);
-               break;
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               /* turn off LNA */
-               sms_set_gpio(coredev, board->lna_ctrl, 0);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_setup);
-
-int sms_board_power(struct smscore_device_t *coredev, int onoff)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               /* power LED */
-               sms_set_gpio(coredev,
-                            board->led_power, onoff ? 1 : 0);
-               break;
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               /* LNA */
-               if (!onoff)
-                       sms_set_gpio(coredev, board->lna_ctrl, 0);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_power);
-
-int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       /* dont touch GPIO if LEDs are already set */
-       if (smscore_led_state(coredev, -1) == led)
-               return 0;
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               sms_set_gpio(coredev,
-                            board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
-               sms_set_gpio(coredev,
-                            board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
-
-               smscore_led_state(coredev, led);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_led_feedback);
-
-int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               sms_set_gpio(coredev,
-                            board->rf_switch, onoff ? 1 : 0);
-               return sms_set_gpio(coredev,
-                                   board->lna_ctrl, onoff ? 1 : 0);
-       }
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(sms_board_lna_control);
-
-int sms_board_load_modules(int id)
-{
-       switch (id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
-       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
-       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               request_module("smsdvb");
-               break;
-       default:
-               /* do nothing */
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
deleted file mode 100644 (file)
index d8cdf75..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Card-specific functions for the Siano SMS1xxx USB dongle
- *
- *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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 __SMS_CARDS_H__
-#define __SMS_CARDS_H__
-
-#include <linux/usb.h>
-#include "smscoreapi.h"
-#include "smsir.h"
-
-#define SMS_BOARD_UNKNOWN 0
-#define SMS1XXX_BOARD_SIANO_STELLAR 1
-#define SMS1XXX_BOARD_SIANO_NOVA_A  2
-#define SMS1XXX_BOARD_SIANO_NOVA_B  3
-#define SMS1XXX_BOARD_SIANO_VEGA    4
-#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
-#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
-#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
-#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
-#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
-#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
-#define SMS1XXX_BOARD_SIANO_NICE       11
-#define SMS1XXX_BOARD_SIANO_VENICE     12
-
-struct sms_board_gpio_cfg {
-       int lna_vhf_exist;
-       int lna_vhf_ctrl;
-       int lna_uhf_exist;
-       int lna_uhf_ctrl;
-       int lna_uhf_d_ctrl;
-       int lna_sband_exist;
-       int lna_sband_ctrl;
-       int lna_sband_d_ctrl;
-       int foreign_lna0_ctrl;
-       int foreign_lna1_ctrl;
-       int foreign_lna2_ctrl;
-       int rf_switch_vhf;
-       int rf_switch_uhf;
-       int rf_switch_sband;
-       int leds_power;
-       int led0;
-       int led1;
-       int led2;
-       int led3;
-       int led4;
-       int ir;
-       int eeprom_wp;
-       int mrc_sense;
-       int mrc_pdn_resetn;
-       int mrc_gp0; /* mrcs spi int */
-       int mrc_gp1;
-       int mrc_gp2;
-       int mrc_gp3;
-       int mrc_gp4;
-       int host_spi_gsp_ts_int;
-};
-
-struct sms_board {
-       enum sms_device_type_st type;
-       char *name, *fw[DEVICE_MODE_MAX];
-       struct sms_board_gpio_cfg board_cfg;
-       char *rc_codes;                         /* Name of IR codes table */
-
-       /* gpios */
-       int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
-};
-
-struct sms_board *sms_get_board(unsigned id);
-
-extern struct smscore_device_t *coredev;
-
-enum SMS_BOARD_EVENTS {
-       BOARD_EVENT_POWER_INIT,
-       BOARD_EVENT_POWER_SUSPEND,
-       BOARD_EVENT_POWER_RESUME,
-       BOARD_EVENT_BIND,
-       BOARD_EVENT_SCAN_PROG,
-       BOARD_EVENT_SCAN_COMP,
-       BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
-       BOARD_EVENT_FE_LOCK,
-       BOARD_EVENT_FE_UNLOCK,
-       BOARD_EVENT_DEMOD_LOCK,
-       BOARD_EVENT_DEMOD_UNLOCK,
-       BOARD_EVENT_RECEPTION_MAX_4,
-       BOARD_EVENT_RECEPTION_3,
-       BOARD_EVENT_RECEPTION_2,
-       BOARD_EVENT_RECEPTION_1,
-       BOARD_EVENT_RECEPTION_LOST_0,
-       BOARD_EVENT_MULTIPLEX_OK,
-       BOARD_EVENT_MULTIPLEX_ERRORS
-};
-
-int sms_board_event(struct smscore_device_t *coredev,
-               enum SMS_BOARD_EVENTS gevent);
-
-int sms_board_setup(struct smscore_device_t *coredev);
-
-#define SMS_LED_OFF 0
-#define SMS_LED_LO  1
-#define SMS_LED_HI  2
-int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
-int sms_board_power(struct smscore_device_t *coredev, int onoff);
-int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
-
-extern int sms_board_load_modules(int id);
-
-#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
deleted file mode 100644 (file)
index 9cc5554..0000000
+++ /dev/null
@@ -1,1637 +0,0 @@
-/*
- *  Siano core API module
- *
- *  This file contains implementation for the interface to sms core component
- *
- *  author: Uri Shkolnik
- *
- *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <linux/firmware.h>
-#include <linux/wait.h>
-#include <asm/byteorder.h>
-
-#include "smscoreapi.h"
-#include "sms-cards.h"
-#include "smsir.h"
-#include "smsendian.h"
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-struct smscore_device_notifyee_t {
-       struct list_head entry;
-       hotplug_t hotplug;
-};
-
-struct smscore_idlist_t {
-       struct list_head entry;
-       int             id;
-       int             data_type;
-};
-
-struct smscore_client_t {
-       struct list_head entry;
-       struct smscore_device_t *coredev;
-       void                    *context;
-       struct list_head        idlist;
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-};
-
-void smscore_set_board_id(struct smscore_device_t *core, int id)
-{
-       core->board_id = id;
-}
-
-int smscore_led_state(struct smscore_device_t *core, int led)
-{
-       if (led >= 0)
-               core->led_state = led;
-       return core->led_state;
-}
-EXPORT_SYMBOL_GPL(smscore_set_board_id);
-
-int smscore_get_board_id(struct smscore_device_t *core)
-{
-       return core->board_id;
-}
-EXPORT_SYMBOL_GPL(smscore_get_board_id);
-
-struct smscore_registry_entry_t {
-       struct list_head entry;
-       char                    devpath[32];
-       int                             mode;
-       enum sms_device_type_st type;
-};
-
-static struct list_head g_smscore_notifyees;
-static struct list_head g_smscore_devices;
-static struct mutex g_smscore_deviceslock;
-
-static struct list_head g_smscore_registry;
-static struct mutex g_smscore_registrylock;
-
-static int default_mode = 4;
-
-module_param(default_mode, int, 0644);
-MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
-
-static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-       struct list_head *next;
-
-       kmutex_lock(&g_smscore_registrylock);
-       for (next = g_smscore_registry.next;
-            next != &g_smscore_registry;
-            next = next->next) {
-               entry = (struct smscore_registry_entry_t *) next;
-               if (!strcmp(entry->devpath, devpath)) {
-                       kmutex_unlock(&g_smscore_registrylock);
-                       return entry;
-               }
-       }
-       entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
-       if (entry) {
-               entry->mode = default_mode;
-               strcpy(entry->devpath, devpath);
-               list_add(&entry->entry, &g_smscore_registry);
-       } else
-               sms_err("failed to create smscore_registry.");
-       kmutex_unlock(&g_smscore_registrylock);
-       return entry;
-}
-
-int smscore_registry_getmode(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               return entry->mode;
-       else
-               sms_err("No registry found.");
-
-       return default_mode;
-}
-EXPORT_SYMBOL_GPL(smscore_registry_getmode);
-
-static enum sms_device_type_st smscore_registry_gettype(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               return entry->type;
-       else
-               sms_err("No registry found.");
-
-       return -1;
-}
-
-void smscore_registry_setmode(char *devpath, int mode)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               entry->mode = mode;
-       else
-               sms_err("No registry found.");
-}
-
-static void smscore_registry_settype(char *devpath,
-                                    enum sms_device_type_st type)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               entry->type = type;
-       else
-               sms_err("No registry found.");
-}
-
-
-static void list_add_locked(struct list_head *new, struct list_head *head,
-                           spinlock_t *lock)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(lock, flags);
-
-       list_add(new, head);
-
-       spin_unlock_irqrestore(lock, flags);
-}
-
-/**
- * register a client callback that called when device plugged in/unplugged
- * NOTE: if devices exist callback is called immediately for each device
- *
- * @param hotplug callback
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_hotplug(hotplug_t hotplug)
-{
-       struct smscore_device_notifyee_t *notifyee;
-       struct list_head *next, *first;
-       int rc = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
-                          GFP_KERNEL);
-       if (notifyee) {
-               /* now notify callback about existing devices */
-               first = &g_smscore_devices;
-               for (next = first->next;
-                    next != first && !rc;
-                    next = next->next) {
-                       struct smscore_device_t *coredev =
-                               (struct smscore_device_t *) next;
-                       rc = hotplug(coredev, coredev->device, 1);
-               }
-
-               if (rc >= 0) {
-                       notifyee->hotplug = hotplug;
-                       list_add(&notifyee->entry, &g_smscore_notifyees);
-               } else
-                       kfree(notifyee);
-       } else
-               rc = -ENOMEM;
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-EXPORT_SYMBOL_GPL(smscore_register_hotplug);
-
-/**
- * unregister a client callback that called when device plugged in/unplugged
- *
- * @param hotplug callback
- *
- */
-void smscore_unregister_hotplug(hotplug_t hotplug)
-{
-       struct list_head *next, *first;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       first = &g_smscore_notifyees;
-
-       for (next = first->next; next != first;) {
-               struct smscore_device_notifyee_t *notifyee =
-                       (struct smscore_device_notifyee_t *) next;
-               next = next->next;
-
-               if (notifyee->hotplug == hotplug) {
-                       list_del(&notifyee->entry);
-                       kfree(notifyee);
-               }
-       }
-
-       kmutex_unlock(&g_smscore_deviceslock);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
-
-static void smscore_notify_clients(struct smscore_device_t *coredev)
-{
-       struct smscore_client_t *client;
-
-       /* the client must call smscore_unregister_client from remove handler */
-       while (!list_empty(&coredev->clients)) {
-               client = (struct smscore_client_t *) coredev->clients.next;
-               client->onremove_handler(client->context);
-       }
-}
-
-static int smscore_notify_callbacks(struct smscore_device_t *coredev,
-                                   struct device *device, int arrival)
-{
-       struct smscore_device_notifyee_t *elem;
-       int rc = 0;
-
-       /* note: must be called under g_deviceslock */
-
-       list_for_each_entry(elem, &g_smscore_notifyees, entry) {
-               rc = elem->hotplug(coredev, device, arrival);
-               if (rc < 0)
-                       break;
-       }
-
-       return rc;
-}
-
-static struct
-smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
-                                      dma_addr_t common_buffer_phys)
-{
-       struct smscore_buffer_t *cb =
-               kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
-       if (!cb) {
-               sms_info("kmalloc(...) failed");
-               return NULL;
-       }
-
-       cb->p = buffer;
-       cb->offset_in_common = buffer - (u8 *) common_buffer;
-       cb->phys = common_buffer_phys + cb->offset_in_common;
-
-       return cb;
-}
-
-/**
- * creates coredev object for a device, prepares buffers,
- * creates buffer mappings, notifies registered hotplugs about new device.
- *
- * @param params device pointer to struct with device specific parameters
- *               and handlers
- * @param coredev pointer to a value that receives created coredev object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_device(struct smsdevice_params_t *params,
-                           struct smscore_device_t **coredev)
-{
-       struct smscore_device_t *dev;
-       u8 *buffer;
-
-       dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
-       if (!dev) {
-               sms_info("kzalloc(...) failed");
-               return -ENOMEM;
-       }
-
-       /* init list entry so it could be safe in smscore_unregister_device */
-       INIT_LIST_HEAD(&dev->entry);
-
-       /* init queues */
-       INIT_LIST_HEAD(&dev->clients);
-       INIT_LIST_HEAD(&dev->buffers);
-
-       /* init locks */
-       spin_lock_init(&dev->clientslock);
-       spin_lock_init(&dev->bufferslock);
-
-       /* init completion events */
-       init_completion(&dev->version_ex_done);
-       init_completion(&dev->data_download_done);
-       init_completion(&dev->trigger_done);
-       init_completion(&dev->init_device_done);
-       init_completion(&dev->reload_start_done);
-       init_completion(&dev->resume_done);
-       init_completion(&dev->gpio_configuration_done);
-       init_completion(&dev->gpio_set_level_done);
-       init_completion(&dev->gpio_get_level_done);
-       init_completion(&dev->ir_init_done);
-
-       /* Buffer management */
-       init_waitqueue_head(&dev->buffer_mng_waitq);
-
-       /* alloc common buffer */
-       dev->common_buffer_size = params->buffer_size * params->num_buffers;
-       dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
-                                               &dev->common_buffer_phys,
-                                               GFP_KERNEL | GFP_DMA);
-       if (!dev->common_buffer) {
-               smscore_unregister_device(dev);
-               return -ENOMEM;
-       }
-
-       /* prepare dma buffers */
-       for (buffer = dev->common_buffer;
-            dev->num_buffers < params->num_buffers;
-            dev->num_buffers++, buffer += params->buffer_size) {
-               struct smscore_buffer_t *cb =
-                       smscore_createbuffer(buffer, dev->common_buffer,
-                                            dev->common_buffer_phys);
-               if (!cb) {
-                       smscore_unregister_device(dev);
-                       return -ENOMEM;
-               }
-
-               smscore_putbuffer(dev, cb);
-       }
-
-       sms_info("allocated %d buffers", dev->num_buffers);
-
-       dev->mode = DEVICE_MODE_NONE;
-       dev->context = params->context;
-       dev->device = params->device;
-       dev->setmode_handler = params->setmode_handler;
-       dev->detectmode_handler = params->detectmode_handler;
-       dev->sendrequest_handler = params->sendrequest_handler;
-       dev->preload_handler = params->preload_handler;
-       dev->postload_handler = params->postload_handler;
-
-       dev->device_flags = params->flags;
-       strcpy(dev->devpath, params->devpath);
-
-       smscore_registry_settype(dev->devpath, params->device_type);
-
-       /* add device to devices list */
-       kmutex_lock(&g_smscore_deviceslock);
-       list_add(&dev->entry, &g_smscore_devices);
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       *coredev = dev;
-
-       sms_info("device %p created", dev);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(smscore_register_device);
-
-
-static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
-               void *buffer, size_t size, struct completion *completion) {
-       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
-       if (rc < 0) {
-               sms_info("sendrequest returned error %d", rc);
-               return rc;
-       }
-
-       return wait_for_completion_timeout(completion,
-                       msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
-                       0 : -ETIME;
-}
-
-/**
- * Starts & enables IR operations
- *
- * @return 0 on success, < 0 on error.
- */
-static int smscore_init_ir(struct smscore_device_t *coredev)
-{
-       int ir_io;
-       int rc;
-       void *buffer;
-
-       coredev->ir.dev = NULL;
-       ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
-       if (ir_io) {/* only if IR port exist we use IR sub-module */
-               sms_info("IR loading");
-               rc = sms_ir_init(coredev);
-
-               if      (rc != 0)
-                       sms_err("Error initialization DTV IR sub-module");
-               else {
-                       buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
-                                               SMS_DMA_ALIGNMENT,
-                                               GFP_KERNEL | GFP_DMA);
-                       if (buffer) {
-                               struct SmsMsgData_ST2 *msg =
-                               (struct SmsMsgData_ST2 *)
-                               SMS_ALIGN_ADDRESS(buffer);
-
-                               SMS_INIT_MSG(&msg->xMsgHeader,
-                                               MSG_SMS_START_IR_REQ,
-                                               sizeof(struct SmsMsgData_ST2));
-                               msg->msgData[0] = coredev->ir.controller;
-                               msg->msgData[1] = coredev->ir.timeout;
-
-                               smsendian_handle_tx_message(
-                                       (struct SmsMsgHdr_ST2 *)msg);
-                               rc = smscore_sendrequest_and_wait(coredev, msg,
-                                               msg->xMsgHeader. msgLength,
-                                               &coredev->ir_init_done);
-
-                               kfree(buffer);
-                       } else
-                               sms_err
-                               ("Sending IR initialization message failed");
-               }
-       } else
-               sms_info("IR port has not been detected");
-
-       return 0;
-}
-
-/**
- * sets initial device mode and notifies client hotplugs that device is ready
- *
- * @param coredev pointer to a coredev object returned by
- *               smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_start_device(struct smscore_device_t *coredev)
-{
-       int rc = smscore_set_device_mode(
-                       coredev, smscore_registry_getmode(coredev->devpath));
-       if (rc < 0) {
-               sms_info("set device mode faile , rc %d", rc);
-               return rc;
-       }
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
-       smscore_init_ir(coredev);
-
-       sms_info("device %p started, rc %d", coredev, rc);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-EXPORT_SYMBOL_GPL(smscore_start_device);
-
-
-static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
-                                        void *buffer, size_t size)
-{
-       struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
-       struct SmsMsgHdr_ST *msg;
-       u32 mem_address;
-       u8 *payload = firmware->Payload;
-       int rc = 0;
-       firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
-       firmware->Length = le32_to_cpu(firmware->Length);
-
-       mem_address = firmware->StartAddress;
-
-       sms_info("loading FW to addr 0x%x size %d",
-                mem_address, firmware->Length);
-       if (coredev->preload_handler) {
-               rc = coredev->preload_handler(coredev->context);
-               if (rc < 0)
-                       return rc;
-       }
-
-       /* PAGE_SIZE buffer shall be enough and dma aligned */
-       msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
-       if (!msg)
-               return -ENOMEM;
-
-       if (coredev->mode != DEVICE_MODE_NONE) {
-               sms_debug("sending reload command.");
-               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
-                            sizeof(struct SmsMsgHdr_ST));
-               rc = smscore_sendrequest_and_wait(coredev, msg,
-                                                 msg->msgLength,
-                                                 &coredev->reload_start_done);
-               mem_address = *(u32 *) &payload[20];
-       }
-
-       while (size && rc >= 0) {
-               struct SmsDataDownload_ST *DataMsg =
-                       (struct SmsDataDownload_ST *) msg;
-               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
-
-               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
-                            (u16)(sizeof(struct SmsMsgHdr_ST) +
-                                     sizeof(u32) + payload_size));
-
-               DataMsg->MemAddr = mem_address;
-               memcpy(DataMsg->Payload, payload, payload_size);
-
-               if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
-                   (coredev->mode == DEVICE_MODE_NONE))
-                       rc = coredev->sendrequest_handler(
-                               coredev->context, DataMsg,
-                               DataMsg->xMsgHeader.msgLength);
-               else
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, DataMsg,
-                               DataMsg->xMsgHeader.msgLength,
-                               &coredev->data_download_done);
-
-               payload += payload_size;
-               size -= payload_size;
-               mem_address += payload_size;
-       }
-
-       if (rc >= 0) {
-               if (coredev->mode == DEVICE_MODE_NONE) {
-                       struct SmsMsgData_ST *TriggerMsg =
-                               (struct SmsMsgData_ST *) msg;
-
-                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
-                                    sizeof(struct SmsMsgHdr_ST) +
-                                    sizeof(u32) * 5);
-
-                       TriggerMsg->msgData[0] = firmware->StartAddress;
-                                               /* Entry point */
-                       TriggerMsg->msgData[1] = 5; /* Priority */
-                       TriggerMsg->msgData[2] = 0x200; /* Stack size */
-                       TriggerMsg->msgData[3] = 0; /* Parameter */
-                       TriggerMsg->msgData[4] = 4; /* Task ID */
-
-                       if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
-                               rc = coredev->sendrequest_handler(
-                                       coredev->context, TriggerMsg,
-                                       TriggerMsg->xMsgHeader.msgLength);
-                               msleep(100);
-                       } else
-                               rc = smscore_sendrequest_and_wait(
-                                       coredev, TriggerMsg,
-                                       TriggerMsg->xMsgHeader.msgLength,
-                                       &coredev->trigger_done);
-               } else {
-                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
-                                    sizeof(struct SmsMsgHdr_ST));
-
-                       rc = coredev->sendrequest_handler(coredev->context,
-                                                         msg, msg->msgLength);
-               }
-               msleep(500);
-       }
-
-       sms_debug("rc=%d, postload=%p ", rc,
-                 coredev->postload_handler);
-
-       kfree(msg);
-
-       return ((rc >= 0) && coredev->postload_handler) ?
-               coredev->postload_handler(coredev->context) :
-               rc;
-}
-
-/**
- * loads specified firmware into a buffer and calls device loadfirmware_handler
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param filename null-terminated string specifies firmware file name
- * @param loadfirmware_handler device handler that loads firmware
- *
- * @return 0 on success, <0 on error.
- */
-static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
-                                          char *filename,
-                                          loadfirmware_t loadfirmware_handler)
-{
-       int rc = -ENOENT;
-       const struct firmware *fw;
-       u8 *fw_buffer;
-
-       if (loadfirmware_handler == NULL && !(coredev->device_flags &
-                                             SMS_DEVICE_FAMILY2))
-               return -EINVAL;
-
-       rc = request_firmware(&fw, filename, coredev->device);
-       if (rc < 0) {
-               sms_info("failed to open \"%s\"", filename);
-               return rc;
-       }
-       sms_info("read FW %s, size=%zd", filename, fw->size);
-       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
-                           GFP_KERNEL | GFP_DMA);
-       if (fw_buffer) {
-               memcpy(fw_buffer, fw->data, fw->size);
-
-               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-                     smscore_load_firmware_family2(coredev,
-                                                   fw_buffer,
-                                                   fw->size) :
-                     loadfirmware_handler(coredev->context,
-                                          fw_buffer, fw->size);
-
-               kfree(fw_buffer);
-       } else {
-               sms_info("failed to allocate firmware buffer");
-               rc = -ENOMEM;
-       }
-
-       release_firmware(fw);
-
-       return rc;
-}
-
-/**
- * notifies all clients registered with the device, notifies hotplugs,
- * frees all buffers and coredev object
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-void smscore_unregister_device(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb;
-       int num_buffers = 0;
-       int retry = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       /* Release input device (IR) resources */
-       sms_ir_exit(coredev);
-
-       smscore_notify_clients(coredev);
-       smscore_notify_callbacks(coredev, NULL, 0);
-
-       /* at this point all buffers should be back
-        * onresponse must no longer be called */
-
-       while (1) {
-               while (!list_empty(&coredev->buffers)) {
-                       cb = (struct smscore_buffer_t *) coredev->buffers.next;
-                       list_del(&cb->entry);
-                       kfree(cb);
-                       num_buffers++;
-               }
-               if (num_buffers == coredev->num_buffers)
-                       break;
-               if (++retry > 10) {
-                       sms_info("exiting although "
-                                "not all buffers released.");
-                       break;
-               }
-
-               sms_info("waiting for %d buffer(s)",
-                        coredev->num_buffers - num_buffers);
-               msleep(100);
-       }
-
-       sms_info("freed %d buffers", num_buffers);
-
-       if (coredev->common_buffer)
-               dma_free_coherent(NULL, coredev->common_buffer_size,
-                       coredev->common_buffer, coredev->common_buffer_phys);
-
-       if (coredev->fw_buf != NULL)
-               kfree(coredev->fw_buf);
-
-       list_del(&coredev->entry);
-       kfree(coredev);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       sms_info("device %p destroyed", coredev);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_device);
-
-static int smscore_detect_mode(struct smscore_device_t *coredev)
-{
-       void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
-                              GFP_KERNEL | GFP_DMA);
-       struct SmsMsgHdr_ST *msg =
-               (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
-       int rc;
-
-       if (!buffer)
-               return -ENOMEM;
-
-       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
-                    sizeof(struct SmsMsgHdr_ST));
-
-       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
-                                         &coredev->version_ex_done);
-       if (rc == -ETIME) {
-               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
-
-               if (wait_for_completion_timeout(&coredev->resume_done,
-                                               msecs_to_jiffies(5000))) {
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, msg, msg->msgLength,
-                               &coredev->version_ex_done);
-                       if (rc < 0)
-                               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
-                                       "second try, rc %d", rc);
-               } else
-                       rc = -ETIME;
-       }
-
-       kfree(buffer);
-
-       return rc;
-}
-
-static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
-       /*Stellar               NOVA A0         Nova B0         VEGA*/
-       /*DVBT*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*DVBH*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*TDMB*/
-       {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
-       /*DABIP*/
-       {"none", "none", "none", "none"},
-       /*BDA*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*ISDBT*/
-       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
-       /*ISDBTBDA*/
-       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
-       /*CMMB*/
-       {"none", "none", "none", "cmmb_vega_12mhz.inp"}
-};
-
-static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
-                                   int mode, enum sms_device_type_st type)
-{
-       char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
-       return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
-}
-
-/**
- * calls device handler to change mode of operation
- * NOTE: stellar/usb may disconnect when changing mode
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param mode requested mode of operation
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
-{
-       void *buffer;
-       int rc = 0;
-       enum sms_device_type_st type;
-
-       sms_debug("set device mode to %d", mode);
-       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
-                       sms_err("invalid mode specified %d", mode);
-                       return -EINVAL;
-               }
-
-               smscore_registry_setmode(coredev->devpath, mode);
-
-               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
-                       rc = smscore_detect_mode(coredev);
-                       if (rc < 0) {
-                               sms_err("mode detect failed %d", rc);
-                               return rc;
-                       }
-               }
-
-               if (coredev->mode == mode) {
-                       sms_info("device mode %d already set", mode);
-                       return 0;
-               }
-
-               if (!(coredev->modes_supported & (1 << mode))) {
-                       char *fw_filename;
-
-                       type = smscore_registry_gettype(coredev->devpath);
-                       fw_filename = sms_get_fw_name(coredev, mode, type);
-
-                       rc = smscore_load_firmware_from_file(coredev,
-                                                            fw_filename, NULL);
-                       if (rc < 0) {
-                               sms_warn("error %d loading firmware: %s, "
-                                        "trying again with default firmware",
-                                        rc, fw_filename);
-
-                               /* try again with the default firmware */
-                               fw_filename = smscore_fw_lkup[mode][type];
-                               rc = smscore_load_firmware_from_file(coredev,
-                                                            fw_filename, NULL);
-
-                               if (rc < 0) {
-                                       sms_warn("error %d loading "
-                                                "firmware: %s", rc,
-                                                fw_filename);
-                                       return rc;
-                               }
-                       }
-                       sms_log("firmware download success: %s", fw_filename);
-               } else
-                       sms_info("mode %d supported by running "
-                                "firmware", mode);
-
-               buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
-                                SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
-               if (buffer) {
-                       struct SmsMsgData_ST *msg =
-                               (struct SmsMsgData_ST *)
-                                       SMS_ALIGN_ADDRESS(buffer);
-
-                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
-                                    sizeof(struct SmsMsgData_ST));
-                       msg->msgData[0] = mode;
-
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, msg, msg->xMsgHeader.msgLength,
-                               &coredev->init_device_done);
-
-                       kfree(buffer);
-               } else {
-                       sms_err("Could not allocate buffer for "
-                               "init device message.");
-                       rc = -ENOMEM;
-               }
-       } else {
-               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
-                       sms_err("invalid mode specified %d", mode);
-                       return -EINVAL;
-               }
-
-               smscore_registry_setmode(coredev->devpath, mode);
-
-               if (coredev->detectmode_handler)
-                       coredev->detectmode_handler(coredev->context,
-                                                   &coredev->mode);
-
-               if (coredev->mode != mode && coredev->setmode_handler)
-                       rc = coredev->setmode_handler(coredev->context, mode);
-       }
-
-       if (rc >= 0) {
-               coredev->mode = mode;
-               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
-       }
-
-       if (rc < 0)
-               sms_err("return error code %d.", rc);
-       return rc;
-}
-
-/**
- * calls device handler to get current mode of operation
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return current mode
- */
-int smscore_get_device_mode(struct smscore_device_t *coredev)
-{
-       return coredev->mode;
-}
-EXPORT_SYMBOL_GPL(smscore_get_device_mode);
-
-/**
- * find client by response id & type within the clients list.
- * return client handle or NULL.
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param data_type client data type (SMS_DONT_CARE for all types)
- * @param id client id (SMS_DONT_CARE for all id)
- *
- */
-static struct
-smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
-                                     int data_type, int id)
-{
-       struct list_head *first;
-       struct smscore_client_t *client;
-       unsigned long flags;
-       struct list_head *firstid;
-       struct smscore_idlist_t *client_id;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-       first = &coredev->clients;
-       list_for_each_entry(client, first, entry) {
-               firstid = &client->idlist;
-               list_for_each_entry(client_id, firstid, entry) {
-                       if ((client_id->id == id) &&
-                           (client_id->data_type == data_type ||
-                           (client_id->data_type == 0)))
-                               goto found;
-               }
-       }
-       client = NULL;
-found:
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-       return client;
-}
-
-/**
- * find client by response id/type, call clients onresponse handler
- * return buffer to pool on error
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param cb pointer to response buffer descriptor
- *
- */
-void smscore_onresponse(struct smscore_device_t *coredev,
-               struct smscore_buffer_t *cb) {
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
-                       + cb->offset);
-       struct smscore_client_t *client;
-       int rc = -EBUSY;
-       static unsigned long last_sample_time; /* = 0; */
-       static int data_total; /* = 0; */
-       unsigned long time_now = jiffies_to_msecs(jiffies);
-
-       if (!last_sample_time)
-               last_sample_time = time_now;
-
-       if (time_now - last_sample_time > 10000) {
-               sms_debug("\ndata rate %d bytes/secs",
-                         (int)((data_total * 1000) /
-                               (time_now - last_sample_time)));
-
-               last_sample_time = time_now;
-               data_total = 0;
-       }
-
-       data_total += cb->size;
-       /* Do we need to re-route? */
-       if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
-                       (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
-               if (coredev->mode == DEVICE_MODE_DVBT_BDA)
-                       phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
-       }
-
-
-       client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
-
-       /* If no client registered for type & id,
-        * check for control client where type is not registered */
-       if (client)
-               rc = client->onresponse_handler(client->context, cb);
-
-       if (rc < 0) {
-               switch (phdr->msgType) {
-               case MSG_SMS_GET_VERSION_EX_RES:
-               {
-                       struct SmsVersionRes_ST *ver =
-                               (struct SmsVersionRes_ST *) phdr;
-                       sms_debug("MSG_SMS_GET_VERSION_EX_RES "
-                                 "id %d prots 0x%x ver %d.%d",
-                                 ver->FirmwareId, ver->SupportedProtocols,
-                                 ver->RomVersionMajor, ver->RomVersionMinor);
-
-                       coredev->mode = ver->FirmwareId == 255 ?
-                               DEVICE_MODE_NONE : ver->FirmwareId;
-                       coredev->modes_supported = ver->SupportedProtocols;
-
-                       complete(&coredev->version_ex_done);
-                       break;
-               }
-               case MSG_SMS_INIT_DEVICE_RES:
-                       sms_debug("MSG_SMS_INIT_DEVICE_RES");
-                       complete(&coredev->init_device_done);
-                       break;
-               case MSG_SW_RELOAD_START_RES:
-                       sms_debug("MSG_SW_RELOAD_START_RES");
-                       complete(&coredev->reload_start_done);
-                       break;
-               case MSG_SMS_DATA_DOWNLOAD_RES:
-                       complete(&coredev->data_download_done);
-                       break;
-               case MSG_SW_RELOAD_EXEC_RES:
-                       sms_debug("MSG_SW_RELOAD_EXEC_RES");
-                       break;
-               case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
-                       sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
-                       complete(&coredev->trigger_done);
-                       break;
-               case MSG_SMS_SLEEP_RESUME_COMP_IND:
-                       complete(&coredev->resume_done);
-                       break;
-               case MSG_SMS_GPIO_CONFIG_EX_RES:
-                       sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
-                       complete(&coredev->gpio_configuration_done);
-                       break;
-               case MSG_SMS_GPIO_SET_LEVEL_RES:
-                       sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
-                       complete(&coredev->gpio_set_level_done);
-                       break;
-               case MSG_SMS_GPIO_GET_LEVEL_RES:
-               {
-                       u32 *msgdata = (u32 *) phdr;
-                       coredev->gpio_get_res = msgdata[1];
-                       sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
-                                       coredev->gpio_get_res);
-                       complete(&coredev->gpio_get_level_done);
-                       break;
-               }
-               case MSG_SMS_START_IR_RES:
-                       complete(&coredev->ir_init_done);
-                       break;
-               case MSG_SMS_IR_SAMPLES_IND:
-                       sms_ir_event(coredev,
-                               (const char *)
-                               ((char *)phdr
-                               + sizeof(struct SmsMsgHdr_ST)),
-                               (int)phdr->msgLength
-                               - sizeof(struct SmsMsgHdr_ST));
-                       break;
-
-               default:
-                       break;
-               }
-               smscore_putbuffer(coredev, cb);
-       }
-}
-EXPORT_SYMBOL_GPL(smscore_onresponse);
-
-/**
- * return pointer to next free buffer descriptor from core pool
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return pointer to descriptor on success, NULL on error.
- */
-
-struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->bufferslock, flags);
-       if (!list_empty(&coredev->buffers)) {
-               cb = (struct smscore_buffer_t *) coredev->buffers.next;
-               list_del(&cb->entry);
-       }
-       spin_unlock_irqrestore(&coredev->bufferslock, flags);
-       return cb;
-}
-
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb = NULL;
-
-       wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
-
-       return cb;
-}
-EXPORT_SYMBOL_GPL(smscore_getbuffer);
-
-/**
- * return buffer descriptor to a pool
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param cb pointer buffer descriptor
- *
- */
-void smscore_putbuffer(struct smscore_device_t *coredev,
-               struct smscore_buffer_t *cb) {
-       wake_up_interruptible(&coredev->buffer_mng_waitq);
-       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
-}
-EXPORT_SYMBOL_GPL(smscore_putbuffer);
-
-static int smscore_validate_client(struct smscore_device_t *coredev,
-                                  struct smscore_client_t *client,
-                                  int data_type, int id)
-{
-       struct smscore_idlist_t *listentry;
-       struct smscore_client_t *registered_client;
-
-       if (!client) {
-               sms_err("bad parameter.");
-               return -EINVAL;
-       }
-       registered_client = smscore_find_client(coredev, data_type, id);
-       if (registered_client == client)
-               return 0;
-
-       if (registered_client) {
-               sms_err("The msg ID already registered to another client.");
-               return -EEXIST;
-       }
-       listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
-       if (!listentry) {
-               sms_err("Can't allocate memory for client id.");
-               return -ENOMEM;
-       }
-       listentry->id = id;
-       listentry->data_type = data_type;
-       list_add_locked(&listentry->entry, &client->idlist,
-                       &coredev->clientslock);
-       return 0;
-}
-
-/**
- * creates smsclient object, check that id is taken by another client
- *
- * @param coredev pointer to a coredev object from clients hotplug
- * @param initial_id all messages with this id would be sent to this client
- * @param data_type all messages of this type would be sent to this client
- * @param onresponse_handler client handler that is called to
- *                           process incoming messages
- * @param onremove_handler client handler that is called when device is removed
- * @param context client-specific context
- * @param client pointer to a value that receives created smsclient object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_client(struct smscore_device_t *coredev,
-                           struct smsclient_params_t *params,
-                           struct smscore_client_t **client)
-{
-       struct smscore_client_t *newclient;
-       /* check that no other channel with same parameters exists */
-       if (smscore_find_client(coredev, params->data_type,
-                               params->initial_id)) {
-               sms_err("Client already exist.");
-               return -EEXIST;
-       }
-
-       newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
-       if (!newclient) {
-               sms_err("Failed to allocate memory for client.");
-               return -ENOMEM;
-       }
-
-       INIT_LIST_HEAD(&newclient->idlist);
-       newclient->coredev = coredev;
-       newclient->onresponse_handler = params->onresponse_handler;
-       newclient->onremove_handler = params->onremove_handler;
-       newclient->context = params->context;
-       list_add_locked(&newclient->entry, &coredev->clients,
-                       &coredev->clientslock);
-       smscore_validate_client(coredev, newclient, params->data_type,
-                               params->initial_id);
-       *client = newclient;
-       sms_debug("%p %d %d", params->context, params->data_type,
-                 params->initial_id);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(smscore_register_client);
-
-/**
- * frees smsclient object and all subclients associated with it
- *
- * @param client pointer to smsclient object returned by
- *               smscore_register_client
- *
- */
-void smscore_unregister_client(struct smscore_client_t *client)
-{
-       struct smscore_device_t *coredev = client->coredev;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-
-
-       while (!list_empty(&client->idlist)) {
-               struct smscore_idlist_t *identry =
-                       (struct smscore_idlist_t *) client->idlist.next;
-               list_del(&identry->entry);
-               kfree(identry);
-       }
-
-       sms_info("%p", client->context);
-
-       list_del(&client->entry);
-       kfree(client);
-
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_client);
-
-/**
- * verifies that source id is not taken by another client,
- * calls device handler to send requests to the device
- *
- * @param client pointer to smsclient object returned by
- *               smscore_register_client
- * @param buffer pointer to a request buffer
- * @param size size (in bytes) of request buffer
- *
- * @return 0 on success, <0 on error.
- */
-int smsclient_sendrequest(struct smscore_client_t *client,
-                         void *buffer, size_t size)
-{
-       struct smscore_device_t *coredev;
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
-       int rc;
-
-       if (client == NULL) {
-               sms_err("Got NULL client");
-               return -EINVAL;
-       }
-
-       coredev = client->coredev;
-
-       /* check that no other channel with same id exists */
-       if (coredev == NULL) {
-               sms_err("Got NULL coredev");
-               return -EINVAL;
-       }
-
-       rc = smscore_validate_client(client->coredev, client, 0,
-                                    phdr->msgSrcId);
-       if (rc < 0)
-               return rc;
-
-       return coredev->sendrequest_handler(coredev->context, buffer, size);
-}
-EXPORT_SYMBOL_GPL(smsclient_sendrequest);
-
-
-/* old GPIO managements implementation */
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-                          struct smscore_config_gpio *pinconfig)
-{
-       struct {
-               struct SmsMsgHdr_ST hdr;
-               u32 data[6];
-       } msg;
-
-       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-               msg.hdr.msgDstId = HIF_TASK;
-               msg.hdr.msgFlags = 0;
-               msg.hdr.msgType  = MSG_SMS_GPIO_CONFIG_EX_REQ;
-               msg.hdr.msgLength = sizeof(msg);
-
-               msg.data[0] = pin;
-               msg.data[1] = pinconfig->pullupdown;
-
-               /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
-               msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
-
-               switch (pinconfig->outputdriving) {
-               case SMS_GPIO_OUTPUTDRIVING_16mA:
-                       msg.data[3] = 7; /* Nova - 16mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_12mA:
-                       msg.data[3] = 5; /* Nova - 11mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_8mA:
-                       msg.data[3] = 3; /* Nova - 7mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_4mA:
-               default:
-                       msg.data[3] = 2; /* Nova - 4mA */
-                       break;
-               }
-
-               msg.data[4] = pinconfig->direction;
-               msg.data[5] = 0;
-       } else /* TODO: SMS_DEVICE_FAMILY1 */
-               return -EINVAL;
-
-       return coredev->sendrequest_handler(coredev->context,
-                                           &msg, sizeof(msg));
-}
-
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
-{
-       struct {
-               struct SmsMsgHdr_ST hdr;
-               u32 data[3];
-       } msg;
-
-       if (pin > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       msg.hdr.msgDstId = HIF_TASK;
-       msg.hdr.msgFlags = 0;
-       msg.hdr.msgType  = MSG_SMS_GPIO_SET_LEVEL_REQ;
-       msg.hdr.msgLength = sizeof(msg);
-
-       msg.data[0] = pin;
-       msg.data[1] = level ? 1 : 0;
-       msg.data[2] = 0;
-
-       return coredev->sendrequest_handler(coredev->context,
-                                           &msg, sizeof(msg));
-}
-
-/* new GPIO management implementation */
-static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
-               u32 *pGroupNum, u32 *pGroupCfg) {
-
-       *pGroupCfg = 1;
-
-       if (PinNum <= 1)        {
-               *pTranslatedPinNum = 0;
-               *pGroupNum = 9;
-               *pGroupCfg = 2;
-       } else if (PinNum >= 2 && PinNum <= 6) {
-               *pTranslatedPinNum = 2;
-               *pGroupNum = 0;
-               *pGroupCfg = 2;
-       } else if (PinNum >= 7 && PinNum <= 11) {
-               *pTranslatedPinNum = 7;
-               *pGroupNum = 1;
-       } else if (PinNum >= 12 && PinNum <= 15) {
-               *pTranslatedPinNum = 12;
-               *pGroupNum = 2;
-               *pGroupCfg = 3;
-       } else if (PinNum == 16) {
-               *pTranslatedPinNum = 16;
-               *pGroupNum = 23;
-       } else if (PinNum >= 17 && PinNum <= 24) {
-               *pTranslatedPinNum = 17;
-               *pGroupNum = 3;
-       } else if (PinNum == 25) {
-               *pTranslatedPinNum = 25;
-               *pGroupNum = 6;
-       } else if (PinNum >= 26 && PinNum <= 28) {
-               *pTranslatedPinNum = 26;
-               *pGroupNum = 4;
-       } else if (PinNum == 29) {
-               *pTranslatedPinNum = 29;
-               *pGroupNum = 5;
-               *pGroupCfg = 2;
-       } else if (PinNum == 30) {
-               *pTranslatedPinNum = 30;
-               *pGroupNum = 8;
-       } else if (PinNum == 31) {
-               *pTranslatedPinNum = 31;
-               *pGroupNum = 17;
-       } else
-               return -1;
-
-       *pGroupCfg <<= 24;
-
-       return 0;
-}
-
-int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
-               struct smscore_gpio_config *pGpioConfig) {
-
-       u32 totalLen;
-       u32 TranslatedPinNum = 0;
-       u32 GroupNum = 0;
-       u32 ElectricChar;
-       u32 groupCfg;
-       void *buffer;
-       int rc;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[6];
-       } *pMsg;
-
-
-       if (PinNum > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       if (pGpioConfig == NULL)
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-
-       if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
-               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
-               if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
-                               &groupCfg) != 0) {
-                       rc = -EINVAL;
-                       goto free;
-               }
-
-               pMsg->msgData[1] = TranslatedPinNum;
-               pMsg->msgData[2] = GroupNum;
-               ElectricChar = (pGpioConfig->PullUpDown)
-                               | (pGpioConfig->InputCharacteristics << 2)
-                               | (pGpioConfig->OutputSlewRate << 3)
-                               | (pGpioConfig->OutputDriving << 4);
-               pMsg->msgData[3] = ElectricChar;
-               pMsg->msgData[4] = pGpioConfig->Direction;
-               pMsg->msgData[5] = groupCfg;
-       } else {
-               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
-               pMsg->msgData[1] = pGpioConfig->PullUpDown;
-               pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
-               pMsg->msgData[3] = pGpioConfig->OutputDriving;
-               pMsg->msgData[4] = pGpioConfig->Direction;
-               pMsg->msgData[5] = 0;
-       }
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_configuration_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_configure timeout");
-               else
-                       sms_err("smscore_gpio_configure error");
-       }
-free:
-       kfree(buffer);
-
-       return rc;
-}
-
-int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 NewLevel) {
-
-       u32 totalLen;
-       int rc;
-       void *buffer;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[3]; /* keep it 3 ! */
-       } *pMsg;
-
-       if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) +
-                       (3 * sizeof(u32)); /* keep it 3 ! */
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-       pMsg->msgData[1] = NewLevel;
-
-       /* Send message to SMS */
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_set_level_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_set_level timeout");
-               else
-                       sms_err("smscore_gpio_set_level error");
-       }
-       kfree(buffer);
-
-       return rc;
-}
-
-int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 *level) {
-
-       u32 totalLen;
-       int rc;
-       void *buffer;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[2];
-       } *pMsg;
-
-
-       if (PinNum > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-       pMsg->msgData[1] = 0;
-
-       /* Send message to SMS */
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_get_level_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_get_level timeout");
-               else
-                       sms_err("smscore_gpio_get_level error");
-       }
-       kfree(buffer);
-
-       /* Its a race between other gpio_get_level() and the copy of the single
-        * global 'coredev->gpio_get_res' to  the function's variable 'level'
-        */
-       *level = coredev->gpio_get_res;
-
-       return rc;
-}
-
-static int __init smscore_module_init(void)
-{
-       int rc = 0;
-
-       INIT_LIST_HEAD(&g_smscore_notifyees);
-       INIT_LIST_HEAD(&g_smscore_devices);
-       kmutex_init(&g_smscore_deviceslock);
-
-       INIT_LIST_HEAD(&g_smscore_registry);
-       kmutex_init(&g_smscore_registrylock);
-
-       return rc;
-}
-
-static void __exit smscore_module_exit(void)
-{
-       kmutex_lock(&g_smscore_deviceslock);
-       while (!list_empty(&g_smscore_notifyees)) {
-               struct smscore_device_notifyee_t *notifyee =
-                       (struct smscore_device_notifyee_t *)
-                               g_smscore_notifyees.next;
-
-               list_del(&notifyee->entry);
-               kfree(notifyee);
-       }
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       kmutex_lock(&g_smscore_registrylock);
-       while (!list_empty(&g_smscore_registry)) {
-               struct smscore_registry_entry_t *entry =
-                       (struct smscore_registry_entry_t *)
-                               g_smscore_registry.next;
-
-               list_del(&entry->entry);
-               kfree(entry);
-       }
-       kmutex_unlock(&g_smscore_registrylock);
-
-       sms_debug("");
-}
-
-module_init(smscore_module_init);
-module_exit(smscore_module_exit);
-
-MODULE_DESCRIPTION("Siano MDTV Core module");
-MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
deleted file mode 100644 (file)
index c592ae0..0000000
+++ /dev/null
@@ -1,775 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
-
-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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_CORE_API_H__
-#define __SMS_CORE_API_H__
-
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <linux/timer.h>
-
-#include <asm/page.h>
-
-#include "smsir.h"
-
-#define kmutex_init(_p_) mutex_init(_p_)
-#define kmutex_lock(_p_) mutex_lock(_p_)
-#define kmutex_trylock(_p_) mutex_trylock(_p_)
-#define kmutex_unlock(_p_) mutex_unlock(_p_)
-
-#ifndef min
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS                 (10000)
-#define SMS_ALLOC_ALIGNMENT                            128
-#define SMS_DMA_ALIGNMENT                              16
-#define SMS_ALIGN_ADDRESS(addr) \
-       ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
-
-#define SMS_DEVICE_FAMILY2                             1
-#define SMS_ROM_NO_RESPONSE                            2
-#define SMS_DEVICE_NOT_READY                           0x8000000
-
-enum sms_device_type_st {
-       SMS_STELLAR = 0,
-       SMS_NOVA_A0,
-       SMS_NOVA_B0,
-       SMS_VEGA,
-       SMS_NUM_OF_DEVICE_TYPES
-};
-
-struct smscore_device_t;
-struct smscore_client_t;
-struct smscore_buffer_t;
-
-typedef int (*hotplug_t)(struct smscore_device_t *coredev,
-                        struct device *device, int arrival);
-
-typedef int (*setmode_t)(void *context, int mode);
-typedef void (*detectmode_t)(void *context, int *mode);
-typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
-typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
-typedef int (*preload_t)(void *context);
-typedef int (*postload_t)(void *context);
-
-typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
-typedef void (*onremove_t)(void *context);
-
-struct smscore_buffer_t {
-       /* public members, once passed to clients can be changed freely */
-       struct list_head entry;
-       int size;
-       int offset;
-
-       /* private members, read-only for clients */
-       void *p;
-       dma_addr_t phys;
-       unsigned long offset_in_common;
-};
-
-struct smsdevice_params_t {
-       struct device   *device;
-
-       int                             buffer_size;
-       int                             num_buffers;
-
-       char                    devpath[32];
-       unsigned long   flags;
-
-       setmode_t               setmode_handler;
-       detectmode_t    detectmode_handler;
-       sendrequest_t   sendrequest_handler;
-       preload_t               preload_handler;
-       postload_t              postload_handler;
-
-       void                    *context;
-       enum sms_device_type_st device_type;
-};
-
-struct smsclient_params_t {
-       int                             initial_id;
-       int                             data_type;
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-       void                    *context;
-};
-
-struct smscore_device_t {
-       struct list_head entry;
-
-       struct list_head clients;
-       struct list_head subclients;
-       spinlock_t clientslock;
-
-       struct list_head buffers;
-       spinlock_t bufferslock;
-       int num_buffers;
-
-       void *common_buffer;
-       int common_buffer_size;
-       dma_addr_t common_buffer_phys;
-
-       void *context;
-       struct device *device;
-
-       char devpath[32];
-       unsigned long device_flags;
-
-       setmode_t setmode_handler;
-       detectmode_t detectmode_handler;
-       sendrequest_t sendrequest_handler;
-       preload_t preload_handler;
-       postload_t postload_handler;
-
-       int mode, modes_supported;
-
-       /* host <--> device messages */
-       struct completion version_ex_done, data_download_done, trigger_done;
-       struct completion init_device_done, reload_start_done, resume_done;
-       struct completion gpio_configuration_done, gpio_set_level_done;
-       struct completion gpio_get_level_done, ir_init_done;
-
-       /* Buffer management */
-       wait_queue_head_t buffer_mng_waitq;
-
-       /* GPIO */
-       int gpio_get_res;
-
-       /* Target hardware board */
-       int board_id;
-
-       /* Firmware */
-       u8 *fw_buf;
-       u32 fw_buf_size;
-
-       /* Infrared (IR) */
-       struct ir_t ir;
-
-       int led_state;
-};
-
-/* GPIO definitions for antenna frequency domain control (SMS8021) */
-#define SMS_ANTENNA_GPIO_0                                     1
-#define SMS_ANTENNA_GPIO_1                                     0
-
-#define BW_8_MHZ                                                       0
-#define BW_7_MHZ                                                       1
-#define BW_6_MHZ                                                       2
-#define BW_5_MHZ                                                       3
-#define BW_ISDBT_1SEG                                          4
-#define BW_ISDBT_3SEG                                          5
-
-#define MSG_HDR_FLAG_SPLIT_MSG                         4
-
-#define MAX_GPIO_PIN_NUMBER                                    31
-
-#define HIF_TASK                                                       11
-#define SMS_HOST_LIB                                           150
-#define DVBT_BDA_CONTROL_MSG_ID                                201
-
-#define SMS_MAX_PAYLOAD_SIZE                           240
-#define SMS_TUNE_TIMEOUT                                       500
-
-#define MSG_SMS_GPIO_CONFIG_REQ                                507
-#define MSG_SMS_GPIO_CONFIG_RES                                508
-#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
-#define MSG_SMS_GPIO_SET_LEVEL_RES                     510
-#define MSG_SMS_GPIO_GET_LEVEL_REQ                     511
-#define MSG_SMS_GPIO_GET_LEVEL_RES                     512
-#define MSG_SMS_RF_TUNE_REQ                                    561
-#define MSG_SMS_RF_TUNE_RES                                    562
-#define MSG_SMS_INIT_DEVICE_REQ                                578
-#define MSG_SMS_INIT_DEVICE_RES                                579
-#define MSG_SMS_ADD_PID_FILTER_REQ                     601
-#define MSG_SMS_ADD_PID_FILTER_RES                     602
-#define MSG_SMS_REMOVE_PID_FILTER_REQ                  603
-#define MSG_SMS_REMOVE_PID_FILTER_RES                  604
-#define MSG_SMS_DAB_CHANNEL                            607
-#define MSG_SMS_GET_PID_FILTER_LIST_REQ                        608
-#define MSG_SMS_GET_PID_FILTER_LIST_RES                        609
-#define MSG_SMS_GET_STATISTICS_RES                     616
-#define MSG_SMS_GET_STATISTICS_REQ                     615
-#define MSG_SMS_HO_PER_SLICES_IND                      630
-#define MSG_SMS_SET_ANTENNA_CONFIG_REQ                 651
-#define MSG_SMS_SET_ANTENNA_CONFIG_RES                 652
-#define MSG_SMS_SLEEP_RESUME_COMP_IND                  655
-#define MSG_SMS_DATA_DOWNLOAD_REQ                      660
-#define MSG_SMS_DATA_DOWNLOAD_RES                      661
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ         664
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES         665
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ                666
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES                667
-#define MSG_SMS_GET_VERSION_EX_REQ                     668
-#define MSG_SMS_GET_VERSION_EX_RES                     669
-#define MSG_SMS_SET_CLOCK_OUTPUT_REQ           670
-#define MSG_SMS_I2C_SET_FREQ_REQ                       685
-#define MSG_SMS_GENERIC_I2C_REQ                                687
-#define MSG_SMS_GENERIC_I2C_RES                                688
-#define MSG_SMS_DVBT_BDA_DATA                          693
-#define MSG_SW_RELOAD_REQ                                      697
-#define MSG_SMS_DATA_MSG                                       699
-#define MSG_SW_RELOAD_START_REQ                                702
-#define MSG_SW_RELOAD_START_RES                                703
-#define MSG_SW_RELOAD_EXEC_REQ                         704
-#define MSG_SW_RELOAD_EXEC_RES                         705
-#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
-#define MSG_SMS_GPIO_CONFIG_EX_REQ                     712
-#define MSG_SMS_GPIO_CONFIG_EX_RES                     713
-#define MSG_SMS_ISDBT_TUNE_REQ                         776
-#define MSG_SMS_ISDBT_TUNE_RES                         777
-#define MSG_SMS_TRANSMISSION_IND                       782
-#define MSG_SMS_START_IR_REQ                           800
-#define MSG_SMS_START_IR_RES                           801
-#define MSG_SMS_IR_SAMPLES_IND                         802
-#define MSG_SMS_SIGNAL_DETECTED_IND                    827
-#define MSG_SMS_NO_SIGNAL_IND                          828
-
-#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
-       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
-       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
-} while (0)
-
-#define SMS_INIT_MSG(ptr, type, len) \
-       SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
-
-enum SMS_DVB3_EVENTS {
-       DVB3_EVENT_INIT = 0,
-       DVB3_EVENT_SLEEP,
-       DVB3_EVENT_HOTPLUG,
-       DVB3_EVENT_FE_LOCK,
-       DVB3_EVENT_FE_UNLOCK,
-       DVB3_EVENT_UNC_OK,
-       DVB3_EVENT_UNC_ERR
-};
-
-enum SMS_DEVICE_MODE {
-       DEVICE_MODE_NONE = -1,
-       DEVICE_MODE_DVBT = 0,
-       DEVICE_MODE_DVBH,
-       DEVICE_MODE_DAB_TDMB,
-       DEVICE_MODE_DAB_TDMB_DABIP,
-       DEVICE_MODE_DVBT_BDA,
-       DEVICE_MODE_ISDBT,
-       DEVICE_MODE_ISDBT_BDA,
-       DEVICE_MODE_CMMB,
-       DEVICE_MODE_RAW_TUNER,
-       DEVICE_MODE_MAX,
-};
-
-struct SmsMsgHdr_ST {
-       u16     msgType;
-       u8      msgSrcId;
-       u8      msgDstId;
-       u16     msgLength; /* Length of entire message, including header */
-       u16     msgFlags;
-};
-
-struct SmsMsgData_ST {
-       struct SmsMsgHdr_ST xMsgHeader;
-       u32 msgData[1];
-};
-
-struct SmsMsgData_ST2 {
-       struct SmsMsgHdr_ST xMsgHeader;
-       u32 msgData[2];
-};
-
-struct SmsDataDownload_ST {
-       struct SmsMsgHdr_ST     xMsgHeader;
-       u32                     MemAddr;
-       u8                      Payload[SMS_MAX_PAYLOAD_SIZE];
-};
-
-struct SmsVersionRes_ST {
-       struct SmsMsgHdr_ST     xMsgHeader;
-
-       u16             ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
-       u8              Step; /* 0 - Step A */
-       u8              MetalFix; /* 0 - Metal 0 */
-
-       /* FirmwareId 0xFF if ROM, otherwise the
-        * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
-       u8 FirmwareId;
-       /* SupportedProtocols Bitwise OR combination of
-                                            * supported protocols */
-       u8 SupportedProtocols;
-
-       u8              VersionMajor;
-       u8              VersionMinor;
-       u8              VersionPatch;
-       u8              VersionFieldPatch;
-
-       u8              RomVersionMajor;
-       u8              RomVersionMinor;
-       u8              RomVersionPatch;
-       u8              RomVersionFieldPatch;
-
-       u8              TextLabel[34];
-};
-
-struct SmsFirmware_ST {
-       u32                     CheckSum;
-       u32                     Length;
-       u32                     StartAddress;
-       u8                      Payload[1];
-};
-
-/* Statistics information returned as response for
- * SmsHostApiGetStatistics_Req */
-struct SMSHOSTLIB_STATISTICS_ST {
-       u32 Reserved;           /* Reserved */
-
-       /* Common parameters */
-       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
-
-       /* Reception quality */
-       s32 SNR;                /* dB */
-       u32 BER;                /* Post Viterbi BER [1E-5] */
-       u32 FIB_CRC;            /* CRC errors percentage, valid only for DAB */
-       u32 TS_PER;             /* Transport stream PER,
-       0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
-       u32 MFER;               /* DVB-H frame error rate in percentage,
-       0xFFFFFFFF indicate N/A, valid only for DVB-H */
-       s32 RSSI;               /* dBm */
-       s32 InBandPwr;          /* In band power in dBM */
-       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
-
-       /* Transmission parameters */
-       u32 Frequency;          /* Frequency in Hz */
-       u32 Bandwidth;          /* Bandwidth in MHz, valid only for DVB-T/H */
-       u32 TransmissionMode;   /* Transmission Mode, for DAB modes 1-4,
-       for DVB-T/H FFT mode carriers in Kilos */
-       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
-       valid only for DVB-T/H */
-       u32 GuardInterval;      /* Guard Interval from
-       SMSHOSTLIB_GUARD_INTERVALS_ET,  valid only for DVB-T/H */
-       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
-       valid only for DVB-T/H */
-       u32 LPCodeRate;         /* Low Priority Code Rate from
-       SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
-       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
-       valid only for DVB-T/H */
-       u32 Constellation;      /* Constellation from
-       SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
-
-       /* Burst parameters, valid only for DVB-H */
-       u32 BurstSize;          /* Current burst size in bytes,
-       valid only for DVB-H */
-       u32 BurstDuration;      /* Current burst duration in mSec,
-       valid only for DVB-H */
-       u32 BurstCycleTime;     /* Current burst cycle time in mSec,
-       valid only for DVB-H */
-       u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
-       as calculated by demodulator, valid only for DVB-H */
-       u32 NumOfRows;          /* Number of rows in MPE table,
-       valid only for DVB-H */
-       u32 NumOfPaddCols;      /* Number of padding columns in MPE table,
-       valid only for DVB-H */
-       u32 NumOfPunctCols;     /* Number of puncturing columns in MPE table,
-       valid only for DVB-H */
-       u32 ErrorTSPackets;     /* Number of erroneous
-       transport-stream packets */
-       u32 TotalTSPackets;     /* Total number of transport-stream packets */
-       u32 NumOfValidMpeTlbs;  /* Number of MPE tables which do not include
-       errors after MPE RS decoding */
-       u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
-       after MPE RS decoding */
-       u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
-       corrected by MPE RS decoding */
-       /* Common params */
-       u32 BERErrorCount;      /* Number of errornous SYNC bits. */
-       u32 BERBitCount;        /* Total number of SYNC bits. */
-
-       /* Interface information */
-       u32 SmsToHostTxErrors;  /* Total number of transmission errors. */
-
-       /* DAB/T-DMB */
-       u32 PreBER;             /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
-
-       /* DVB-H TPS parameters */
-       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-        if set to 0xFFFFFFFF cell_id not yet recovered */
-       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
-       Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
-       Time Slicing indicator, bit 0 - MPE-FEC indicator */
-
-       u32 NumMPEReceived;     /* DVB-H, Num MPE section received */
-
-       u32 ReservedFields[10]; /* Reserved */
-};
-
-struct SmsMsgStatisticsInfo_ST {
-       u32 RequestResult;
-
-       struct SMSHOSTLIB_STATISTICS_ST Stat;
-
-       /* Split the calc of the SNR in DAB */
-       u32 Signal; /* dB */
-       u32 Noise; /* dB */
-
-};
-
-struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
-       /* Per-layer information */
-       u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
-                      * 255 means layer does not exist */
-       u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
-                           * 255 means layer does not exist */
-       u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-       u32 BERErrorCount; /* Post Viterbi Error Bits Count */
-       u32 BERBitCount; /* Post Viterbi Total Bits Count */
-       u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-       u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
-       u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
-       u32 TotalTSPackets; /* Total number of transport-stream packets */
-       u32 TILdepthI; /* Time interleaver depth I parameter,
-                       * 255 means layer does not exist */
-       u32 NumberOfSegments; /* Number of segments in layer A,
-                              * 255 means layer does not exist */
-       u32 TMCCErrors; /* TMCC errors */
-};
-
-struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
-       u32 StatisticsType; /* Enumerator identifying the type of the
-                               * structure.  Values are the same as
-                               * SMSHOSTLIB_DEVICE_MODES_E
-                               *
-                               * This field MUST always be first in any
-                               * statistics structure */
-
-       u32 FullSize; /* Total size of the structure returned by the modem.
-                      * If the size requested by the host is smaller than
-                      * FullSize, the struct will be truncated */
-
-       /* Common parameters */
-       u32 IsRfLocked; /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
-
-       /* Reception quality */
-       s32  SNR; /* dB */
-       s32  RSSI; /* dBm */
-       s32  InBandPwr; /* In band power in dBM */
-       s32  CarrierOffset; /* Carrier Offset in Hz */
-
-       /* Transmission parameters */
-       u32 Frequency; /* Frequency in Hz */
-       u32 Bandwidth; /* Bandwidth in MHz */
-       u32 TransmissionMode; /* ISDB-T transmission mode */
-       u32 ModemState; /* 0 - Acquisition, 1 - Locked */
-       u32 GuardInterval; /* Guard Interval, 1 divided by value */
-       u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
-       u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
-       u32 NumOfLayers; /* Number of ISDB-T layers in the network */
-
-       /* Per-layer information */
-       /* Layers A, B and C */
-       struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST   LayerInfo[3];
-       /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
-
-       /* Interface information */
-       u32 SmsToHostTxErrors; /* Total number of transmission errors. */
-};
-
-struct PID_STATISTICS_DATA_S {
-       struct PID_BURST_S {
-               u32 size;
-               u32 padding_cols;
-               u32 punct_cols;
-               u32 duration;
-               u32 cycle;
-               u32 calc_cycle;
-       } burst;
-
-       u32 tot_tbl_cnt;
-       u32 invalid_tbl_cnt;
-       u32 tot_cor_tbl;
-};
-
-struct PID_DATA_S {
-       u32 pid;
-       u32 num_rows;
-       struct PID_STATISTICS_DATA_S pid_statistics;
-};
-
-#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
-#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
-#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
-       if (_stat.TransmissionMode == 0) \
-               _stat.TransmissionMode = 2; \
-       else if (_stat.TransmissionMode == 1) \
-               _stat.TransmissionMode = 8; \
-               else \
-                       _stat.TransmissionMode = 4;
-
-struct TRANSMISSION_STATISTICS_S {
-       u32 Frequency;          /* Frequency in Hz */
-       u32 Bandwidth;          /* Bandwidth in MHz */
-       u32 TransmissionMode;   /* FFT mode carriers in Kilos */
-       u32 GuardInterval;      /* Guard Interval from
-       SMSHOSTLIB_GUARD_INTERVALS_ET */
-       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
-       u32 LPCodeRate;         /* Low Priority Code Rate from
-       SMSHOSTLIB_CODE_RATE_ET */
-       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
-       u32 Constellation;      /* Constellation from
-       SMSHOSTLIB_CONSTELLATION_ET */
-
-       /* DVB-H TPS parameters */
-       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-        if set to 0xFFFFFFFF cell_id not yet recovered */
-       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
-        Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
-        Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-};
-
-struct RECEPTION_STATISTICS_S {
-       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
-
-       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
-       s32 SNR;                /* dB */
-       u32 BER;                /* Post Viterbi BER [1E-5] */
-       u32 BERErrorCount;      /* Number of erronous SYNC bits. */
-       u32 BERBitCount;        /* Total number of SYNC bits. */
-       u32 TS_PER;             /* Transport stream PER,
-       0xFFFFFFFF indicate N/A */
-       u32 MFER;               /* DVB-H frame error rate in percentage,
-       0xFFFFFFFF indicate N/A, valid only for DVB-H */
-       s32 RSSI;               /* dBm */
-       s32 InBandPwr;          /* In band power in dBM */
-       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
-       u32 ErrorTSPackets;     /* Number of erroneous
-       transport-stream packets */
-       u32 TotalTSPackets;     /* Total number of transport-stream packets */
-
-       s32 MRC_SNR;            /* dB */
-       s32 MRC_RSSI;           /* dBm */
-       s32 MRC_InBandPwr;      /* In band power in dBM */
-};
-
-
-/* Statistics information returned as response for
- * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
-struct SMSHOSTLIB_STATISTICS_DVB_S {
-       /* Reception */
-       struct RECEPTION_STATISTICS_S ReceptionData;
-
-       /* Transmission parameters */
-       struct TRANSMISSION_STATISTICS_S TransmissionData;
-
-       /* Burst parameters, valid only for DVB-H */
-#define        SRVM_MAX_PID_FILTERS 8
-       struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
-};
-
-struct SRVM_SIGNAL_STATUS_S {
-       u32 result;
-       u32 snr;
-       u32 tsPackets;
-       u32 etsPackets;
-       u32 constellation;
-       u32 hpCode;
-       u32 tpsSrvIndLP;
-       u32 tpsSrvIndHP;
-       u32 cellId;
-       u32 reason;
-
-       s32 inBandPower;
-       u32 requestId;
-};
-
-struct SMSHOSTLIB_I2C_REQ_ST {
-       u32     DeviceAddress; /* I2c device address */
-       u32     WriteCount; /* number of bytes to write */
-       u32     ReadCount; /* number of bytes to read */
-       u8      Data[1];
-};
-
-struct SMSHOSTLIB_I2C_RES_ST {
-       u32     Status; /* non-zero value in case of failure */
-       u32     ReadCount; /* number of bytes read */
-       u8      Data[1];
-};
-
-
-struct smscore_config_gpio {
-#define SMS_GPIO_DIRECTION_INPUT  0
-#define SMS_GPIO_DIRECTION_OUTPUT 1
-       u8 direction;
-
-#define SMS_GPIO_PULLUPDOWN_NONE     0
-#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
-#define SMS_GPIO_PULLUPDOWN_PULLUP   2
-#define SMS_GPIO_PULLUPDOWN_KEEPER   3
-       u8 pullupdown;
-
-#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL  0
-#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
-       u8 inputcharacteristics;
-
-#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
-#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
-       u8 outputslewrate;
-
-#define SMS_GPIO_OUTPUTDRIVING_4mA  0
-#define SMS_GPIO_OUTPUTDRIVING_8mA  1
-#define SMS_GPIO_OUTPUTDRIVING_12mA 2
-#define SMS_GPIO_OUTPUTDRIVING_16mA 3
-       u8 outputdriving;
-};
-
-struct smscore_gpio_config {
-#define SMS_GPIO_DIRECTION_INPUT  0
-#define SMS_GPIO_DIRECTION_OUTPUT 1
-       u8 Direction;
-
-#define SMS_GPIO_PULL_UP_DOWN_NONE     0
-#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
-#define SMS_GPIO_PULL_UP_DOWN_PULLUP   2
-#define SMS_GPIO_PULL_UP_DOWN_KEEPER   3
-       u8 PullUpDown;
-
-#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL  0
-#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
-       u8 InputCharacteristics;
-
-#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW         1 /* 10xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST         0 /* 10xx */
-
-
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS    0 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS     1 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS     2 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS     3 /* 11xx */
-       u8 OutputSlewRate;
-
-#define SMS_GPIO_OUTPUT_DRIVING_S_4mA          0 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_8mA          1 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_12mA         2 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_16mA         3 /* 10xx */
-
-#define SMS_GPIO_OUTPUT_DRIVING_1_5mA          0 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_2_8mA          1 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_4mA            2 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_7mA            3 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_10mA           4 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_11mA           5 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_14mA           6 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_16mA           7 /* 11xx */
-       u8 OutputDriving;
-};
-
-extern void smscore_registry_setmode(char *devpath, int mode);
-extern int smscore_registry_getmode(char *devpath);
-
-extern int smscore_register_hotplug(hotplug_t hotplug);
-extern void smscore_unregister_hotplug(hotplug_t hotplug);
-
-extern int smscore_register_device(struct smsdevice_params_t *params,
-                                  struct smscore_device_t **coredev);
-extern void smscore_unregister_device(struct smscore_device_t *coredev);
-
-extern int smscore_start_device(struct smscore_device_t *coredev);
-extern int smscore_load_firmware(struct smscore_device_t *coredev,
-                                char *filename,
-                                loadfirmware_t loadfirmware_handler);
-
-extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
-extern int smscore_get_device_mode(struct smscore_device_t *coredev);
-
-extern int smscore_register_client(struct smscore_device_t *coredev,
-                                   struct smsclient_params_t *params,
-                                   struct smscore_client_t **client);
-extern void smscore_unregister_client(struct smscore_client_t *client);
-
-extern int smsclient_sendrequest(struct smscore_client_t *client,
-                                void *buffer, size_t size);
-extern void smscore_onresponse(struct smscore_device_t *coredev,
-                              struct smscore_buffer_t *cb);
-
-extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
-extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
-                                     struct vm_area_struct *vma);
-extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
-                                  int mode, char *filename);
-extern int smscore_send_fw_file(struct smscore_device_t *coredev,
-                               u8 *ufwbuf, int size);
-
-extern
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
-extern void smscore_putbuffer(struct smscore_device_t *coredev,
-                             struct smscore_buffer_t *cb);
-
-/* old GPIO management */
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-                          struct smscore_config_gpio *pinconfig);
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
-
-/* new GPIO management */
-extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
-               struct smscore_gpio_config *pGpioConfig);
-extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 NewLevel);
-extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 *level);
-
-void smscore_set_board_id(struct smscore_device_t *core, int id);
-int smscore_get_board_id(struct smscore_device_t *core);
-
-int smscore_led_state(struct smscore_device_t *core, int led);
-
-
-/* ------------------------------------------------------------------------ */
-
-#define DBG_INFO 1
-#define DBG_ADV  2
-
-#define sms_printk(kern, fmt, arg...) \
-       printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define dprintk(kern, lvl, fmt, arg...) do {\
-       if (sms_dbg & lvl) \
-               sms_printk(kern, fmt, ##arg); } while (0)
-
-#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
-#define sms_err(fmt, arg...) \
-       sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
-#define sms_warn(fmt, arg...)  sms_printk(KERN_WARNING, fmt, ##arg)
-#define sms_info(fmt, arg...) \
-       dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
-#define sms_debug(fmt, arg...) \
-       dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
-
-
-#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
deleted file mode 100644 (file)
index aa77e54..0000000
+++ /dev/null
@@ -1,1078 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2008, Uri Shkolnik
-
-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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-
-#include "smscoreapi.h"
-#include "smsendian.h"
-#include "sms-cards.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct smsdvb_client_t {
-       struct list_head entry;
-
-       struct smscore_device_t *coredev;
-       struct smscore_client_t *smsclient;
-
-       struct dvb_adapter      adapter;
-       struct dvb_demux        demux;
-       struct dmxdev           dmxdev;
-       struct dvb_frontend     frontend;
-
-       fe_status_t             fe_status;
-
-       struct completion       tune_done;
-
-       struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
-       int event_fe_state;
-       int event_unc_state;
-};
-
-static struct list_head g_smsdvb_clients;
-static struct mutex g_smsdvb_clientslock;
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-/* Events that may come from DVB v3 adapter */
-static void sms_board_dvb3_event(struct smsdvb_client_t *client,
-               enum SMS_DVB3_EVENTS event) {
-
-       struct smscore_device_t *coredev = client->coredev;
-       switch (event) {
-       case DVB3_EVENT_INIT:
-               sms_debug("DVB3_EVENT_INIT");
-               sms_board_event(coredev, BOARD_EVENT_BIND);
-               break;
-       case DVB3_EVENT_SLEEP:
-               sms_debug("DVB3_EVENT_SLEEP");
-               sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
-               break;
-       case DVB3_EVENT_HOTPLUG:
-               sms_debug("DVB3_EVENT_HOTPLUG");
-               sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
-               break;
-       case DVB3_EVENT_FE_LOCK:
-               if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
-                       client->event_fe_state = DVB3_EVENT_FE_LOCK;
-                       sms_debug("DVB3_EVENT_FE_LOCK");
-                       sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
-               }
-               break;
-       case DVB3_EVENT_FE_UNLOCK:
-               if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
-                       client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
-                       sms_debug("DVB3_EVENT_FE_UNLOCK");
-                       sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
-               }
-               break;
-       case DVB3_EVENT_UNC_OK:
-               if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
-                       client->event_unc_state = DVB3_EVENT_UNC_OK;
-                       sms_debug("DVB3_EVENT_UNC_OK");
-                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
-               }
-               break;
-       case DVB3_EVENT_UNC_ERR:
-               if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
-                       client->event_unc_state = DVB3_EVENT_UNC_ERR;
-                       sms_debug("DVB3_EVENT_UNC_ERR");
-                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
-               }
-               break;
-
-       default:
-               sms_err("Unknown dvb3 api event");
-               break;
-       }
-}
-
-
-static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
-                                  struct SMSHOSTLIB_STATISTICS_ST *p)
-{
-       if (sms_dbg & 2) {
-               printk(KERN_DEBUG "Reserved = %d", p->Reserved);
-               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
-               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
-               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
-               printk(KERN_DEBUG "SNR = %d", p->SNR);
-               printk(KERN_DEBUG "BER = %d", p->BER);
-               printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
-               printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
-               printk(KERN_DEBUG "MFER = %d", p->MFER);
-               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
-               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
-               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
-               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
-               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
-               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
-               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
-               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
-               printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
-               printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
-               printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
-               printk(KERN_DEBUG "Constellation = %d", p->Constellation);
-               printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
-               printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
-               printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
-               printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
-               printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
-               printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
-               printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
-               printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
-               printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
-               printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
-               printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
-               printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
-               printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
-               printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
-               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
-               printk(KERN_DEBUG "PreBER = %d", p->PreBER);
-               printk(KERN_DEBUG "CellId = %d", p->CellId);
-               printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
-               printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
-               printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
-       }
-
-       pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
-       pReceptionData->SNR = p->SNR;
-       pReceptionData->BER = p->BER;
-       pReceptionData->BERErrorCount = p->BERErrorCount;
-       pReceptionData->InBandPwr = p->InBandPwr;
-       pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
-};
-
-
-static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
-                                   struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
-{
-       int i;
-
-       if (sms_dbg & 2) {
-               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
-               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
-               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
-               printk(KERN_DEBUG "SNR = %d", p->SNR);
-               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
-               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
-               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
-               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
-               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
-               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
-               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
-               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
-               printk(KERN_DEBUG "SystemType = %d", p->SystemType);
-               printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
-               printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
-               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
-
-               for (i = 0; i < 3; i++) {
-                       printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
-                       printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
-                       printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
-                       printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
-                       printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
-                       printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
-                       printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
-                       printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
-                       printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
-                       printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
-                       printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
-                       printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
-               }
-       }
-
-       pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
-       pReceptionData->SNR = p->SNR;
-       pReceptionData->InBandPwr = p->InBandPwr;
-
-       pReceptionData->ErrorTSPackets = 0;
-       pReceptionData->BER = 0;
-       pReceptionData->BERErrorCount = 0;
-       for (i = 0; i < 3; i++) {
-               pReceptionData->BER += p->LayerInfo[i].BER;
-               pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
-               pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
-       }
-}
-
-static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
-{
-       struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
-                       + cb->offset);
-       u32 *pMsgData = (u32 *) phdr + 1;
-       /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
-       bool is_status_update = false;
-
-       smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
-
-       switch (phdr->msgType) {
-       case MSG_SMS_DVBT_BDA_DATA:
-               dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
-                                cb->size - sizeof(struct SmsMsgHdr_ST));
-               break;
-
-       case MSG_SMS_RF_TUNE_RES:
-       case MSG_SMS_ISDBT_TUNE_RES:
-               complete(&client->tune_done);
-               break;
-
-       case MSG_SMS_SIGNAL_DETECTED_IND:
-               sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
-               client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
-               is_status_update = true;
-               break;
-
-       case MSG_SMS_NO_SIGNAL_IND:
-               sms_info("MSG_SMS_NO_SIGNAL_IND");
-               client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
-               is_status_update = true;
-               break;
-
-       case MSG_SMS_TRANSMISSION_IND: {
-               sms_info("MSG_SMS_TRANSMISSION_IND");
-
-               pMsgData++;
-               memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
-                               sizeof(struct TRANSMISSION_STATISTICS_S));
-
-               /* Mo need to correct guard interval
-                * (as opposed to old statistics message).
-                */
-               CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
-               CORRECT_STAT_TRANSMISSON_MODE(
-                               client->sms_stat_dvb.TransmissionData);
-               is_status_update = true;
-               break;
-       }
-       case MSG_SMS_HO_PER_SLICES_IND: {
-               struct RECEPTION_STATISTICS_S *pReceptionData =
-                               &client->sms_stat_dvb.ReceptionData;
-               struct SRVM_SIGNAL_STATUS_S SignalStatusData;
-
-               /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
-               pMsgData++;
-               SignalStatusData.result = pMsgData[0];
-               SignalStatusData.snr = pMsgData[1];
-               SignalStatusData.inBandPower = (s32) pMsgData[2];
-               SignalStatusData.tsPackets = pMsgData[3];
-               SignalStatusData.etsPackets = pMsgData[4];
-               SignalStatusData.constellation = pMsgData[5];
-               SignalStatusData.hpCode = pMsgData[6];
-               SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
-               SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
-               SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
-               SignalStatusData.reason = pMsgData[10];
-               SignalStatusData.requestId = pMsgData[11];
-               pReceptionData->IsRfLocked = pMsgData[16];
-               pReceptionData->IsDemodLocked = pMsgData[17];
-               pReceptionData->ModemState = pMsgData[12];
-               pReceptionData->SNR = pMsgData[1];
-               pReceptionData->BER = pMsgData[13];
-               pReceptionData->RSSI = pMsgData[14];
-               CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
-
-               pReceptionData->InBandPwr = (s32) pMsgData[2];
-               pReceptionData->CarrierOffset = (s32) pMsgData[15];
-               pReceptionData->TotalTSPackets = pMsgData[3];
-               pReceptionData->ErrorTSPackets = pMsgData[4];
-
-               /* TS PER */
-               if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
-                               > 0) {
-                       pReceptionData->TS_PER = (SignalStatusData.etsPackets
-                                       * 100) / (SignalStatusData.tsPackets
-                                       + SignalStatusData.etsPackets);
-               } else {
-                       pReceptionData->TS_PER = 0;
-               }
-
-               pReceptionData->BERBitCount = pMsgData[18];
-               pReceptionData->BERErrorCount = pMsgData[19];
-
-               pReceptionData->MRC_SNR = pMsgData[20];
-               pReceptionData->MRC_InBandPwr = pMsgData[21];
-               pReceptionData->MRC_RSSI = pMsgData[22];
-
-               is_status_update = true;
-               break;
-       }
-       case MSG_SMS_GET_STATISTICS_RES: {
-               union {
-                       struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
-                       struct SmsMsgStatisticsInfo_ST         dvb;
-               } *p = (void *) (phdr + 1);
-               struct RECEPTION_STATISTICS_S *pReceptionData =
-                               &client->sms_stat_dvb.ReceptionData;
-
-               sms_info("MSG_SMS_GET_STATISTICS_RES");
-
-               is_status_update = true;
-
-               switch (smscore_get_device_mode(client->coredev)) {
-               case DEVICE_MODE_ISDBT:
-               case DEVICE_MODE_ISDBT_BDA:
-                       smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
-                       break;
-               default:
-                       smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
-               }
-               if (!pReceptionData->IsDemodLocked) {
-                       pReceptionData->SNR = 0;
-                       pReceptionData->BER = 0;
-                       pReceptionData->BERErrorCount = 0;
-                       pReceptionData->InBandPwr = 0;
-                       pReceptionData->ErrorTSPackets = 0;
-               }
-
-               complete(&client->tune_done);
-               break;
-       }
-       default:
-               sms_info("Unhandled message %d", phdr->msgType);
-
-       }
-       smscore_putbuffer(client->coredev, cb);
-
-       if (is_status_update) {
-               if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
-                       client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
-                               | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-                       sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
-                       if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
-                                       == 0)
-                               sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
-                       else
-                               sms_board_dvb3_event(client,
-                                               DVB3_EVENT_UNC_ERR);
-
-               } else {
-                       if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
-                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
-                       else
-                               client->fe_status = 0;
-                       sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
-               }
-       }
-
-       return 0;
-}
-
-static void smsdvb_unregister_client(struct smsdvb_client_t *client)
-{
-       /* must be called under clientslock */
-
-       list_del(&client->entry);
-
-       smscore_unregister_client(client->smsclient);
-       dvb_unregister_frontend(&client->frontend);
-       dvb_dmxdev_release(&client->dmxdev);
-       dvb_dmx_release(&client->demux);
-       dvb_unregister_adapter(&client->adapter);
-       kfree(client);
-}
-
-static void smsdvb_onremove(void *context)
-{
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       smsdvb_unregister_client((struct smsdvb_client_t *) context);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-static int smsdvb_start_feed(struct dvb_demux_feed *feed)
-{
-       struct smsdvb_client_t *client =
-               container_of(feed->demux, struct smsdvb_client_t, demux);
-       struct SmsMsgData_ST PidMsg;
-
-       sms_debug("add pid %d(%x)",
-                 feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
-       return smsclient_sendrequest(client->smsclient,
-                                    &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct smsdvb_client_t *client =
-               container_of(feed->demux, struct smsdvb_client_t, demux);
-       struct SmsMsgData_ST PidMsg;
-
-       sms_debug("remove pid %d(%x)",
-                 feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
-       return smsclient_sendrequest(client->smsclient,
-                                    &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
-                                       void *buffer, size_t size,
-                                       struct completion *completion)
-{
-       int rc;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
-       rc = smsclient_sendrequest(client->smsclient, buffer, size);
-       if (rc < 0)
-               return rc;
-
-       return wait_for_completion_timeout(completion,
-                                          msecs_to_jiffies(2000)) ?
-                                               0 : -ETIME;
-}
-
-static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
-{
-       int rc;
-       struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
-                                   DVBT_BDA_CONTROL_MSG_ID,
-                                   HIF_TASK,
-                                   sizeof(struct SmsMsgHdr_ST), 0 };
-
-       rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                         &client->tune_done);
-
-       return rc;
-}
-
-static inline int led_feedback(struct smsdvb_client_t *client)
-{
-       if (client->fe_status & FE_HAS_LOCK)
-               return sms_board_led_feedback(client->coredev,
-                       (client->sms_stat_dvb.ReceptionData.BER
-                       == 0) ? SMS_LED_HI : SMS_LED_LO);
-       else
-               return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
-}
-
-static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *stat = client->fe_status;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *ber = client->sms_stat_dvb.ReceptionData.BER;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       int rc;
-
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
-               *strength = 0;
-               else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
-                       *strength = 100;
-               else
-                       *strength =
-                               (client->sms_stat_dvb.ReceptionData.InBandPwr
-                               + 95) * 3 / 2;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *snr = client->sms_stat_dvb.ReceptionData.SNR;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
-                                   struct dvb_frontend_tune_settings *tune)
-{
-       sms_debug("");
-
-       tune->min_delay_ms = 400;
-       tune->step_size = 250000;
-       tune->max_drift = 0;
-       return 0;
-}
-
-static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       struct {
-               struct SmsMsgHdr_ST     Msg;
-               u32             Data[3];
-       } Msg;
-
-       int ret;
-
-       client->fe_status = FE_HAS_SIGNAL;
-       client->event_fe_state = -1;
-       client->event_unc_state = -1;
-       fe->dtv_property_cache.delivery_system = SYS_DVBT;
-
-       Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       Msg.Msg.msgDstId = HIF_TASK;
-       Msg.Msg.msgFlags = 0;
-       Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
-       Msg.Msg.msgLength = sizeof(Msg);
-       Msg.Data[0] = c->frequency;
-       Msg.Data[2] = 12000000;
-
-       sms_info("%s: freq %d band %d", __func__, c->frequency,
-                c->bandwidth_hz);
-
-       switch (c->bandwidth_hz / 1000000) {
-       case 8:
-               Msg.Data[1] = BW_8_MHZ;
-               break;
-       case 7:
-               Msg.Data[1] = BW_7_MHZ;
-               break;
-       case 6:
-               Msg.Data[1] = BW_6_MHZ;
-               break;
-       case 0:
-               return -EOPNOTSUPP;
-       default:
-               return -EINVAL;
-       }
-       /* Disable LNA, if any. An error is returned if no LNA is present */
-       ret = sms_board_lna_control(client->coredev, 0);
-       if (ret == 0) {
-               fe_status_t status;
-
-               /* tune with LNA off at first */
-               ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                                 &client->tune_done);
-
-               smsdvb_read_status(fe, &status);
-
-               if (status & FE_HAS_LOCK)
-                       return ret;
-
-               /* previous tune didn't lock - enable LNA and tune again */
-               sms_board_lna_control(client->coredev, 1);
-       }
-
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                          &client->tune_done);
-}
-
-static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       struct {
-               struct SmsMsgHdr_ST     Msg;
-               u32             Data[4];
-       } Msg;
-
-       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
-
-       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
-       Msg.Msg.msgDstId  = HIF_TASK;
-       Msg.Msg.msgFlags  = 0;
-       Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
-       Msg.Msg.msgLength = sizeof(Msg);
-
-       if (c->isdbt_sb_segment_idx == -1)
-               c->isdbt_sb_segment_idx = 0;
-
-       switch (c->isdbt_sb_segment_count) {
-       case 3:
-               Msg.Data[1] = BW_ISDBT_3SEG;
-               break;
-       case 1:
-               Msg.Data[1] = BW_ISDBT_1SEG;
-               break;
-       case 0: /* AUTO */
-               switch (c->bandwidth_hz / 1000000) {
-               case 8:
-               case 7:
-                       c->isdbt_sb_segment_count = 3;
-                       Msg.Data[1] = BW_ISDBT_3SEG;
-                       break;
-               case 6:
-                       c->isdbt_sb_segment_count = 1;
-                       Msg.Data[1] = BW_ISDBT_1SEG;
-                       break;
-               default: /* Assumes 6 MHZ bw */
-                       c->isdbt_sb_segment_count = 1;
-                       c->bandwidth_hz = 6000;
-                       Msg.Data[1] = BW_ISDBT_1SEG;
-                       break;
-               }
-               break;
-       default:
-               sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
-               return -EINVAL;
-       }
-
-       Msg.Data[0] = c->frequency;
-       Msg.Data[2] = 12000000;
-       Msg.Data[3] = c->isdbt_sb_segment_idx;
-
-       sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
-                c->frequency, c->isdbt_sb_segment_count,
-                c->isdbt_sb_segment_idx);
-
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                          &client->tune_done);
-}
-
-static int smsdvb_set_frontend(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-       struct smscore_device_t *coredev = client->coredev;
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               return smsdvb_dvbt_set_frontend(fe);
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               return smsdvb_isdbt_set_frontend(fe);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int smsdvb_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-       struct smscore_device_t *coredev = client->coredev;
-       struct TRANSMISSION_STATISTICS_S *td =
-               &client->sms_stat_dvb.TransmissionData;
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               fep->frequency = td->Frequency;
-
-               switch (td->Bandwidth) {
-               case 6:
-                       fep->bandwidth_hz = 6000000;
-                       break;
-               case 7:
-                       fep->bandwidth_hz = 7000000;
-                       break;
-               case 8:
-                       fep->bandwidth_hz = 8000000;
-                       break;
-               }
-
-               switch (td->TransmissionMode) {
-               case 2:
-                       fep->transmission_mode = TRANSMISSION_MODE_2K;
-                       break;
-               case 8:
-                       fep->transmission_mode = TRANSMISSION_MODE_8K;
-               }
-
-               switch (td->GuardInterval) {
-               case 0:
-                       fep->guard_interval = GUARD_INTERVAL_1_32;
-                       break;
-               case 1:
-                       fep->guard_interval = GUARD_INTERVAL_1_16;
-                       break;
-               case 2:
-                       fep->guard_interval = GUARD_INTERVAL_1_8;
-                       break;
-               case 3:
-                       fep->guard_interval = GUARD_INTERVAL_1_4;
-                       break;
-               }
-
-               switch (td->CodeRate) {
-               case 0:
-                       fep->code_rate_HP = FEC_1_2;
-                       break;
-               case 1:
-                       fep->code_rate_HP = FEC_2_3;
-                       break;
-               case 2:
-                       fep->code_rate_HP = FEC_3_4;
-                       break;
-               case 3:
-                       fep->code_rate_HP = FEC_5_6;
-                       break;
-               case 4:
-                       fep->code_rate_HP = FEC_7_8;
-                       break;
-               }
-
-               switch (td->LPCodeRate) {
-               case 0:
-                       fep->code_rate_LP = FEC_1_2;
-                       break;
-               case 1:
-                       fep->code_rate_LP = FEC_2_3;
-                       break;
-               case 2:
-                       fep->code_rate_LP = FEC_3_4;
-                       break;
-               case 3:
-                       fep->code_rate_LP = FEC_5_6;
-                       break;
-               case 4:
-                       fep->code_rate_LP = FEC_7_8;
-                       break;
-               }
-
-               switch (td->Constellation) {
-               case 0:
-                       fep->modulation = QPSK;
-                       break;
-               case 1:
-                       fep->modulation = QAM_16;
-                       break;
-               case 2:
-                       fep->modulation = QAM_64;
-                       break;
-               }
-
-               switch (td->Hierarchy) {
-               case 0:
-                       fep->hierarchy = HIERARCHY_NONE;
-                       break;
-               case 1:
-                       fep->hierarchy = HIERARCHY_1;
-                       break;
-               case 2:
-                       fep->hierarchy = HIERARCHY_2;
-                       break;
-               case 3:
-                       fep->hierarchy = HIERARCHY_4;
-                       break;
-               }
-
-               fep->inversion = INVERSION_AUTO;
-               break;
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               fep->frequency = td->Frequency;
-               fep->bandwidth_hz = 6000000;
-               /* todo: retrive the other parameters */
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int smsdvb_init(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       sms_board_power(client->coredev, 1);
-
-       sms_board_dvb3_event(client, DVB3_EVENT_INIT);
-       return 0;
-}
-
-static int smsdvb_sleep(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       sms_board_led_feedback(client->coredev, SMS_LED_OFF);
-       sms_board_power(client->coredev, 0);
-
-       sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
-
-       return 0;
-}
-
-static void smsdvb_release(struct dvb_frontend *fe)
-{
-       /* do nothing */
-}
-
-static struct dvb_frontend_ops smsdvb_fe_ops = {
-       .info = {
-               .name                   = "Siano Mobile Digital MDTV Receiver",
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 250000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = smsdvb_release,
-
-       .set_frontend = smsdvb_set_frontend,
-       .get_frontend = smsdvb_get_frontend,
-       .get_tune_settings = smsdvb_get_tune_settings,
-
-       .read_status = smsdvb_read_status,
-       .read_ber = smsdvb_read_ber,
-       .read_signal_strength = smsdvb_read_signal_strength,
-       .read_snr = smsdvb_read_snr,
-       .read_ucblocks = smsdvb_read_ucblocks,
-
-       .init = smsdvb_init,
-       .sleep = smsdvb_sleep,
-};
-
-static int smsdvb_hotplug(struct smscore_device_t *coredev,
-                         struct device *device, int arrival)
-{
-       struct smsclient_params_t params;
-       struct smsdvb_client_t *client;
-       int rc;
-
-       /* device removal handled by onremove callback */
-       if (!arrival)
-               return 0;
-       client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
-       if (!client) {
-               sms_err("kmalloc() failed");
-               return -ENOMEM;
-       }
-
-       /* register dvb adapter */
-       rc = dvb_register_adapter(&client->adapter,
-                                 sms_get_board(
-                                       smscore_get_board_id(coredev))->name,
-                                 THIS_MODULE, device, adapter_nr);
-       if (rc < 0) {
-               sms_err("dvb_register_adapter() failed %d", rc);
-               goto adapter_error;
-       }
-
-       /* init dvb demux */
-       client->demux.dmx.capabilities = DMX_TS_FILTERING;
-       client->demux.filternum = 32; /* todo: nova ??? */
-       client->demux.feednum = 32;
-       client->demux.start_feed = smsdvb_start_feed;
-       client->demux.stop_feed = smsdvb_stop_feed;
-
-       rc = dvb_dmx_init(&client->demux);
-       if (rc < 0) {
-               sms_err("dvb_dmx_init failed %d", rc);
-               goto dvbdmx_error;
-       }
-
-       /* init dmxdev */
-       client->dmxdev.filternum = 32;
-       client->dmxdev.demux = &client->demux.dmx;
-       client->dmxdev.capabilities = 0;
-
-       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
-       if (rc < 0) {
-               sms_err("dvb_dmxdev_init failed %d", rc);
-               goto dmxdev_error;
-       }
-
-       /* init and register frontend */
-       memcpy(&client->frontend.ops, &smsdvb_fe_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               client->frontend.ops.delsys[0] = SYS_DVBT;
-               break;
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               client->frontend.ops.delsys[0] = SYS_ISDBT;
-               break;
-       }
-
-       rc = dvb_register_frontend(&client->adapter, &client->frontend);
-       if (rc < 0) {
-               sms_err("frontend registration failed %d", rc);
-               goto frontend_error;
-       }
-
-       params.initial_id = 1;
-       params.data_type = MSG_SMS_DVBT_BDA_DATA;
-       params.onresponse_handler = smsdvb_onresponse;
-       params.onremove_handler = smsdvb_onremove;
-       params.context = client;
-
-       rc = smscore_register_client(coredev, &params, &client->smsclient);
-       if (rc < 0) {
-               sms_err("smscore_register_client() failed %d", rc);
-               goto client_error;
-       }
-
-       client->coredev = coredev;
-
-       init_completion(&client->tune_done);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       list_add(&client->entry, &g_smsdvb_clients);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-
-       client->event_fe_state = -1;
-       client->event_unc_state = -1;
-       sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
-
-       sms_info("success");
-       sms_board_setup(coredev);
-
-       return 0;
-
-client_error:
-       dvb_unregister_frontend(&client->frontend);
-
-frontend_error:
-       dvb_dmxdev_release(&client->dmxdev);
-
-dmxdev_error:
-       dvb_dmx_release(&client->demux);
-
-dvbdmx_error:
-       dvb_unregister_adapter(&client->adapter);
-
-adapter_error:
-       kfree(client);
-       return rc;
-}
-
-static int __init smsdvb_module_init(void)
-{
-       int rc;
-
-       INIT_LIST_HEAD(&g_smsdvb_clients);
-       kmutex_init(&g_smsdvb_clientslock);
-
-       rc = smscore_register_hotplug(smsdvb_hotplug);
-
-       sms_debug("");
-
-       return rc;
-}
-
-static void __exit smsdvb_module_exit(void)
-{
-       smscore_unregister_hotplug(smsdvb_hotplug);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       while (!list_empty(&g_smsdvb_clients))
-              smsdvb_unregister_client(
-                       (struct smsdvb_client_t *) g_smsdvb_clients.next);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-module_init(smsdvb_module_init);
-module_exit(smsdvb_module_exit);
-
-MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
-MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c
deleted file mode 100644 (file)
index e2657c2..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- 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, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
-
-#include <linux/export.h>
-#include <asm/byteorder.h>
-
-#include "smsendian.h"
-#include "smscoreapi.h"
-
-void smsendian_handle_tx_message(void *buffer)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
-       int i;
-       int msgWords;
-
-       switch (msg->xMsgHeader.msgType) {
-       case MSG_SMS_DATA_DOWNLOAD_REQ:
-       {
-               msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
-               break;
-       }
-
-       default:
-               msgWords = (msg->xMsgHeader.msgLength -
-                               sizeof(struct SmsMsgHdr_ST))/4;
-
-               for (i = 0; i < msgWords; i++)
-                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
-
-               break;
-       }
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
-
-void smsendian_handle_rx_message(void *buffer)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
-       int i;
-       int msgWords;
-
-       switch (msg->xMsgHeader.msgType) {
-       case MSG_SMS_GET_VERSION_EX_RES:
-       {
-               struct SmsVersionRes_ST *ver =
-                       (struct SmsVersionRes_ST *) msg;
-               ver->ChipModel = le16_to_cpu(ver->ChipModel);
-               break;
-       }
-
-       case MSG_SMS_DVBT_BDA_DATA:
-       case MSG_SMS_DAB_CHANNEL:
-       case MSG_SMS_DATA_MSG:
-       {
-               break;
-       }
-
-       default:
-       {
-               msgWords = (msg->xMsgHeader.msgLength -
-                               sizeof(struct SmsMsgHdr_ST))/4;
-
-               for (i = 0; i < msgWords; i++)
-                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
-
-               break;
-       }
-       }
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
-
-void smsendian_handle_message_header(void *msg)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
-
-       phdr->msgType = le16_to_cpu(phdr->msgType);
-       phdr->msgLength = le16_to_cpu(phdr->msgLength);
-       phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h
deleted file mode 100644 (file)
index 1624d6f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
-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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_ENDIAN_H__
-#define __SMS_ENDIAN_H__
-
-#include <asm/byteorder.h>
-
-extern void smsendian_handle_tx_message(void *buffer);
-extern void smsendian_handle_rx_message(void *buffer);
-extern void smsendian_handle_message_header(void *msg);
-
-#endif /* __SMS_ENDIAN_H__ */
-
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
deleted file mode 100644 (file)
index 37bc5c4..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-       - Ported the driver to use rc-core
-       - IR raw event decoding is now done at rc-core
-       - Code almost re-written
-
- 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, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
-
-
-#include <linux/types.h>
-#include <linux/input.h>
-
-#include "smscoreapi.h"
-#include "smsir.h"
-#include "sms-cards.h"
-
-#define MODULE_NAME "smsmdtv"
-
-void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
-{
-       int i;
-       const s32 *samples = (const void *)buf;
-
-       for (i = 0; i < len >> 2; i++) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
-               ev.pulse = (samples[i] > 0) ? false : true;
-
-               ir_raw_event_store(coredev->ir.dev, &ev);
-       }
-       ir_raw_event_handle(coredev->ir.dev);
-}
-
-int sms_ir_init(struct smscore_device_t *coredev)
-{
-       int err;
-       int board_id = smscore_get_board_id(coredev);
-       struct rc_dev *dev;
-
-       sms_log("Allocating rc device");
-       dev = rc_allocate_device();
-       if (!dev) {
-               sms_err("Not enough memory");
-               return -ENOMEM;
-       }
-
-       coredev->ir.controller = 0;     /* Todo: vega/nova SPI number */
-       coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
-       sms_log("IR port %d, timeout %d ms",
-                       coredev->ir.controller, coredev->ir.timeout);
-
-       snprintf(coredev->ir.name, sizeof(coredev->ir.name),
-                "SMS IR (%s)", sms_get_board(board_id)->name);
-
-       strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
-       strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
-
-       dev->input_name = coredev->ir.name;
-       dev->input_phys = coredev->ir.phys;
-       dev->dev.parent = coredev->device;
-
-#if 0
-       /* TODO: properly initialize the parameters bellow */
-       dev->input_id.bustype = BUS_USB;
-       dev->input_id.version = 1;
-       dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
-       dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
-#endif
-
-       dev->priv = coredev;
-       dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protos = RC_TYPE_ALL;
-       dev->map_name = sms_get_board(board_id)->rc_codes;
-       dev->driver_name = MODULE_NAME;
-
-       sms_log("Input device (IR) %s is set for key events", dev->input_name);
-
-       err = rc_register_device(dev);
-       if (err < 0) {
-               sms_err("Failed to register device");
-               rc_free_device(dev);
-               return err;
-       }
-
-       coredev->ir.dev = dev;
-       return 0;
-}
-
-void sms_ir_exit(struct smscore_device_t *coredev)
-{
-       if (coredev->ir.dev)
-               rc_unregister_device(coredev->ir.dev);
-
-       sms_log("");
-}
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
deleted file mode 100644 (file)
index ae92b3a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-       - Ported the driver to use rc-core
-       - IR raw event decoding is now done at rc-core
-       - Code almost re-written
-
-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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_IR_H__
-#define __SMS_IR_H__
-
-#include <linux/input.h>
-#include <media/rc-core.h>
-
-#define IR_DEFAULT_TIMEOUT             100
-
-struct smscore_device_t;
-
-struct ir_t {
-       struct rc_dev *dev;
-       char name[40];
-       char phys[32];
-
-       char *rc_codes;
-       u64 protocol;
-
-       u32 timeout;
-       u32 controller;
-};
-
-int sms_ir_init(struct smscore_device_t *coredev);
-void sms_ir_exit(struct smscore_device_t *coredev);
-void sms_ir_event(struct smscore_device_t *coredev,
-                       const char *buf, int len);
-
-#endif /* __SMS_IR_H__ */
-
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
deleted file mode 100644 (file)
index d6f3f10..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- *  smssdio.c - Siano 1xxx SDIO interface driver
- *
- *  Copyright 2008 Pierre Ossman
- *
- * Based on code by Siano Mobile Silicon, Inc.,
- * Copyright (C) 2006-2008, Uri Shkolnik
- *
- * 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 hardware is a bit odd in that all transfers should be done
- * to/from the SMSSDIO_DATA register, yet the "increase address" bit
- * always needs to be set.
- *
- * Also, buffers from the card are always aligned to 128 byte
- * boundaries.
- */
-
-/*
- * General cleanup notes:
- *
- * - only typedefs should be name *_t
- *
- * - use ERR_PTR and friends for smscore_register_device()
- *
- * - smscore_getbuffer should zero fields
- *
- * Fix stop command
- */
-
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/module.h>
-
-#include "smscoreapi.h"
-#include "sms-cards.h"
-
-/* Registers */
-
-#define SMSSDIO_DATA           0x00
-#define SMSSDIO_INT            0x04
-#define SMSSDIO_BLOCK_SIZE     128
-
-static const struct sdio_device_id smssdio_ids[] __devinitconst = {
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
-        .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
-        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
-        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
-        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
-        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
-       { /* end: all zeroes */ },
-};
-
-MODULE_DEVICE_TABLE(sdio, smssdio_ids);
-
-struct smssdio_device {
-       struct sdio_func *func;
-
-       struct smscore_device_t *coredev;
-
-       struct smscore_buffer_t *split_cb;
-};
-
-/*******************************************************************/
-/* Siano core callbacks                                            */
-/*******************************************************************/
-
-static int smssdio_sendrequest(void *context, void *buffer, size_t size)
-{
-       int ret = 0;
-       struct smssdio_device *smsdev;
-
-       smsdev = context;
-
-       sdio_claim_host(smsdev->func);
-
-       while (size >= smsdev->func->cur_blksize) {
-               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
-                                       buffer, smsdev->func->cur_blksize);
-               if (ret)
-                       goto out;
-
-               buffer += smsdev->func->cur_blksize;
-               size -= smsdev->func->cur_blksize;
-       }
-
-       if (size) {
-               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
-                                       buffer, size);
-       }
-
-out:
-       sdio_release_host(smsdev->func);
-
-       return ret;
-}
-
-/*******************************************************************/
-/* SDIO callbacks                                                  */
-/*******************************************************************/
-
-static void smssdio_interrupt(struct sdio_func *func)
-{
-       int ret;
-
-       struct smssdio_device *smsdev;
-       struct smscore_buffer_t *cb;
-       struct SmsMsgHdr_ST *hdr;
-       size_t size;
-
-       smsdev = sdio_get_drvdata(func);
-
-       /*
-        * The interrupt register has no defined meaning. It is just
-        * a way of turning of the level triggered interrupt.
-        */
-       (void)sdio_readb(func, SMSSDIO_INT, &ret);
-       if (ret) {
-               sms_err("Unable to read interrupt register!\n");
-               return;
-       }
-
-       if (smsdev->split_cb == NULL) {
-               cb = smscore_getbuffer(smsdev->coredev);
-               if (!cb) {
-                       sms_err("Unable to allocate data buffer!\n");
-                       return;
-               }
-
-               ret = sdio_memcpy_fromio(smsdev->func,
-                                        cb->p,
-                                        SMSSDIO_DATA,
-                                        SMSSDIO_BLOCK_SIZE);
-               if (ret) {
-                       sms_err("Error %d reading initial block!\n", ret);
-                       return;
-               }
-
-               hdr = cb->p;
-
-               if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
-                       smsdev->split_cb = cb;
-                       return;
-               }
-
-               if (hdr->msgLength > smsdev->func->cur_blksize)
-                       size = hdr->msgLength - smsdev->func->cur_blksize;
-               else
-                       size = 0;
-       } else {
-               cb = smsdev->split_cb;
-               hdr = cb->p;
-
-               size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
-
-               smsdev->split_cb = NULL;
-       }
-
-       if (size) {
-               void *buffer;
-
-               buffer = cb->p + (hdr->msgLength - size);
-               size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
-
-               BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
-
-               /*
-                * First attempt to transfer all of it in one go...
-                */
-               ret = sdio_memcpy_fromio(smsdev->func,
-                                        buffer,
-                                        SMSSDIO_DATA,
-                                        size);
-               if (ret && ret != -EINVAL) {
-                       smscore_putbuffer(smsdev->coredev, cb);
-                       sms_err("Error %d reading data from card!\n", ret);
-                       return;
-               }
-
-               /*
-                * ..then fall back to one block at a time if that is
-                * not possible...
-                *
-                * (we have to do this manually because of the
-                * problem with the "increase address" bit)
-                */
-               if (ret == -EINVAL) {
-                       while (size) {
-                               ret = sdio_memcpy_fromio(smsdev->func,
-                                                 buffer, SMSSDIO_DATA,
-                                                 smsdev->func->cur_blksize);
-                               if (ret) {
-                                       smscore_putbuffer(smsdev->coredev, cb);
-                                       sms_err("Error %d reading "
-                                               "data from card!\n", ret);
-                                       return;
-                               }
-
-                               buffer += smsdev->func->cur_blksize;
-                               if (size > smsdev->func->cur_blksize)
-                                       size -= smsdev->func->cur_blksize;
-                               else
-                                       size = 0;
-                       }
-               }
-       }
-
-       cb->size = hdr->msgLength;
-       cb->offset = 0;
-
-       smscore_onresponse(smsdev->coredev, cb);
-}
-
-static int __devinit smssdio_probe(struct sdio_func *func,
-                        const struct sdio_device_id *id)
-{
-       int ret;
-
-       int board_id;
-       struct smssdio_device *smsdev;
-       struct smsdevice_params_t params;
-
-       board_id = id->driver_data;
-
-       smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
-       if (!smsdev)
-               return -ENOMEM;
-
-       smsdev->func = func;
-
-       memset(&params, 0, sizeof(struct smsdevice_params_t));
-
-       params.device = &func->dev;
-       params.buffer_size = 0x5000;    /* ?? */
-       params.num_buffers = 22;        /* ?? */
-       params.context = smsdev;
-
-       snprintf(params.devpath, sizeof(params.devpath),
-                "sdio\\%s", sdio_func_id(func));
-
-       params.sendrequest_handler = smssdio_sendrequest;
-
-       params.device_type = sms_get_board(board_id)->type;
-
-       if (params.device_type != SMS_STELLAR)
-               params.flags |= SMS_DEVICE_FAMILY2;
-       else {
-               /*
-                * FIXME: Stellar needs special handling...
-                */
-               ret = -ENODEV;
-               goto free;
-       }
-
-       ret = smscore_register_device(&params, &smsdev->coredev);
-       if (ret < 0)
-               goto free;
-
-       smscore_set_board_id(smsdev->coredev, board_id);
-
-       sdio_claim_host(func);
-
-       ret = sdio_enable_func(func);
-       if (ret)
-               goto release;
-
-       ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
-       if (ret)
-               goto disable;
-
-       ret = sdio_claim_irq(func, smssdio_interrupt);
-       if (ret)
-               goto disable;
-
-       sdio_set_drvdata(func, smsdev);
-
-       sdio_release_host(func);
-
-       ret = smscore_start_device(smsdev->coredev);
-       if (ret < 0)
-               goto reclaim;
-
-       return 0;
-
-reclaim:
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-disable:
-       sdio_disable_func(func);
-release:
-       sdio_release_host(func);
-       smscore_unregister_device(smsdev->coredev);
-free:
-       kfree(smsdev);
-
-       return ret;
-}
-
-static void smssdio_remove(struct sdio_func *func)
-{
-       struct smssdio_device *smsdev;
-
-       smsdev = sdio_get_drvdata(func);
-
-       /* FIXME: racy! */
-       if (smsdev->split_cb)
-               smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
-
-       smscore_unregister_device(smsdev->coredev);
-
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-       sdio_disable_func(func);
-       sdio_release_host(func);
-
-       kfree(smsdev);
-}
-
-static struct sdio_driver smssdio_driver = {
-       .name = "smssdio",
-       .id_table = smssdio_ids,
-       .probe = smssdio_probe,
-       .remove = smssdio_remove,
-};
-
-/*******************************************************************/
-/* Module functions                                                */
-/*******************************************************************/
-
-static int __init smssdio_module_init(void)
-{
-       int ret = 0;
-
-       printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
-       printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
-
-       ret = sdio_register_driver(&smssdio_driver);
-
-       return ret;
-}
-
-static void __exit smssdio_module_exit(void)
-{
-       sdio_unregister_driver(&smssdio_driver);
-}
-
-module_init(smssdio_module_init);
-module_exit(smssdio_module_exit);
-
-MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
-MODULE_AUTHOR("Pierre Ossman");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
deleted file mode 100644 (file)
index 664e460..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat
-
-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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "smscoreapi.h"
-#include "sms-cards.h"
-#include "smsendian.h"
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-#define USB1_BUFFER_SIZE               0x1000
-#define USB2_BUFFER_SIZE               0x4000
-
-#define MAX_BUFFERS            50
-#define MAX_URBS               10
-
-struct smsusb_device_t;
-
-struct smsusb_urb_t {
-       struct smscore_buffer_t *cb;
-       struct smsusb_device_t  *dev;
-
-       struct urb urb;
-};
-
-struct smsusb_device_t {
-       struct usb_device *udev;
-       struct smscore_device_t *coredev;
-
-       struct smsusb_urb_t     surbs[MAX_URBS];
-
-       int             response_alignment;
-       int             buffer_size;
-};
-
-static int smsusb_submit_urb(struct smsusb_device_t *dev,
-                            struct smsusb_urb_t *surb);
-
-static void smsusb_onresponse(struct urb *urb)
-{
-       struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
-       struct smsusb_device_t *dev = surb->dev;
-
-       if (urb->status == -ESHUTDOWN) {
-               sms_err("error, urb status %d (-ESHUTDOWN), %d bytes",
-                       urb->status, urb->actual_length);
-               return;
-       }
-
-       if ((urb->actual_length > 0) && (urb->status == 0)) {
-               struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p;
-
-               smsendian_handle_message_header(phdr);
-               if (urb->actual_length >= phdr->msgLength) {
-                       surb->cb->size = phdr->msgLength;
-
-                       if (dev->response_alignment &&
-                           (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {
-
-                               surb->cb->offset =
-                                       dev->response_alignment +
-                                       ((phdr->msgFlags >> 8) & 3);
-
-                               /* sanity check */
-                               if (((int) phdr->msgLength +
-                                    surb->cb->offset) > urb->actual_length) {
-                                       sms_err("invalid response "
-                                               "msglen %d offset %d "
-                                               "size %d",
-                                               phdr->msgLength,
-                                               surb->cb->offset,
-                                               urb->actual_length);
-                                       goto exit_and_resubmit;
-                               }
-
-                               /* move buffer pointer and
-                                * copy header to its new location */
-                               memcpy((char *) phdr + surb->cb->offset,
-                                      phdr, sizeof(struct SmsMsgHdr_ST));
-                       } else
-                               surb->cb->offset = 0;
-
-                       smscore_onresponse(dev->coredev, surb->cb);
-                       surb->cb = NULL;
-               } else {
-                       sms_err("invalid response "
-                               "msglen %d actual %d",
-                               phdr->msgLength, urb->actual_length);
-               }
-       } else
-               sms_err("error, urb status %d, %d bytes",
-                       urb->status, urb->actual_length);
-
-
-exit_and_resubmit:
-       smsusb_submit_urb(dev, surb);
-}
-
-static int smsusb_submit_urb(struct smsusb_device_t *dev,
-                            struct smsusb_urb_t *surb)
-{
-       if (!surb->cb) {
-               surb->cb = smscore_getbuffer(dev->coredev);
-               if (!surb->cb) {
-                       sms_err("smscore_getbuffer(...) returned NULL");
-                       return -ENOMEM;
-               }
-       }
-
-       usb_fill_bulk_urb(
-               &surb->urb,
-               dev->udev,
-               usb_rcvbulkpipe(dev->udev, 0x81),
-               surb->cb->p,
-               dev->buffer_size,
-               smsusb_onresponse,
-               surb
-       );
-       surb->urb.transfer_dma = surb->cb->phys;
-       surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       return usb_submit_urb(&surb->urb, GFP_ATOMIC);
-}
-
-static void smsusb_stop_streaming(struct smsusb_device_t *dev)
-{
-       int i;
-
-       for (i = 0; i < MAX_URBS; i++) {
-               usb_kill_urb(&dev->surbs[i].urb);
-
-               if (dev->surbs[i].cb) {
-                       smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
-                       dev->surbs[i].cb = NULL;
-               }
-       }
-}
-
-static int smsusb_start_streaming(struct smsusb_device_t *dev)
-{
-       int i, rc;
-
-       for (i = 0; i < MAX_URBS; i++) {
-               rc = smsusb_submit_urb(dev, &dev->surbs[i]);
-               if (rc < 0) {
-                       sms_err("smsusb_submit_urb(...) failed");
-                       smsusb_stop_streaming(dev);
-                       break;
-               }
-       }
-
-       return rc;
-}
-
-static int smsusb_sendrequest(void *context, void *buffer, size_t size)
-{
-       struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
-       int dummy;
-
-       smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
-       return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
-                           buffer, size, &dummy, 1000);
-}
-
-static char *smsusb1_fw_lkup[] = {
-       "dvbt_stellar_usb.inp",
-       "dvbh_stellar_usb.inp",
-       "tdmb_stellar_usb.inp",
-       "none",
-       "dvbt_bda_stellar_usb.inp",
-};
-
-static inline char *sms_get_fw_name(int mode, int board_id)
-{
-       char **fw = sms_get_board(board_id)->fw;
-       return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode];
-}
-
-static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id)
-{
-       const struct firmware *fw;
-       u8 *fw_buffer;
-       int rc, dummy;
-       char *fw_filename;
-
-       if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) {
-               sms_err("invalid firmware id specified %d", id);
-               return -EINVAL;
-       }
-
-       fw_filename = sms_get_fw_name(id, board_id);
-
-       rc = request_firmware(&fw, fw_filename, &udev->dev);
-       if (rc < 0) {
-               sms_warn("failed to open \"%s\" mode %d, "
-                        "trying again with default firmware", fw_filename, id);
-
-               fw_filename = smsusb1_fw_lkup[id];
-               rc = request_firmware(&fw, fw_filename, &udev->dev);
-               if (rc < 0) {
-                       sms_warn("failed to open \"%s\" mode %d",
-                                fw_filename, id);
-
-                       return rc;
-               }
-       }
-
-       fw_buffer = kmalloc(fw->size, GFP_KERNEL);
-       if (fw_buffer) {
-               memcpy(fw_buffer, fw->data, fw->size);
-
-               rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2),
-                                 fw_buffer, fw->size, &dummy, 1000);
-
-               sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc);
-
-               kfree(fw_buffer);
-       } else {
-               sms_err("failed to allocate firmware buffer");
-               rc = -ENOMEM;
-       }
-       sms_info("read FW %s, size=%zd", fw_filename, fw->size);
-
-       release_firmware(fw);
-
-       return rc;
-}
-
-static void smsusb1_detectmode(void *context, int *mode)
-{
-       char *product_string =
-               ((struct smsusb_device_t *) context)->udev->product;
-
-       *mode = DEVICE_MODE_NONE;
-
-       if (!product_string) {
-               product_string = "none";
-               sms_err("product string not found");
-       } else if (strstr(product_string, "DVBH"))
-               *mode = 1;
-       else if (strstr(product_string, "BDA"))
-               *mode = 4;
-       else if (strstr(product_string, "DVBT"))
-               *mode = 0;
-       else if (strstr(product_string, "TDMB"))
-               *mode = 2;
-
-       sms_info("%d \"%s\"", *mode, product_string);
-}
-
-static int smsusb1_setmode(void *context, int mode)
-{
-       struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK,
-                            sizeof(struct SmsMsgHdr_ST), 0 };
-
-       if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
-               sms_err("invalid firmware id specified %d", mode);
-               return -EINVAL;
-       }
-
-       return smsusb_sendrequest(context, &Msg, sizeof(Msg));
-}
-
-static void smsusb_term_device(struct usb_interface *intf)
-{
-       struct smsusb_device_t *dev = usb_get_intfdata(intf);
-
-       if (dev) {
-               smsusb_stop_streaming(dev);
-
-               /* unregister from smscore */
-               if (dev->coredev)
-                       smscore_unregister_device(dev->coredev);
-
-               sms_info("device %p destroyed", dev);
-               kfree(dev);
-       }
-
-       usb_set_intfdata(intf, NULL);
-}
-
-static int smsusb_init_device(struct usb_interface *intf, int board_id)
-{
-       struct smsdevice_params_t params;
-       struct smsusb_device_t *dev;
-       int i, rc;
-
-       /* create device object */
-       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
-       if (!dev) {
-               sms_err("kzalloc(sizeof(struct smsusb_device_t) failed");
-               return -ENOMEM;
-       }
-
-       memset(&params, 0, sizeof(params));
-       usb_set_intfdata(intf, dev);
-       dev->udev = interface_to_usbdev(intf);
-
-       params.device_type = sms_get_board(board_id)->type;
-
-       switch (params.device_type) {
-       case SMS_STELLAR:
-               dev->buffer_size = USB1_BUFFER_SIZE;
-
-               params.setmode_handler = smsusb1_setmode;
-               params.detectmode_handler = smsusb1_detectmode;
-               break;
-       default:
-               sms_err("Unspecified sms device type!");
-               /* fall-thru */
-       case SMS_NOVA_A0:
-       case SMS_NOVA_B0:
-       case SMS_VEGA:
-               dev->buffer_size = USB2_BUFFER_SIZE;
-               dev->response_alignment =
-                   le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
-                   sizeof(struct SmsMsgHdr_ST);
-
-               params.flags |= SMS_DEVICE_FAMILY2;
-               break;
-       }
-
-       params.device = &dev->udev->dev;
-       params.buffer_size = dev->buffer_size;
-       params.num_buffers = MAX_BUFFERS;
-       params.sendrequest_handler = smsusb_sendrequest;
-       params.context = dev;
-       usb_make_path(dev->udev, params.devpath, sizeof(params.devpath));
-
-       /* register in smscore */
-       rc = smscore_register_device(&params, &dev->coredev);
-       if (rc < 0) {
-               sms_err("smscore_register_device(...) failed, rc %d", rc);
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       smscore_set_board_id(dev->coredev, board_id);
-
-       /* initialize urbs */
-       for (i = 0; i < MAX_URBS; i++) {
-               dev->surbs[i].dev = dev;
-               usb_init_urb(&dev->surbs[i].urb);
-       }
-
-       sms_info("smsusb_start_streaming(...).");
-       rc = smsusb_start_streaming(dev);
-       if (rc < 0) {
-               sms_err("smsusb_start_streaming(...) failed");
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       rc = smscore_start_device(dev->coredev);
-       if (rc < 0) {
-               sms_err("smscore_start_device(...) failed");
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       sms_info("device %p created", dev);
-
-       return rc;
-}
-
-static int __devinit smsusb_probe(struct usb_interface *intf,
-                       const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       char devpath[32];
-       int i, rc;
-
-       rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
-       rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
-
-       if (intf->num_altsetting > 0) {
-               rc = usb_set_interface(
-                       udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
-               if (rc < 0) {
-                       sms_err("usb_set_interface failed, rc %d", rc);
-                       return rc;
-               }
-       }
-
-       sms_info("smsusb_probe %d",
-              intf->cur_altsetting->desc.bInterfaceNumber);
-       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
-               sms_info("endpoint %d %02x %02x %d", i,
-                      intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
-                      intf->cur_altsetting->endpoint[i].desc.bmAttributes,
-                      intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
-
-       if ((udev->actconfig->desc.bNumInterfaces == 2) &&
-           (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
-               sms_err("rom interface 0 is not used");
-               return -ENODEV;
-       }
-
-       if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
-               snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
-                        udev->bus->busnum, udev->devpath);
-               sms_info("stellar device was found.");
-               return smsusb1_load_firmware(
-                               udev, smscore_registry_getmode(devpath),
-                               id->driver_info);
-       }
-
-       rc = smsusb_init_device(intf, id->driver_info);
-       sms_info("rc %d", rc);
-       sms_board_load_modules(id->driver_info);
-       return rc;
-}
-
-static void smsusb_disconnect(struct usb_interface *intf)
-{
-       smsusb_term_device(intf);
-}
-
-static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
-{
-       struct smsusb_device_t *dev = usb_get_intfdata(intf);
-       printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
-       smsusb_stop_streaming(dev);
-       return 0;
-}
-
-static int smsusb_resume(struct usb_interface *intf)
-{
-       int rc, i;
-       struct smsusb_device_t *dev = usb_get_intfdata(intf);
-       struct usb_device *udev = interface_to_usbdev(intf);
-
-       printk(KERN_INFO "%s: Entering.\n", __func__);
-       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
-       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
-
-       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
-               printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,
-                      intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
-                      intf->cur_altsetting->endpoint[i].desc.bmAttributes,
-                      intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
-
-       if (intf->num_altsetting > 0) {
-               rc = usb_set_interface(udev,
-                                      intf->cur_altsetting->desc.
-                                      bInterfaceNumber, 0);
-               if (rc < 0) {
-                       printk(KERN_INFO "%s usb_set_interface failed, "
-                              "rc %d\n", __func__, rc);
-                       return rc;
-               }
-       }
-
-       smsusb_start_streaming(dev);
-       return 0;
-}
-
-static const struct usb_device_id smsusb_id_table[] __devinitconst = {
-       { USB_DEVICE(0x187f, 0x0010),
-               .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
-       { USB_DEVICE(0x187f, 0x0100),
-               .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
-       { USB_DEVICE(0x187f, 0x0200),
-               .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
-       { USB_DEVICE(0x187f, 0x0201),
-               .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
-       { USB_DEVICE(0x187f, 0x0300),
-               .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
-       { USB_DEVICE(0x2040, 0x1700),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
-       { USB_DEVICE(0x2040, 0x1800),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
-       { USB_DEVICE(0x2040, 0x1801),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
-       { USB_DEVICE(0x2040, 0x2000),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-       { USB_DEVICE(0x2040, 0x2009),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
-       { USB_DEVICE(0x2040, 0x200a),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-       { USB_DEVICE(0x2040, 0x2010),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-       { USB_DEVICE(0x2040, 0x2011),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-       { USB_DEVICE(0x2040, 0x2019),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-       { USB_DEVICE(0x2040, 0x5500),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0x5510),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0x5520),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0x5530),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0x5580),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0x5590),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x187f, 0x0202),
-               .driver_info = SMS1XXX_BOARD_SIANO_NICE },
-       { USB_DEVICE(0x187f, 0x0301),
-               .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
-       { USB_DEVICE(0x2040, 0xb900),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xb910),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xb980),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xb990),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xc000),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xc010),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xc080),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xc090),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xc0a0),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { USB_DEVICE(0x2040, 0xf5a0),
-               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-       { } /* Terminating entry */
-       };
-
-MODULE_DEVICE_TABLE(usb, smsusb_id_table);
-
-static struct usb_driver smsusb_driver = {
-       .name                   = "smsusb",
-       .probe                  = smsusb_probe,
-       .disconnect             = smsusb_disconnect,
-       .id_table               = smsusb_id_table,
-
-       .suspend                = smsusb_suspend,
-       .resume                 = smsusb_resume,
-};
-
-module_usb_driver(smsusb_driver);
-
-MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle");
-MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
deleted file mode 100644 (file)
index 2663ae3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-config DVB_TTUSB_BUDGET
-       tristate "Technotrend/Hauppauge Nova-USB devices"
-       depends on DVB_CORE && USB && I2C && PCI
-       select DVB_CX22700 if !DVB_FE_CUSTOMISE
-       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-       select DVB_VES1820 if !DVB_FE_CUSTOMISE
-       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
-       select DVB_STV0299 if !DVB_FE_CUSTOMISE
-       select DVB_STV0297 if !DVB_FE_CUSTOMISE
-       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
-       help
-         Support for external USB adapters designed by Technotrend and
-         produced by Hauppauge, shipped under the brand name 'Nova-USB'.
-
-         These devices don't have a MPEG decoder built in, so you need
-         an external software decoder to watch TV.
-
-         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile
deleted file mode 100644 (file)
index f47bbf6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
-
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
deleted file mode 100644 (file)
index 5b682cc..0000000
+++ /dev/null
@@ -1,1816 +0,0 @@
-/*
- * TTUSB DVB driver
- *
- * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
- * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.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.
- */
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/jiffies.h>
-#include <linux/mutex.h>
-#include <linux/firmware.h>
-
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "ves1820.h"
-#include "cx22700.h"
-#include "tda1004x.h"
-#include "stv0299.h"
-#include "tda8083.h"
-#include "stv0297.h"
-#include "lnbp21.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>
-#include <linux/pci.h>
-
-/*
-  TTUSB_HWSECTIONS:
-    the DSP supports filtering in hardware, however, since the "muxstream"
-    is a bit braindead (no matching channel masks or no matching filter mask),
-    we won't support this - yet. it doesn't event support negative filters,
-    so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
-    parse TS data. USB bandwidth will be a problem when having large
-    datastreams, especially for dvb-net, but hey, that's not my problem.
-
-  TTUSB_DISEQC, TTUSB_TONE:
-    let the STC do the diseqc/tone stuff. this isn't supported at least with
-    my TTUSB, so let it undef'd unless you want to implement another
-    frontend. never tested.
-
-  debug:
-    define it to > 3 for really hardcore debugging. you probably don't want
-    this unless the device doesn't load at all. > 2 for bandwidth statistics.
-*/
-
-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(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
-
-#define ISO_BUF_COUNT      4
-#define FRAMES_PER_ISO_BUF 4
-#define ISO_FRAME_SIZE     912
-#define TTUSB_MAXCHANNEL   32
-#ifdef TTUSB_HWSECTIONS
-#define TTUSB_MAXFILTER    16  /* ??? */
-#endif
-
-#define TTUSB_REV_2_2  0x22
-#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
-
-/**
- *  since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
- *  the dvb_demux field must be the first in struct!!
- */
-struct ttusb {
-       struct dvb_demux dvb_demux;
-       struct dmxdev dmxdev;
-       struct dvb_net dvbnet;
-
-       /* and one for USB access. */
-       struct mutex semi2c;
-       struct mutex semusb;
-
-       struct dvb_adapter adapter;
-       struct usb_device *dev;
-
-       struct i2c_adapter i2c_adap;
-
-       int disconnecting;
-       int iso_streaming;
-
-       unsigned int bulk_out_pipe;
-       unsigned int bulk_in_pipe;
-       unsigned int isoc_in_pipe;
-
-       void *iso_buffer;
-       dma_addr_t iso_dma_handle;
-
-       struct urb *iso_urb[ISO_BUF_COUNT];
-
-       int running_feed_count;
-       int last_channel;
-       int last_filter;
-
-       u8 c;                   /* transaction counter, wraps around...  */
-       fe_sec_tone_mode_t tone;
-       fe_sec_voltage_t voltage;
-
-       int mux_state;          // 0..2 - MuxSyncWord, 3 - nMuxPacks,    4 - muxpack
-       u8 mux_npacks;
-       u8 muxpack[256 + 8];
-       int muxpack_ptr, muxpack_len;
-
-       int insync;
-
-       int cc;                 /* MuxCounter - will increment on EVERY MUX PACKET */
-       /* (including stuffing. yes. really.) */
-
-       u8 last_result[32];
-
-       int revision;
-
-       struct dvb_frontend* fe;
-};
-
-/* ugly workaround ... don't know why it's necessary to read */
-/* all result codes. */
-
-static int ttusb_cmd(struct ttusb *ttusb,
-             const u8 * data, int len, int needresult)
-{
-       int actual_len;
-       int err;
-       int i;
-
-       if (debug >= 3) {
-               printk(KERN_DEBUG ">");
-               for (i = 0; i < len; ++i)
-                       printk(KERN_CONT " %02x", data[i]);
-               printk(KERN_CONT "\n");
-       }
-
-       if (mutex_lock_interruptible(&ttusb->semusb) < 0)
-               return -EAGAIN;
-
-       err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
-                          (u8 *) data, len, &actual_len, 1000);
-       if (err != 0) {
-               dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
-                       __func__, err);
-               mutex_unlock(&ttusb->semusb);
-               return err;
-       }
-       if (actual_len != len) {
-               dprintk("%s: only wrote %d of %d bytes\n", __func__,
-                       actual_len, len);
-               mutex_unlock(&ttusb->semusb);
-               return -1;
-       }
-
-       err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
-                          ttusb->last_result, 32, &actual_len, 1000);
-
-       if (err != 0) {
-               printk("%s: failed, receive error %d\n", __func__,
-                      err);
-               mutex_unlock(&ttusb->semusb);
-               return err;
-       }
-
-       if (debug >= 3) {
-               actual_len = ttusb->last_result[3] + 4;
-               printk(KERN_DEBUG "<");
-               for (i = 0; i < actual_len; ++i)
-                       printk(KERN_CONT " %02x", ttusb->last_result[i]);
-               printk(KERN_CONT "\n");
-       }
-
-       if (!needresult)
-               mutex_unlock(&ttusb->semusb);
-       return 0;
-}
-
-static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
-{
-       memcpy(data, ttusb->last_result, len);
-       mutex_unlock(&ttusb->semusb);
-       return 0;
-}
-
-static int ttusb_i2c_msg(struct ttusb *ttusb,
-                 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
-                 u8 rcv_len)
-{
-       u8 b[0x28];
-       u8 id = ++ttusb->c;
-       int i, err;
-
-       if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
-               return -EINVAL;
-
-       b[0] = 0xaa;
-       b[1] = id;
-       b[2] = 0x31;
-       b[3] = snd_len + 3;
-       b[4] = addr << 1;
-       b[5] = snd_len;
-       b[6] = rcv_len;
-
-       for (i = 0; i < snd_len; i++)
-               b[7 + i] = snd_buf[i];
-
-       err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
-
-       if (err)
-               return -EREMOTEIO;
-
-       err = ttusb_result(ttusb, b, 0x20);
-
-       /* check if the i2c transaction was successful */
-       if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
-
-       if (rcv_len > 0) {
-
-               if (err || b[0] != 0x55 || b[1] != id) {
-                       dprintk
-                           ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
-                            __func__, err, id);
-                       return -EREMOTEIO;
-               }
-
-               for (i = 0; i < rcv_len; i++)
-                       rcv_buf[i] = b[7 + i];
-       }
-
-       return rcv_len;
-}
-
-static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
-{
-       struct ttusb *ttusb = i2c_get_adapdata(adapter);
-       int i = 0;
-       int inc;
-
-       if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
-               int err;
-
-               if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
-                       addr = msg[i].addr;
-                       snd_buf = msg[i].buf;
-                       snd_len = msg[i].len;
-                       rcv_buf = msg[i + 1].buf;
-                       rcv_len = msg[i + 1].len;
-                       inc = 2;
-               } else {
-                       addr = msg[i].addr;
-                       snd_buf = msg[i].buf;
-                       snd_len = msg[i].len;
-                       rcv_buf = NULL;
-                       rcv_len = 0;
-                       inc = 1;
-               }
-
-               err = ttusb_i2c_msg(ttusb, addr,
-                                   snd_buf, snd_len, rcv_buf, rcv_len);
-
-               if (err < rcv_len) {
-                       dprintk("%s: i == %i\n", __func__, i);
-                       break;
-               }
-
-               i += inc;
-       }
-
-       mutex_unlock(&ttusb->semi2c);
-       return i;
-}
-
-static int ttusb_boot_dsp(struct ttusb *ttusb)
-{
-       const struct firmware *fw;
-       int i, err;
-       u8 b[40];
-
-       err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
-                              &ttusb->dev->dev);
-       if (err) {
-               printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
-               return err;
-       }
-
-       /* BootBlock */
-       b[0] = 0xaa;
-       b[2] = 0x13;
-       b[3] = 28;
-
-       /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
-       /* 32 is max packet size, no messages should be splitted. */
-       for (i = 0; i < fw->size; i += 28) {
-               memcpy(&b[4], &fw->data[i], 28);
-
-               b[1] = ++ttusb->c;
-
-               err = ttusb_cmd(ttusb, b, 32, 0);
-               if (err)
-                       goto done;
-       }
-
-       /* last block ... */
-       b[1] = ++ttusb->c;
-       b[2] = 0x13;
-       b[3] = 0;
-
-       err = ttusb_cmd(ttusb, b, 4, 0);
-       if (err)
-               goto done;
-
-       /* BootEnd */
-       b[1] = ++ttusb->c;
-       b[2] = 0x14;
-       b[3] = 0;
-
-       err = ttusb_cmd(ttusb, b, 4, 0);
-
-      done:
-       release_firmware(fw);
-       if (err) {
-               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-                       __func__, err);
-       }
-
-       return err;
-}
-
-static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
-                     int pid)
-{
-       int err;
-       /* SetChannel */
-       u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
-               (pid >> 8) & 0xff, pid & 0xff
-       };
-
-       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-       return err;
-}
-
-static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
-{
-       int err;
-       /* DelChannel */
-       u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
-
-       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-       return err;
-}
-
-#ifdef TTUSB_HWSECTIONS
-static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
-                    int associated_chan, u8 filter[8], u8 mask[8])
-{
-       int err;
-       /* SetFilter */
-       u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
-               filter[0], filter[1], filter[2], filter[3],
-               filter[4], filter[5], filter[6], filter[7],
-               filter[8], filter[9], filter[10], filter[11],
-               mask[0], mask[1], mask[2], mask[3],
-               mask[4], mask[5], mask[6], mask[7],
-               mask[8], mask[9], mask[10], mask[11]
-       };
-
-       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-       return err;
-}
-
-static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
-{
-       int err;
-       /* DelFilter */
-       u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
-
-       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-       return err;
-}
-#endif
-
-static int ttusb_init_controller(struct ttusb *ttusb)
-{
-       u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
-       u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
-       u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
-       /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
-       u8 b3[] =
-           { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
-       u8 b4[] =
-           { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
-
-       u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
-       u8 get_dsp_version[0x20] =
-           { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
-       int err;
-
-       /* reset board */
-       if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
-               return err;
-
-       /* reset board (again?) */
-       if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
-               return err;
-
-       ttusb_boot_dsp(ttusb);
-
-       /* set i2c bit rate */
-       if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
-               return err;
-
-       if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
-               return err;
-
-       err = ttusb_result(ttusb, b4, sizeof(b4));
-
-       if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
-               return err;
-
-       if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
-               return err;
-
-       dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
-               get_version[4], get_version[5], get_version[6],
-               get_version[7], get_version[8]);
-
-       if (memcmp(get_version + 4, "V 0.0", 5) &&
-           memcmp(get_version + 4, "V 1.1", 5) &&
-           memcmp(get_version + 4, "V 2.1", 5) &&
-           memcmp(get_version + 4, "V 2.2", 5)) {
-               printk
-                   ("%s: unknown STC version %c%c%c%c%c, please report!\n",
-                    __func__, get_version[4], get_version[5],
-                    get_version[6], get_version[7], get_version[8]);
-       }
-
-       ttusb->revision = ((get_version[6] - '0') << 4) |
-                          (get_version[8] - '0');
-
-       err =
-           ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
-       if (err)
-               return err;
-
-       err =
-           ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
-       if (err)
-               return err;
-       printk("%s: dsp-version: %c%c%c\n", __func__,
-              get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
-       return 0;
-}
-
-#ifdef TTUSB_DISEQC
-static int ttusb_send_diseqc(struct dvb_frontend* fe,
-                            const struct dvb_diseqc_master_cmd *cmd)
-{
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-       u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
-
-       int err;
-
-       b[3] = 4 + 2 + cmd->msg_len;
-       b[4] = 0xFF;            /* send diseqc master, not burst */
-       b[5] = cmd->msg_len;
-
-       memcpy(b + 5, cmd->msg, cmd->msg_len);
-
-       /* Diseqc */
-       if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
-               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-                       __func__, err);
-       }
-
-       return err;
-}
-#endif
-
-static int ttusb_update_lnb(struct ttusb *ttusb)
-{
-       u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
-               ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
-               ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
-       };
-       int err;
-
-       /* SetLNB */
-       if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
-               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-                       __func__, err);
-       }
-
-       return err;
-}
-
-static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-
-       ttusb->voltage = voltage;
-       return ttusb_update_lnb(ttusb);
-}
-
-#ifdef TTUSB_TONE
-static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-
-       ttusb->tone = tone;
-       return ttusb_update_lnb(ttusb);
-}
-#endif
-
-
-#if 0
-static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
-{
-       u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
-       int err, actual_len;
-
-       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-       if (err) {
-               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-                       __func__, err);
-       }
-}
-#endif
-
-/*****************************************************************************/
-
-#ifdef TTUSB_HWSECTIONS
-static void ttusb_handle_ts_data(struct ttusb_channel *channel,
-                                const u8 * data, int len);
-static void ttusb_handle_sec_data(struct ttusb_channel *channel,
-                                 const u8 * data, int len);
-#endif
-
-static int numpkt, numts, numstuff, numsec, numinvalid;
-static unsigned long lastj;
-
-static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
-                          int len)
-{
-       u16 csum = 0, cc;
-       int i;
-       for (i = 0; i < len; i += 2)
-               csum ^= le16_to_cpup((__le16 *) (muxpack + i));
-       if (csum) {
-               printk("%s: muxpack with incorrect checksum, ignoring\n",
-                      __func__);
-               numinvalid++;
-               return;
-       }
-
-       cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
-       cc &= 0x7FFF;
-       if ((cc != ttusb->cc) && (ttusb->cc != -1))
-               printk("%s: cc discontinuity (%d frames missing)\n",
-                      __func__, (cc - ttusb->cc) & 0x7FFF);
-       ttusb->cc = (cc + 1) & 0x7FFF;
-       if (muxpack[0] & 0x80) {
-#ifdef TTUSB_HWSECTIONS
-               /* section data */
-               int pusi = muxpack[0] & 0x40;
-               int channel = muxpack[0] & 0x1F;
-               int payload = muxpack[1];
-               const u8 *data = muxpack + 2;
-               /* check offset flag */
-               if (muxpack[0] & 0x20)
-                       data++;
-
-               ttusb_handle_sec_data(ttusb->channel + channel, data,
-                                     payload);
-               data += payload;
-
-               if ((!!(ttusb->muxpack[0] & 0x20)) ^
-                   !!(ttusb->muxpack[1] & 1))
-                       data++;
-#warning TODO: pusi
-               printk("cc: %04x\n", (data[0] << 8) | data[1]);
-#endif
-               numsec++;
-       } else if (muxpack[0] == 0x47) {
-#ifdef TTUSB_HWSECTIONS
-               /* we have TS data here! */
-               int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
-               int channel;
-               for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
-                       if (ttusb->channel[channel].active
-                           && (pid == ttusb->channel[channel].pid))
-                               ttusb_handle_ts_data(ttusb->channel +
-                                                    channel, muxpack,
-                                                    188);
-#endif
-               numts++;
-               dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
-       } else if (muxpack[0] != 0) {
-               numinvalid++;
-               printk("illegal muxpack type %02x\n", muxpack[0]);
-       } else
-               numstuff++;
-}
-
-static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
-{
-       int maxwork = 1024;
-       while (len) {
-               if (!(maxwork--)) {
-                       printk("%s: too much work\n", __func__);
-                       break;
-               }
-
-               switch (ttusb->mux_state) {
-               case 0:
-               case 1:
-               case 2:
-                       len--;
-                       if (*data++ == 0xAA)
-                               ++ttusb->mux_state;
-                       else {
-                               ttusb->mux_state = 0;
-                               if (ttusb->insync) {
-                                       dprintk("%s: %02x\n",
-                                               __func__, data[-1]);
-                                       printk(KERN_INFO "%s: lost sync.\n",
-                                              __func__);
-                                       ttusb->insync = 0;
-                               }
-                       }
-                       break;
-               case 3:
-                       ttusb->insync = 1;
-                       len--;
-                       ttusb->mux_npacks = *data++;
-                       ++ttusb->mux_state;
-                       ttusb->muxpack_ptr = 0;
-                       /* maximum bytes, until we know the length */
-                       ttusb->muxpack_len = 2;
-                       break;
-               case 4:
-                       {
-                               int avail;
-                               avail = len;
-                               if (avail >
-                                   (ttusb->muxpack_len -
-                                    ttusb->muxpack_ptr))
-                                       avail =
-                                           ttusb->muxpack_len -
-                                           ttusb->muxpack_ptr;
-                               memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
-                                      data, avail);
-                               ttusb->muxpack_ptr += avail;
-                               BUG_ON(ttusb->muxpack_ptr > 264);
-                               data += avail;
-                               len -= avail;
-                               /* determine length */
-                               if (ttusb->muxpack_ptr == 2) {
-                                       if (ttusb->muxpack[0] & 0x80) {
-                                               ttusb->muxpack_len =
-                                                   ttusb->muxpack[1] + 2;
-                                               if (ttusb->
-                                                   muxpack[0] & 0x20)
-                                                       ttusb->
-                                                           muxpack_len++;
-                                               if ((!!
-                                                    (ttusb->
-                                                     muxpack[0] & 0x20)) ^
-                                                   !!(ttusb->
-                                                      muxpack[1] & 1))
-                                                       ttusb->
-                                                           muxpack_len++;
-                                               ttusb->muxpack_len += 4;
-                                       } else if (ttusb->muxpack[0] ==
-                                                  0x47)
-                                               ttusb->muxpack_len =
-                                                   188 + 4;
-                                       else if (ttusb->muxpack[0] == 0x00)
-                                               ttusb->muxpack_len =
-                                                   ttusb->muxpack[1] + 2 +
-                                                   4;
-                                       else {
-                                               dprintk
-                                                   ("%s: invalid state: first byte is %x\n",
-                                                    __func__,
-                                                    ttusb->muxpack[0]);
-                                               ttusb->mux_state = 0;
-                                       }
-                               }
-
-                       /**
-                        * if length is valid and we reached the end:
-                        * goto next muxpack
-                        */
-                               if ((ttusb->muxpack_ptr >= 2) &&
-                                   (ttusb->muxpack_ptr ==
-                                    ttusb->muxpack_len)) {
-                                       ttusb_process_muxpack(ttusb,
-                                                             ttusb->
-                                                             muxpack,
-                                                             ttusb->
-                                                             muxpack_ptr);
-                                       ttusb->muxpack_ptr = 0;
-                                       /* maximum bytes, until we know the length */
-                                       ttusb->muxpack_len = 2;
-
-                               /**
-                                * no muxpacks left?
-                                * return to search-sync state
-                                */
-                                       if (!ttusb->mux_npacks--) {
-                                               ttusb->mux_state = 0;
-                                               break;
-                                       }
-                               }
-                               break;
-                       }
-               default:
-                       BUG();
-                       break;
-               }
-       }
-}
-
-static void ttusb_iso_irq(struct urb *urb)
-{
-       struct ttusb *ttusb = urb->context;
-       struct usb_iso_packet_descriptor *d;
-       u8 *data;
-       int len, i;
-
-       if (!ttusb->iso_streaming)
-               return;
-
-#if 0
-       printk("%s: status %d, errcount == %d, length == %i\n",
-              __func__,
-              urb->status, urb->error_count, urb->actual_length);
-#endif
-
-       if (!urb->status) {
-               for (i = 0; i < urb->number_of_packets; ++i) {
-                       numpkt++;
-                       if (time_after_eq(jiffies, lastj + HZ)) {
-                               dprintk("frames/s: %lu (ts: %d, stuff %d, "
-                                       "sec: %d, invalid: %d, all: %d)\n",
-                                       numpkt * HZ / (jiffies - lastj),
-                                       numts, numstuff, numsec, numinvalid,
-                                       numts + numstuff + numsec + numinvalid);
-                               numts = numstuff = numsec = numinvalid = 0;
-                               lastj = jiffies;
-                               numpkt = 0;
-                       }
-                       d = &urb->iso_frame_desc[i];
-                       data = urb->transfer_buffer + d->offset;
-                       len = d->actual_length;
-                       d->actual_length = 0;
-                       d->status = 0;
-                       ttusb_process_frame(ttusb, data, len);
-               }
-       }
-       usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void ttusb_free_iso_urbs(struct ttusb *ttusb)
-{
-       int i;
-
-       for (i = 0; i < ISO_BUF_COUNT; i++)
-               if (ttusb->iso_urb[i])
-                       usb_free_urb(ttusb->iso_urb[i]);
-
-       pci_free_consistent(NULL,
-                           ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
-                           ISO_BUF_COUNT, ttusb->iso_buffer,
-                           ttusb->iso_dma_handle);
-}
-
-static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
-{
-       int i;
-
-       ttusb->iso_buffer = pci_alloc_consistent(NULL,
-                                                ISO_FRAME_SIZE *
-                                                FRAMES_PER_ISO_BUF *
-                                                ISO_BUF_COUNT,
-                                                &ttusb->iso_dma_handle);
-
-       if (!ttusb->iso_buffer) {
-               dprintk("%s: pci_alloc_consistent - not enough memory\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       memset(ttusb->iso_buffer, 0,
-              ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
-
-       for (i = 0; i < ISO_BUF_COUNT; i++) {
-               struct urb *urb;
-
-               if (!
-                   (urb =
-                    usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
-                       ttusb_free_iso_urbs(ttusb);
-                       return -ENOMEM;
-               }
-
-               ttusb->iso_urb[i] = urb;
-       }
-
-       return 0;
-}
-
-static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
-{
-       int i;
-
-       for (i = 0; i < ISO_BUF_COUNT; i++)
-               usb_kill_urb(ttusb->iso_urb[i]);
-
-       ttusb->iso_streaming = 0;
-}
-
-static int ttusb_start_iso_xfer(struct ttusb *ttusb)
-{
-       int i, j, err, buffer_offset = 0;
-
-       if (ttusb->iso_streaming) {
-               printk("%s: iso xfer already running!\n", __func__);
-               return 0;
-       }
-
-       ttusb->cc = -1;
-       ttusb->insync = 0;
-       ttusb->mux_state = 0;
-
-       for (i = 0; i < ISO_BUF_COUNT; i++) {
-               int frame_offset = 0;
-               struct urb *urb = ttusb->iso_urb[i];
-
-               urb->dev = ttusb->dev;
-               urb->context = ttusb;
-               urb->complete = ttusb_iso_irq;
-               urb->pipe = ttusb->isoc_in_pipe;
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->interval = 1;
-               urb->number_of_packets = FRAMES_PER_ISO_BUF;
-               urb->transfer_buffer_length =
-                   ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-               urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
-               buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-
-               for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
-                       frame_offset += ISO_FRAME_SIZE;
-               }
-       }
-
-       for (i = 0; i < ISO_BUF_COUNT; i++) {
-               if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
-                       ttusb_stop_iso_xfer(ttusb);
-                       printk
-                           ("%s: failed urb submission (%i: err = %i)!\n",
-                            __func__, i, err);
-                       return err;
-               }
-       }
-
-       ttusb->iso_streaming = 1;
-
-       return 0;
-}
-
-#ifdef TTUSB_HWSECTIONS
-static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
-                         int len)
-{
-       dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
-}
-
-static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
-                          int len)
-{
-//      struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
-#error TODO: handle ugly stuff
-//      dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
-}
-#endif
-
-static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
-       int feed_type = 1;
-
-       dprintk("ttusb_start_feed\n");
-
-       switch (dvbdmxfeed->type) {
-       case DMX_TYPE_TS:
-               break;
-       case DMX_TYPE_SEC:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (dvbdmxfeed->type == DMX_TYPE_TS) {
-               switch (dvbdmxfeed->pes_type) {
-               case DMX_TS_PES_VIDEO:
-               case DMX_TS_PES_AUDIO:
-               case DMX_TS_PES_TELETEXT:
-               case DMX_TS_PES_PCR:
-               case DMX_TS_PES_OTHER:
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-#ifdef TTUSB_HWSECTIONS
-#error TODO: allocate filters
-       if (dvbdmxfeed->type == DMX_TYPE_TS) {
-               feed_type = 1;
-       } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
-               feed_type = 2;
-       }
-#endif
-
-       ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
-
-       if (0 == ttusb->running_feed_count++)
-               ttusb_start_iso_xfer(ttusb);
-
-       return 0;
-}
-
-static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
-
-       ttusb_del_channel(ttusb, dvbdmxfeed->index);
-
-       if (--ttusb->running_feed_count == 0)
-               ttusb_stop_iso_xfer(ttusb);
-
-       return 0;
-}
-
-static int ttusb_setup_interfaces(struct ttusb *ttusb)
-{
-       usb_set_interface(ttusb->dev, 1, 1);
-
-       ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
-       ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
-       ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
-
-       return 0;
-}
-
-#if 0
-static u8 stc_firmware[8192];
-
-static int stc_open(struct inode *inode, struct file *file)
-{
-       struct ttusb *ttusb = file->private_data;
-       int addr;
-
-       for (addr = 0; addr < 8192; addr += 16) {
-               u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
-               ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
-                             16);
-       }
-
-       return 0;
-}
-
-static ssize_t stc_read(struct file *file, char *buf, size_t count,
-                loff_t *offset)
-{
-       return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
-}
-
-static int stc_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static const struct file_operations stc_fops = {
-       .owner = THIS_MODULE,
-       .read = stc_read,
-       .open = stc_open,
-       .release = stc_release,
-};
-#endif
-
-static u32 functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-
-
-static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-       u8 data[4];
-       struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
-       u32 div;
-
-       div = (p->frequency + 36166667) / 166667;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = ((div >> 10) & 0x60) | 0x85;
-       data[3] = p->frequency < 592000000 ? 0x40 : 0x80;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct cx22700_config alps_tdmb7_config = {
-       .demod_address = 0x43,
-};
-
-
-
-
-
-static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
-{
-       struct ttusb* ttusb = (struct ttusb*) 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=0x60, .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(&ttusb->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(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
-               i2c_transfer(&ttusb->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 ttusb* ttusb = (struct ttusb*) 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 = 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
-       switch (p->bandwidth_hz) {
-       case 6000000:
-               tda1004x_writereg(fe, 0x0C, 0);
-               filter = 0;
-               break;
-
-       case 7000000:
-               tda1004x_writereg(fe, 0x0C, 0);
-               filter = 0;
-               break;
-
-       case 8000000:
-               tda1004x_writereg(fe, 0x0C, 0xFF);
-               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(&ttusb->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 ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-
-       return request_firmware(fw, name, &ttusb->dev->dev);
-}
-
-static struct tda1004x_config philips_tdm1316l_config = {
-
-       .demod_address = 0x8,
-       .invert = 1,
-       .invert_oclk = 0,
-       .request_firmware = philips_tdm1316l_request_firmware,
-};
-
-static u8 alps_bsbe1_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, LNB power on OP2/LOCK pin on */
-       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 u8 alps_bsru6_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, LNB power on OP2/LOCK pin on */
-       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, 0x52,
-       0xff, 0xff
-};
-
-static int alps_stv0299_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 int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
-
-       if ((p->frequency < 950000) || (p->frequency > 2150000))
-               return -EINVAL;
-
-       div = (p->frequency + (125 - 1)) / 125; /* round correctly */
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       buf[3] = 0xC4;
-
-       if (p->frequency > 1530000)
-               buf[3] = 0xC0;
-
-       /* BSBE1 wants XCE bit set */
-       if (ttusb->revision == TTUSB_REV_2_2)
-               buf[3] |= 0x20;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-static struct stv0299_config alps_stv0299_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_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 = alps_stv0299_set_symbol_rate,
-};
-
-static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
-
-       div = p->frequency / 125;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x8e;
-       buf[3] = 0x00;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
-
-       .demod_address = 0x68,
-};
-
-static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusb* ttusb = 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 (&ttusb->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 u8 read_pwm(struct ttusb* ttusb)
-{
-       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(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
-               pwm = 0x48;
-
-       return pwm;
-}
-
-
-static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
-       u8 tuner_buf[5];
-       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 = p->frequency;
-       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
-       // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
-       tuner_frequency = ((p->frequency + 36125000) / 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(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
-               printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
-               return -EIO;
-       }
-
-       msleep(50);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
-               printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
-               return -EIO;
-       }
-
-       msleep(1);
-
-       return 0;
-}
-
-static u8 dvbc_philips_tdm1316l_inittab[] = {
-       0x80, 0x21,
-       0x80, 0x20,
-       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, 0xff,
-       0x4b, 0x7f,
-       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, 0x00,
-       0x89, 0x00,
-       0x90, 0x01,
-       0x91, 0x01,
-       0xa0, 0x00,
-       0xa1, 0x00,
-       0xa2, 0x00,
-       0xb0, 0x91,
-       0xb1, 0x0b,
-       0xc0, 0x4b,
-       0xc1, 0x00,
-       0xc2, 0x00,
-       0xd0, 0x00,
-       0xd1, 0x00,
-       0xd2, 0x00,
-       0xd3, 0x00,
-       0xd4, 0x00,
-       0xd5, 0x00,
-       0xde, 0x00,
-       0xdf, 0x00,
-       0x61, 0x38,
-       0x62, 0x0a,
-       0x53, 0x13,
-       0x59, 0x08,
-       0x55, 0x00,
-       0x56, 0x40,
-       0x57, 0x08,
-       0x58, 0x3d,
-       0x88, 0x10,
-       0xa0, 0x00,
-       0xa0, 0x00,
-       0xa0, 0x00,
-       0xa0, 0x04,
-       0xff, 0xff,
-};
-
-static struct stv0297_config dvbc_philips_tdm1316l_config = {
-       .demod_address = 0x1c,
-       .inittab = dvbc_philips_tdm1316l_inittab,
-       .invert = 0,
-};
-
-static void frontend_init(struct ttusb* ttusb)
-{
-       switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
-       case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
-               // try the stv0299 based first
-               ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
-
-                       if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
-                               alps_stv0299_config.inittab = alps_bsbe1_inittab;
-                               dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
-                       } else { // ALPS BSRU6
-                               ttusb->fe->ops.set_voltage = ttusb_set_voltage;
-                       }
-                       break;
-               }
-
-               // Grundig 29504-491
-               ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
-                       ttusb->fe->ops.set_voltage = ttusb_set_voltage;
-                       break;
-               }
-               break;
-
-       case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
-               ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
-                       break;
-               }
-
-               ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
-                       break;
-               }
-               break;
-
-       case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
-               // try the ALPS TDMB7 first
-               ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
-                       break;
-               }
-
-               // Philips td1316
-               ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
-               if (ttusb->fe != NULL) {
-                       ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
-                       ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
-                       break;
-               }
-               break;
-       }
-
-       if (ttusb->fe == NULL) {
-               printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
-                      le16_to_cpu(ttusb->dev->descriptor.idVendor),
-                      le16_to_cpu(ttusb->dev->descriptor.idProduct));
-       } else {
-               if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
-                       printk("dvb-ttusb-budget: Frontend registration failed!\n");
-                       dvb_frontend_detach(ttusb->fe);
-                       ttusb->fe = NULL;
-               }
-       }
-}
-
-
-
-static struct i2c_algorithm ttusb_dec_algo = {
-       .master_xfer    = master_xfer,
-       .functionality  = functionality,
-};
-
-static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
-       struct usb_device *udev;
-       struct ttusb *ttusb;
-       int result;
-
-       dprintk("%s: TTUSB DVB connected\n", __func__);
-
-       udev = interface_to_usbdev(intf);
-
-       if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
-
-       if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
-               return -ENOMEM;
-
-       ttusb->dev = udev;
-       ttusb->c = 0;
-       ttusb->mux_state = 0;
-       mutex_init(&ttusb->semi2c);
-
-       mutex_lock(&ttusb->semi2c);
-
-       mutex_init(&ttusb->semusb);
-
-       ttusb_setup_interfaces(ttusb);
-
-       result = ttusb_alloc_iso_urbs(ttusb);
-       if (result < 0) {
-               dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
-               mutex_unlock(&ttusb->semi2c);
-               kfree(ttusb);
-               return result;
-       }
-
-       if (ttusb_init_controller(ttusb))
-               printk("ttusb_init_controller: error\n");
-
-       mutex_unlock(&ttusb->semi2c);
-
-       result = dvb_register_adapter(&ttusb->adapter,
-                                     "Technotrend/Hauppauge Nova-USB",
-                                     THIS_MODULE, &udev->dev, adapter_nr);
-       if (result < 0) {
-               ttusb_free_iso_urbs(ttusb);
-               kfree(ttusb);
-               return result;
-       }
-       ttusb->adapter.priv = ttusb;
-
-       /* i2c */
-       memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
-       strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
-
-       i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
-
-       ttusb->i2c_adap.algo              = &ttusb_dec_algo;
-       ttusb->i2c_adap.algo_data         = NULL;
-       ttusb->i2c_adap.dev.parent        = &udev->dev;
-
-       result = i2c_add_adapter(&ttusb->i2c_adap);
-       if (result)
-               goto err_unregister_adapter;
-
-       memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
-
-       ttusb->dvb_demux.dmx.capabilities =
-           DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       ttusb->dvb_demux.priv = NULL;
-#ifdef TTUSB_HWSECTIONS
-       ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
-#else
-       ttusb->dvb_demux.filternum = 32;
-#endif
-       ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
-       ttusb->dvb_demux.start_feed = ttusb_start_feed;
-       ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
-       ttusb->dvb_demux.write_to_decoder = NULL;
-
-       result = dvb_dmx_init(&ttusb->dvb_demux);
-       if (result < 0) {
-               printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
-               result = -ENODEV;
-               goto err_i2c_del_adapter;
-       }
-//FIXME dmxdev (nur WAS?)
-       ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
-       ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
-       ttusb->dmxdev.capabilities = 0;
-
-       result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter);
-       if (result < 0) {
-               printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
-                      result);
-               result = -ENODEV;
-               goto err_release_dmx;
-       }
-
-       if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
-               printk("ttusb_dvb: dvb_net_init failed!\n");
-               result = -ENODEV;
-               goto err_release_dmxdev;
-       }
-
-       usb_set_intfdata(intf, (void *) ttusb);
-
-       frontend_init(ttusb);
-
-       return 0;
-
-err_release_dmxdev:
-       dvb_dmxdev_release(&ttusb->dmxdev);
-err_release_dmx:
-       dvb_dmx_release(&ttusb->dvb_demux);
-err_i2c_del_adapter:
-       i2c_del_adapter(&ttusb->i2c_adap);
-err_unregister_adapter:
-       dvb_unregister_adapter (&ttusb->adapter);
-       return result;
-}
-
-static void ttusb_disconnect(struct usb_interface *intf)
-{
-       struct ttusb *ttusb = usb_get_intfdata(intf);
-
-       usb_set_intfdata(intf, NULL);
-
-       ttusb->disconnecting = 1;
-
-       ttusb_stop_iso_xfer(ttusb);
-
-       ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
-       dvb_net_release(&ttusb->dvbnet);
-       dvb_dmxdev_release(&ttusb->dmxdev);
-       dvb_dmx_release(&ttusb->dvb_demux);
-       if (ttusb->fe != NULL) {
-               dvb_unregister_frontend(ttusb->fe);
-               dvb_frontend_detach(ttusb->fe);
-       }
-       i2c_del_adapter(&ttusb->i2c_adap);
-       dvb_unregister_adapter(&ttusb->adapter);
-
-       ttusb_free_iso_urbs(ttusb);
-
-       kfree(ttusb);
-
-       dprintk("%s: TTUSB DVB disconnected\n", __func__);
-}
-
-static struct usb_device_id ttusb_table[] = {
-       {USB_DEVICE(0xb48, 0x1003)},
-       {USB_DEVICE(0xb48, 0x1004)},
-       {USB_DEVICE(0xb48, 0x1005)},
-       {}
-};
-
-MODULE_DEVICE_TABLE(usb, ttusb_table);
-
-static struct usb_driver ttusb_driver = {
-      .name            = "ttusb",
-      .probe           = ttusb_probe,
-      .disconnect      = ttusb_disconnect,
-      .id_table                = ttusb_table,
-};
-
-module_usb_driver(ttusb_driver);
-
-MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
-MODULE_DESCRIPTION("TTUSB DVB Driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
deleted file mode 100644 (file)
index 290254a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-config DVB_TTUSB_DEC
-       tristate "Technotrend/Hauppauge USB DEC devices"
-       depends on DVB_CORE && USB && INPUT && PCI
-       select CRC32
-       help
-         Support for external USB adapters designed by Technotrend and
-         produced by Hauppauge, shipped under the brand name 'DEC2000-t'
-         and 'DEC3000-s'.
-
-         Even if these devices have a MPEG decoder built in, they transmit
-         only compressed MPEG data over the USB bus, so you need
-         an external software decoder to watch TV on your computer.
-
-         This driver needs external firmware. Please use the commands
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
-         download/extract them, and then copy them to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile
deleted file mode 100644 (file)
index 5352740..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
-
-ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
deleted file mode 100644 (file)
index 504c812..0000000
+++ /dev/null
@@ -1,1764 +0,0 @@
-/*
- * TTUSB DEC Driver
- *
- * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
- * IR support by Peter Beutner <p.beutner@gmx.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/crc32.h>
-#include <linux/init.h>
-#include <linux/input.h>
-
-#include <linux/mutex.h>
-
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_filter.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "ttusbdecfe.h"
-
-static int debug;
-static int output_pva;
-static int enable_rc;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-module_param(output_pva, int, 0444);
-MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
-module_param(enable_rc, int, 0644);
-MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define dprintk        if (debug) printk
-
-#define DRIVER_NAME            "TechnoTrend/Hauppauge DEC USB"
-
-#define COMMAND_PIPE           0x03
-#define RESULT_PIPE            0x04
-#define IN_PIPE                        0x08
-#define OUT_PIPE               0x07
-#define IRQ_PIPE               0x0A
-
-#define COMMAND_PACKET_SIZE    0x3c
-#define ARM_PACKET_SIZE                0x1000
-#define IRQ_PACKET_SIZE                0x8
-
-#define ISO_BUF_COUNT          0x04
-#define FRAMES_PER_ISO_BUF     0x04
-#define ISO_FRAME_SIZE         0x0380
-
-#define        MAX_PVA_LENGTH          6144
-
-enum ttusb_dec_model {
-       TTUSB_DEC2000T,
-       TTUSB_DEC2540T,
-       TTUSB_DEC3000S
-};
-
-enum ttusb_dec_packet_type {
-       TTUSB_DEC_PACKET_PVA,
-       TTUSB_DEC_PACKET_SECTION,
-       TTUSB_DEC_PACKET_EMPTY
-};
-
-enum ttusb_dec_interface {
-       TTUSB_DEC_INTERFACE_INITIAL,
-       TTUSB_DEC_INTERFACE_IN,
-       TTUSB_DEC_INTERFACE_OUT
-};
-
-struct ttusb_dec {
-       enum ttusb_dec_model            model;
-       char                            *model_name;
-       char                            *firmware_name;
-       int                             can_playback;
-
-       /* DVB bits */
-       struct dvb_adapter              adapter;
-       struct dmxdev                   dmxdev;
-       struct dvb_demux                demux;
-       struct dmx_frontend             frontend;
-       struct dvb_net                  dvb_net;
-       struct dvb_frontend*            fe;
-
-       u16                     pid[DMX_PES_OTHER];
-
-       /* USB bits */
-       struct usb_device               *udev;
-       u8                              trans_count;
-       unsigned int                    command_pipe;
-       unsigned int                    result_pipe;
-       unsigned int                    in_pipe;
-       unsigned int                    out_pipe;
-       unsigned int                    irq_pipe;
-       enum ttusb_dec_interface        interface;
-       struct mutex                    usb_mutex;
-
-       void                    *irq_buffer;
-       struct urb              *irq_urb;
-       dma_addr_t              irq_dma_handle;
-       void                    *iso_buffer;
-       dma_addr_t              iso_dma_handle;
-       struct urb              *iso_urb[ISO_BUF_COUNT];
-       int                     iso_stream_count;
-       struct mutex            iso_mutex;
-
-       u8                              packet[MAX_PVA_LENGTH + 4];
-       enum ttusb_dec_packet_type      packet_type;
-       int                             packet_state;
-       int                             packet_length;
-       int                             packet_payload_length;
-       u16                             next_packet_id;
-
-       int                             pva_stream_count;
-       int                             filter_stream_count;
-
-       struct dvb_filter_pes2ts        a_pes2ts;
-       struct dvb_filter_pes2ts        v_pes2ts;
-
-       u8                      v_pes[16 + MAX_PVA_LENGTH];
-       int                     v_pes_length;
-       int                     v_pes_postbytes;
-
-       struct list_head        urb_frame_list;
-       struct tasklet_struct   urb_tasklet;
-       spinlock_t              urb_frame_list_lock;
-
-       struct dvb_demux_filter *audio_filter;
-       struct dvb_demux_filter *video_filter;
-       struct list_head        filter_info_list;
-       spinlock_t              filter_info_list_lock;
-
-       struct input_dev        *rc_input_dev;
-       char                    rc_phys[64];
-
-       int                     active; /* Loaded successfully */
-};
-
-struct urb_frame {
-       u8                      data[ISO_FRAME_SIZE];
-       int                     length;
-       struct list_head        urb_frame_list;
-};
-
-struct filter_info {
-       u8                      stream_id;
-       struct dvb_demux_filter *filter;
-       struct list_head        filter_info_list;
-};
-
-static u16 rc_keys[] = {
-       KEY_POWER,
-       KEY_MUTE,
-       KEY_1,
-       KEY_2,
-       KEY_3,
-       KEY_4,
-       KEY_5,
-       KEY_6,
-       KEY_7,
-       KEY_8,
-       KEY_9,
-       KEY_0,
-       KEY_CHANNELUP,
-       KEY_VOLUMEDOWN,
-       KEY_OK,
-       KEY_VOLUMEUP,
-       KEY_CHANNELDOWN,
-       KEY_PREVIOUS,
-       KEY_ESC,
-       KEY_RED,
-       KEY_GREEN,
-       KEY_YELLOW,
-       KEY_BLUE,
-       KEY_OPTION,
-       KEY_M,
-       KEY_RADIO
-};
-
-static void ttusb_dec_set_model(struct ttusb_dec *dec,
-                               enum ttusb_dec_model model);
-
-static void ttusb_dec_handle_irq( struct urb *urb)
-{
-       struct ttusb_dec * dec = urb->context;
-       char *buffer = dec->irq_buffer;
-       int retval;
-
-       switch(urb->status) {
-               case 0: /*success*/
-                       break;
-               case -ECONNRESET:
-               case -ENOENT:
-               case -ESHUTDOWN:
-               case -ETIME:
-                       /* this urb is dead, cleanup */
-                       dprintk("%s:urb shutting down with status: %d\n",
-                                       __func__, urb->status);
-                       return;
-               default:
-                       dprintk("%s:nonzero status received: %d\n",
-                                       __func__,urb->status);
-                       goto exit;
-       }
-
-       if( (buffer[0] == 0x1) && (buffer[2] == 0x15) )  {
-               /* IR - Event */
-               /* this is an fact a bit too simple implementation;
-                * the box also reports a keyrepeat signal
-                * (with buffer[3] == 0x40) in an intervall of ~100ms.
-                * But to handle this correctly we had to imlemenent some
-                * kind of timer which signals a 'key up' event if no
-                * keyrepeat signal is received for lets say 200ms.
-                * this should/could be added later ...
-                * for now lets report each signal as a key down and up*/
-               dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
-               input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
-               input_sync(dec->rc_input_dev);
-               input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
-               input_sync(dec->rc_input_dev);
-       }
-
-exit:  retval = usb_submit_urb(urb, GFP_ATOMIC);
-       if(retval)
-               printk("%s - usb_commit_urb failed with result: %d\n",
-                       __func__, retval);
-}
-
-static u16 crc16(u16 crc, const u8 *buf, size_t len)
-{
-       u16 tmp;
-
-       while (len--) {
-               crc ^= *buf++;
-               crc ^= (u8)crc >> 4;
-               tmp = (u8)crc;
-               crc ^= (tmp ^ (tmp << 1)) << 4;
-       }
-       return crc;
-}
-
-static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
-                                 int param_length, const u8 params[],
-                                 int *result_length, u8 cmd_result[])
-{
-       int result, actual_len, i;
-       u8 *b;
-
-       dprintk("%s\n", __func__);
-
-       b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
-       if (!b)
-               return -ENOMEM;
-
-       if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
-               kfree(b);
-               printk("%s: Failed to lock usb mutex.\n", __func__);
-               return result;
-       }
-
-       b[0] = 0xaa;
-       b[1] = ++dec->trans_count;
-       b[2] = command;
-       b[3] = param_length;
-
-       if (params)
-               memcpy(&b[4], params, param_length);
-
-       if (debug) {
-               printk("%s: command: ", __func__);
-               for (i = 0; i < param_length + 4; i++)
-                       printk("0x%02X ", b[i]);
-               printk("\n");
-       }
-
-       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
-                             COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
-
-       if (result) {
-               printk("%s: command bulk message failed: error %d\n",
-                      __func__, result);
-               mutex_unlock(&dec->usb_mutex);
-               kfree(b);
-               return result;
-       }
-
-       result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
-                             COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
-
-       if (result) {
-               printk("%s: result bulk message failed: error %d\n",
-                      __func__, result);
-               mutex_unlock(&dec->usb_mutex);
-               kfree(b);
-               return result;
-       } else {
-               if (debug) {
-                       printk("%s: result: ", __func__);
-                       for (i = 0; i < actual_len; i++)
-                               printk("0x%02X ", b[i]);
-                       printk("\n");
-               }
-
-               if (result_length)
-                       *result_length = b[3];
-               if (cmd_result && b[3] > 0)
-                       memcpy(cmd_result, &b[4], b[3]);
-
-               mutex_unlock(&dec->usb_mutex);
-
-               kfree(b);
-               return 0;
-       }
-}
-
-static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
-                                   unsigned int *model, unsigned int *version)
-{
-       u8 c[COMMAND_PACKET_SIZE];
-       int c_length;
-       int result;
-       __be32 tmp;
-
-       dprintk("%s\n", __func__);
-
-       result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
-       if (result)
-               return result;
-
-       if (c_length >= 0x0c) {
-               if (mode != NULL) {
-                       memcpy(&tmp, c, 4);
-                       *mode = ntohl(tmp);
-               }
-               if (model != NULL) {
-                       memcpy(&tmp, &c[4], 4);
-                       *model = ntohl(tmp);
-               }
-               if (version != NULL) {
-                       memcpy(&tmp, &c[8], 4);
-                       *version = ntohl(tmp);
-               }
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
-{
-       struct ttusb_dec *dec = priv;
-
-       dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
-                                      &dec->audio_filter->feed->feed.ts,
-                                      DMX_OK);
-
-       return 0;
-}
-
-static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
-{
-       struct ttusb_dec *dec = priv;
-
-       dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
-                                      &dec->video_filter->feed->feed.ts,
-                                      DMX_OK);
-
-       return 0;
-}
-
-static void ttusb_dec_set_pids(struct ttusb_dec *dec)
-{
-       u8 b[] = { 0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0xff, 0xff,
-                  0xff, 0xff, 0xff, 0xff };
-
-       __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
-       __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
-       __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
-
-       dprintk("%s\n", __func__);
-
-       memcpy(&b[0], &pcr, 2);
-       memcpy(&b[2], &audio, 2);
-       memcpy(&b[4], &video, 2);
-
-       ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
-
-       dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
-                              ttusb_dec_audio_pes2ts_cb, dec);
-       dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
-                              ttusb_dec_video_pes2ts_cb, dec);
-       dec->v_pes_length = 0;
-       dec->v_pes_postbytes = 0;
-}
-
-static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
-{
-       if (length < 8) {
-               printk("%s: packet too short - discarding\n", __func__);
-               return;
-       }
-
-       if (length > 8 + MAX_PVA_LENGTH) {
-               printk("%s: packet too long - discarding\n", __func__);
-               return;
-       }
-
-       switch (pva[2]) {
-
-       case 0x01: {            /* VideoStream */
-               int prebytes = pva[5] & 0x03;
-               int postbytes = (pva[5] & 0x0c) >> 2;
-               __be16 v_pes_payload_length;
-
-               if (output_pva) {
-                       dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
-                               &dec->video_filter->feed->feed.ts, DMX_OK);
-                       return;
-               }
-
-               if (dec->v_pes_postbytes > 0 &&
-                   dec->v_pes_postbytes == prebytes) {
-                       memcpy(&dec->v_pes[dec->v_pes_length],
-                              &pva[12], prebytes);
-
-                       dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
-                                         dec->v_pes_length + prebytes, 1);
-               }
-
-               if (pva[5] & 0x10) {
-                       dec->v_pes[7] = 0x80;
-                       dec->v_pes[8] = 0x05;
-
-                       dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
-                       dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
-                                        ((pva[9] & 0xc0) >> 6);
-                       dec->v_pes[11] = 0x01 |
-                                        ((pva[9] & 0x3f) << 2) |
-                                        ((pva[10] & 0x80) >> 6);
-                       dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
-                                        ((pva[11] & 0xc0) >> 7);
-                       dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
-
-                       memcpy(&dec->v_pes[14], &pva[12 + prebytes],
-                              length - 12 - prebytes);
-                       dec->v_pes_length = 14 + length - 12 - prebytes;
-               } else {
-                       dec->v_pes[7] = 0x00;
-                       dec->v_pes[8] = 0x00;
-
-                       memcpy(&dec->v_pes[9], &pva[8], length - 8);
-                       dec->v_pes_length = 9 + length - 8;
-               }
-
-               dec->v_pes_postbytes = postbytes;
-
-               if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
-                   dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
-                   dec->v_pes[11 + dec->v_pes[8]] == 0x01)
-                       dec->v_pes[6] = 0x84;
-               else
-                       dec->v_pes[6] = 0x80;
-
-               v_pes_payload_length = htons(dec->v_pes_length - 6 +
-                                            postbytes);
-               memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
-
-               if (postbytes == 0)
-                       dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
-                                         dec->v_pes_length, 1);
-
-               break;
-       }
-
-       case 0x02:              /* MainAudioStream */
-               if (output_pva) {
-                       dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
-                               &dec->audio_filter->feed->feed.ts, DMX_OK);
-                       return;
-               }
-
-               dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
-                                 pva[5] & 0x10);
-               break;
-
-       default:
-               printk("%s: unknown PVA type: %02x.\n", __func__,
-                      pva[2]);
-               break;
-       }
-}
-
-static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
-                                    int length)
-{
-       struct list_head *item;
-       struct filter_info *finfo;
-       struct dvb_demux_filter *filter = NULL;
-       unsigned long flags;
-       u8 sid;
-
-       sid = packet[1];
-       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
-       for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
-            item = item->next) {
-               finfo = list_entry(item, struct filter_info, filter_info_list);
-               if (finfo->stream_id == sid) {
-                       filter = finfo->filter;
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
-
-       if (filter)
-               filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
-                                    &filter->filter, DMX_OK);
-}
-
-static void ttusb_dec_process_packet(struct ttusb_dec *dec)
-{
-       int i;
-       u16 csum = 0;
-       u16 packet_id;
-
-       if (dec->packet_length % 2) {
-               printk("%s: odd sized packet - discarding\n", __func__);
-               return;
-       }
-
-       for (i = 0; i < dec->packet_length; i += 2)
-               csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
-
-       if (csum) {
-               printk("%s: checksum failed - discarding\n", __func__);
-               return;
-       }
-
-       packet_id = dec->packet[dec->packet_length - 4] << 8;
-       packet_id += dec->packet[dec->packet_length - 3];
-
-       if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
-               printk("%s: warning: lost packets between %u and %u\n",
-                      __func__, dec->next_packet_id - 1, packet_id);
-       }
-
-       if (packet_id == 0xffff)
-               dec->next_packet_id = 0x8000;
-       else
-               dec->next_packet_id = packet_id + 1;
-
-       switch (dec->packet_type) {
-       case TTUSB_DEC_PACKET_PVA:
-               if (dec->pva_stream_count)
-                       ttusb_dec_process_pva(dec, dec->packet,
-                                             dec->packet_payload_length);
-               break;
-
-       case TTUSB_DEC_PACKET_SECTION:
-               if (dec->filter_stream_count)
-                       ttusb_dec_process_filter(dec, dec->packet,
-                                                dec->packet_payload_length);
-               break;
-
-       case TTUSB_DEC_PACKET_EMPTY:
-               break;
-       }
-}
-
-static void swap_bytes(u8 *b, int length)
-{
-       u8 c;
-
-       length -= length % 2;
-       for (; length; b += 2, length -= 2) {
-               c = *b;
-               *b = *(b + 1);
-               *(b + 1) = c;
-       }
-}
-
-static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
-                                       int length)
-{
-       swap_bytes(b, length);
-
-       while (length) {
-               switch (dec->packet_state) {
-
-               case 0:
-               case 1:
-               case 2:
-                       if (*b++ == 0xaa)
-                               dec->packet_state++;
-                       else
-                               dec->packet_state = 0;
-
-                       length--;
-                       break;
-
-               case 3:
-                       if (*b == 0x00) {
-                               dec->packet_state++;
-                               dec->packet_length = 0;
-                       } else if (*b != 0xaa) {
-                               dec->packet_state = 0;
-                       }
-
-                       b++;
-                       length--;
-                       break;
-
-               case 4:
-                       dec->packet[dec->packet_length++] = *b++;
-
-                       if (dec->packet_length == 2) {
-                               if (dec->packet[0] == 'A' &&
-                                   dec->packet[1] == 'V') {
-                                       dec->packet_type =
-                                               TTUSB_DEC_PACKET_PVA;
-                                       dec->packet_state++;
-                               } else if (dec->packet[0] == 'S') {
-                                       dec->packet_type =
-                                               TTUSB_DEC_PACKET_SECTION;
-                                       dec->packet_state++;
-                               } else if (dec->packet[0] == 0x00) {
-                                       dec->packet_type =
-                                               TTUSB_DEC_PACKET_EMPTY;
-                                       dec->packet_payload_length = 2;
-                                       dec->packet_state = 7;
-                               } else {
-                                       printk("%s: unknown packet type: "
-                                              "%02x%02x\n", __func__,
-                                              dec->packet[0], dec->packet[1]);
-                                       dec->packet_state = 0;
-                               }
-                       }
-
-                       length--;
-                       break;
-
-               case 5:
-                       dec->packet[dec->packet_length++] = *b++;
-
-                       if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
-                           dec->packet_length == 8) {
-                               dec->packet_state++;
-                               dec->packet_payload_length = 8 +
-                                       (dec->packet[6] << 8) +
-                                       dec->packet[7];
-                       } else if (dec->packet_type ==
-                                       TTUSB_DEC_PACKET_SECTION &&
-                                  dec->packet_length == 5) {
-                               dec->packet_state++;
-                               dec->packet_payload_length = 5 +
-                                       ((dec->packet[3] & 0x0f) << 8) +
-                                       dec->packet[4];
-                       }
-
-                       length--;
-                       break;
-
-               case 6: {
-                       int remainder = dec->packet_payload_length -
-                                       dec->packet_length;
-
-                       if (length >= remainder) {
-                               memcpy(dec->packet + dec->packet_length,
-                                      b, remainder);
-                               dec->packet_length += remainder;
-                               b += remainder;
-                               length -= remainder;
-                               dec->packet_state++;
-                       } else {
-                               memcpy(&dec->packet[dec->packet_length],
-                                      b, length);
-                               dec->packet_length += length;
-                               length = 0;
-                       }
-
-                       break;
-               }
-
-               case 7: {
-                       int tail = 4;
-
-                       dec->packet[dec->packet_length++] = *b++;
-
-                       if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
-                           dec->packet_payload_length % 2)
-                               tail++;
-
-                       if (dec->packet_length ==
-                           dec->packet_payload_length + tail) {
-                               ttusb_dec_process_packet(dec);
-                               dec->packet_state = 0;
-                       }
-
-                       length--;
-                       break;
-               }
-
-               default:
-                       printk("%s: illegal packet state encountered.\n",
-                              __func__);
-                       dec->packet_state = 0;
-               }
-       }
-}
-
-static void ttusb_dec_process_urb_frame_list(unsigned long data)
-{
-       struct ttusb_dec *dec = (struct ttusb_dec *)data;
-       struct list_head *item;
-       struct urb_frame *frame;
-       unsigned long flags;
-
-       while (1) {
-               spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
-               if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
-                       frame = list_entry(item, struct urb_frame,
-                                          urb_frame_list);
-                       list_del(&frame->urb_frame_list);
-               } else {
-                       spin_unlock_irqrestore(&dec->urb_frame_list_lock,
-                                              flags);
-                       return;
-               }
-               spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
-
-               ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
-               kfree(frame);
-       }
-}
-
-static void ttusb_dec_process_urb(struct urb *urb)
-{
-       struct ttusb_dec *dec = urb->context;
-
-       if (!urb->status) {
-               int i;
-
-               for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
-                       struct usb_iso_packet_descriptor *d;
-                       u8 *b;
-                       int length;
-                       struct urb_frame *frame;
-
-                       d = &urb->iso_frame_desc[i];
-                       b = urb->transfer_buffer + d->offset;
-                       length = d->actual_length;
-
-                       if ((frame = kmalloc(sizeof(struct urb_frame),
-                                            GFP_ATOMIC))) {
-                               unsigned long flags;
-
-                               memcpy(frame->data, b, length);
-                               frame->length = length;
-
-                               spin_lock_irqsave(&dec->urb_frame_list_lock,
-                                                    flags);
-                               list_add_tail(&frame->urb_frame_list,
-                                             &dec->urb_frame_list);
-                               spin_unlock_irqrestore(&dec->urb_frame_list_lock,
-                                                      flags);
-
-                               tasklet_schedule(&dec->urb_tasklet);
-                       }
-               }
-       } else {
-                /* -ENOENT is expected when unlinking urbs */
-               if (urb->status != -ENOENT)
-                       dprintk("%s: urb error: %d\n", __func__,
-                               urb->status);
-       }
-
-       if (dec->iso_stream_count)
-               usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
-{
-       int i, j, buffer_offset = 0;
-
-       dprintk("%s\n", __func__);
-
-       for (i = 0; i < ISO_BUF_COUNT; i++) {
-               int frame_offset = 0;
-               struct urb *urb = dec->iso_urb[i];
-
-               urb->dev = dec->udev;
-               urb->context = dec;
-               urb->complete = ttusb_dec_process_urb;
-               urb->pipe = dec->in_pipe;
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->interval = 1;
-               urb->number_of_packets = FRAMES_PER_ISO_BUF;
-               urb->transfer_buffer_length = ISO_FRAME_SIZE *
-                                             FRAMES_PER_ISO_BUF;
-               urb->transfer_buffer = dec->iso_buffer + buffer_offset;
-               buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-
-               for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
-                       frame_offset += ISO_FRAME_SIZE;
-               }
-       }
-}
-
-static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
-{
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       if (mutex_lock_interruptible(&dec->iso_mutex))
-               return;
-
-       dec->iso_stream_count--;
-
-       if (!dec->iso_stream_count) {
-               for (i = 0; i < ISO_BUF_COUNT; i++)
-                       usb_kill_urb(dec->iso_urb[i]);
-       }
-
-       mutex_unlock(&dec->iso_mutex);
-}
-
-/* Setting the interface of the DEC tends to take down the USB communications
- * for a short period, so it's important not to call this function just before
- * trying to talk to it.
- */
-static int ttusb_dec_set_interface(struct ttusb_dec *dec,
-                                  enum ttusb_dec_interface interface)
-{
-       int result = 0;
-       u8 b[] = { 0x05 };
-
-       if (interface != dec->interface) {
-               switch (interface) {
-               case TTUSB_DEC_INTERFACE_INITIAL:
-                       result = usb_set_interface(dec->udev, 0, 0);
-                       break;
-               case TTUSB_DEC_INTERFACE_IN:
-                       result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
-                                                       b, NULL, NULL);
-                       if (result)
-                               return result;
-                       result = usb_set_interface(dec->udev, 0, 8);
-                       break;
-               case TTUSB_DEC_INTERFACE_OUT:
-                       result = usb_set_interface(dec->udev, 0, 1);
-                       break;
-               }
-
-               if (result)
-                       return result;
-
-               dec->interface = interface;
-       }
-
-       return 0;
-}
-
-static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
-{
-       int i, result;
-
-       dprintk("%s\n", __func__);
-
-       if (mutex_lock_interruptible(&dec->iso_mutex))
-               return -EAGAIN;
-
-       if (!dec->iso_stream_count) {
-               ttusb_dec_setup_urbs(dec);
-
-               dec->packet_state = 0;
-               dec->v_pes_postbytes = 0;
-               dec->next_packet_id = 0;
-
-               for (i = 0; i < ISO_BUF_COUNT; i++) {
-                       if ((result = usb_submit_urb(dec->iso_urb[i],
-                                                    GFP_ATOMIC))) {
-                               printk("%s: failed urb submission %d: "
-                                      "error %d\n", __func__, i, result);
-
-                               while (i) {
-                                       usb_kill_urb(dec->iso_urb[i - 1]);
-                                       i--;
-                               }
-
-                               mutex_unlock(&dec->iso_mutex);
-                               return result;
-                       }
-               }
-       }
-
-       dec->iso_stream_count++;
-
-       mutex_unlock(&dec->iso_mutex);
-
-       return 0;
-}
-
-static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-       struct ttusb_dec *dec = dvbdmx->priv;
-       u8 b0[] = { 0x05 };
-       int result = 0;
-
-       dprintk("%s\n", __func__);
-
-       dprintk("  ts_type:");
-
-       if (dvbdmxfeed->ts_type & TS_DECODER)
-               dprintk(" TS_DECODER");
-
-       if (dvbdmxfeed->ts_type & TS_PACKET)
-               dprintk(" TS_PACKET");
-
-       if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
-               dprintk(" TS_PAYLOAD_ONLY");
-
-       dprintk("\n");
-
-       switch (dvbdmxfeed->pes_type) {
-
-       case DMX_TS_PES_VIDEO:
-               dprintk("  pes_type: DMX_TS_PES_VIDEO\n");
-               dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
-               dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
-               dec->video_filter = dvbdmxfeed->filter;
-               ttusb_dec_set_pids(dec);
-               break;
-
-       case DMX_TS_PES_AUDIO:
-               dprintk("  pes_type: DMX_TS_PES_AUDIO\n");
-               dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
-               dec->audio_filter = dvbdmxfeed->filter;
-               ttusb_dec_set_pids(dec);
-               break;
-
-       case DMX_TS_PES_TELETEXT:
-               dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
-               dprintk("  pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
-               return -ENOSYS;
-
-       case DMX_TS_PES_PCR:
-               dprintk("  pes_type: DMX_TS_PES_PCR\n");
-               dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
-               ttusb_dec_set_pids(dec);
-               break;
-
-       case DMX_TS_PES_OTHER:
-               dprintk("  pes_type: DMX_TS_PES_OTHER(not supported)\n");
-               return -ENOSYS;
-
-       default:
-               dprintk("  pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
-               return -EINVAL;
-
-       }
-
-       result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
-       if (result)
-               return result;
-
-       dec->pva_stream_count++;
-       return ttusb_dec_start_iso_xfer(dec);
-}
-
-static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
-       u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x00, 0xff, 0x00, 0x00,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x00 };
-       __be16 pid;
-       u8 c[COMMAND_PACKET_SIZE];
-       int c_length;
-       int result;
-       struct filter_info *finfo;
-       unsigned long flags;
-       u8 x = 1;
-
-       dprintk("%s\n", __func__);
-
-       pid = htons(dvbdmxfeed->pid);
-       memcpy(&b0[0], &pid, 2);
-       memcpy(&b0[4], &x, 1);
-       memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
-
-       result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
-                                       &c_length, c);
-
-       if (!result) {
-               if (c_length == 2) {
-                       if (!(finfo = kmalloc(sizeof(struct filter_info),
-                                             GFP_ATOMIC)))
-                               return -ENOMEM;
-
-                       finfo->stream_id = c[1];
-                       finfo->filter = dvbdmxfeed->filter;
-
-                       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
-                       list_add_tail(&finfo->filter_info_list,
-                                     &dec->filter_info_list);
-                       spin_unlock_irqrestore(&dec->filter_info_list_lock,
-                                              flags);
-
-                       dvbdmxfeed->priv = finfo;
-
-                       dec->filter_stream_count++;
-                       return ttusb_dec_start_iso_xfer(dec);
-               }
-
-               return -EAGAIN;
-       } else
-               return result;
-}
-
-static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-
-       dprintk("%s\n", __func__);
-
-       if (!dvbdmx->dmx.frontend)
-               return -EINVAL;
-
-       dprintk("  pid: 0x%04X\n", dvbdmxfeed->pid);
-
-       switch (dvbdmxfeed->type) {
-
-       case DMX_TYPE_TS:
-               return ttusb_dec_start_ts_feed(dvbdmxfeed);
-               break;
-
-       case DMX_TYPE_SEC:
-               return ttusb_dec_start_sec_feed(dvbdmxfeed);
-               break;
-
-       default:
-               dprintk("  type: unknown (%d)\n", dvbdmxfeed->type);
-               return -EINVAL;
-
-       }
-}
-
-static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
-       u8 b0[] = { 0x00 };
-
-       ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
-
-       dec->pva_stream_count--;
-
-       ttusb_dec_stop_iso_xfer(dec);
-
-       return 0;
-}
-
-static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
-       u8 b0[] = { 0x00, 0x00 };
-       struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
-       unsigned long flags;
-
-       b0[1] = finfo->stream_id;
-       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
-       list_del(&finfo->filter_info_list);
-       spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
-       kfree(finfo);
-       ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
-
-       dec->filter_stream_count--;
-
-       ttusb_dec_stop_iso_xfer(dec);
-
-       return 0;
-}
-
-static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       dprintk("%s\n", __func__);
-
-       switch (dvbdmxfeed->type) {
-       case DMX_TYPE_TS:
-               return ttusb_dec_stop_ts_feed(dvbdmxfeed);
-               break;
-
-       case DMX_TYPE_SEC:
-               return ttusb_dec_stop_sec_feed(dvbdmxfeed);
-               break;
-       }
-
-       return 0;
-}
-
-static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
-{
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       for (i = 0; i < ISO_BUF_COUNT; i++)
-               usb_free_urb(dec->iso_urb[i]);
-
-       pci_free_consistent(NULL,
-                           ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
-                                             ISO_BUF_COUNT),
-                           dec->iso_buffer, dec->iso_dma_handle);
-}
-
-static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
-{
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       dec->iso_buffer = pci_alloc_consistent(NULL,
-                                              ISO_FRAME_SIZE *
-                                              (FRAMES_PER_ISO_BUF *
-                                               ISO_BUF_COUNT),
-                                              &dec->iso_dma_handle);
-
-       if (!dec->iso_buffer) {
-               dprintk("%s: pci_alloc_consistent - not enough memory\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       memset(dec->iso_buffer, 0,
-              ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
-
-       for (i = 0; i < ISO_BUF_COUNT; i++) {
-               struct urb *urb;
-
-               if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
-                       ttusb_dec_free_iso_urbs(dec);
-                       return -ENOMEM;
-               }
-
-               dec->iso_urb[i] = urb;
-       }
-
-       ttusb_dec_setup_urbs(dec);
-
-       return 0;
-}
-
-static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
-{
-       spin_lock_init(&dec->urb_frame_list_lock);
-       INIT_LIST_HEAD(&dec->urb_frame_list);
-       tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
-                    (unsigned long)dec);
-}
-
-static int ttusb_init_rc( struct ttusb_dec *dec)
-{
-       struct input_dev *input_dev;
-       u8 b[] = { 0x00, 0x01 };
-       int i;
-       int err;
-
-       usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
-       strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
-
-       input_dev = input_allocate_device();
-       if (!input_dev)
-               return -ENOMEM;
-
-       input_dev->name = "ttusb_dec remote control";
-       input_dev->phys = dec->rc_phys;
-       input_dev->evbit[0] = BIT_MASK(EV_KEY);
-       input_dev->keycodesize = sizeof(u16);
-       input_dev->keycodemax = 0x1a;
-       input_dev->keycode = rc_keys;
-
-       for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
-                 set_bit(rc_keys[i], input_dev->keybit);
-
-       err = input_register_device(input_dev);
-       if (err) {
-               input_free_device(input_dev);
-               return err;
-       }
-
-       dec->rc_input_dev = input_dev;
-       if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
-               printk("%s: usb_submit_urb failed\n",__func__);
-       /* enable irq pipe */
-       ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
-
-       return 0;
-}
-
-static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
-{
-       dprintk("%s\n", __func__);
-
-       dec->v_pes[0] = 0x00;
-       dec->v_pes[1] = 0x00;
-       dec->v_pes[2] = 0x01;
-       dec->v_pes[3] = 0xe0;
-}
-
-static int ttusb_dec_init_usb(struct ttusb_dec *dec)
-{
-       dprintk("%s\n", __func__);
-
-       mutex_init(&dec->usb_mutex);
-       mutex_init(&dec->iso_mutex);
-
-       dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
-       dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
-       dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
-       dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
-       dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
-
-       if(enable_rc) {
-               dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
-               if(!dec->irq_urb) {
-                       return -ENOMEM;
-               }
-               dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
-                                       GFP_ATOMIC, &dec->irq_dma_handle);
-               if(!dec->irq_buffer) {
-                       usb_free_urb(dec->irq_urb);
-                       return -ENOMEM;
-               }
-               usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
-                                dec->irq_buffer, IRQ_PACKET_SIZE,
-                                ttusb_dec_handle_irq, dec, 1);
-               dec->irq_urb->transfer_dma = dec->irq_dma_handle;
-               dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-       }
-
-       return ttusb_dec_alloc_iso_urbs(dec);
-}
-
-static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
-{
-       int i, j, actual_len, result, size, trans_count;
-       u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
-                   0x00, 0x00, 0x00, 0x00,
-                   0x61, 0x00 };
-       u8 b1[] = { 0x61 };
-       u8 *b;
-       char idstring[21];
-       const u8 *firmware = NULL;
-       size_t firmware_size = 0;
-       u16 firmware_csum = 0;
-       __be16 firmware_csum_ns;
-       __be32 firmware_size_nl;
-       u32 crc32_csum, crc32_check;
-       __be32 tmp;
-       const struct firmware *fw_entry = NULL;
-
-       dprintk("%s\n", __func__);
-
-       if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
-               printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
-                      __func__, dec->firmware_name);
-               return 1;
-       }
-
-       firmware = fw_entry->data;
-       firmware_size = fw_entry->size;
-
-       if (firmware_size < 60) {
-               printk("%s: firmware size too small for DSP code (%zu < 60).\n",
-                       __func__, firmware_size);
-               release_firmware(fw_entry);
-               return -1;
-       }
-
-       /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
-          at offset 56 of file, so use it to check if the firmware file is
-          valid. */
-       crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
-       memcpy(&tmp, &firmware[56], 4);
-       crc32_check = ntohl(tmp);
-       if (crc32_csum != crc32_check) {
-               printk("%s: crc32 check of DSP code failed (calculated "
-                      "0x%08x != 0x%08x in file), file invalid.\n",
-                       __func__, crc32_csum, crc32_check);
-               release_firmware(fw_entry);
-               return -1;
-       }
-       memcpy(idstring, &firmware[36], 20);
-       idstring[20] = '\0';
-       printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
-
-       firmware_size_nl = htonl(firmware_size);
-       memcpy(b0, &firmware_size_nl, 4);
-       firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
-       firmware_csum_ns = htons(firmware_csum);
-       memcpy(&b0[6], &firmware_csum_ns, 2);
-
-       result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
-
-       if (result) {
-               release_firmware(fw_entry);
-               return result;
-       }
-
-       trans_count = 0;
-       j = 0;
-
-       b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
-       if (b == NULL) {
-               release_firmware(fw_entry);
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
-               size = firmware_size - i;
-               if (size > COMMAND_PACKET_SIZE)
-                       size = COMMAND_PACKET_SIZE;
-
-               b[j + 0] = 0xaa;
-               b[j + 1] = trans_count++;
-               b[j + 2] = 0xf0;
-               b[j + 3] = size;
-               memcpy(&b[j + 4], &firmware[i], size);
-
-               j += COMMAND_PACKET_SIZE + 4;
-
-               if (j >= ARM_PACKET_SIZE) {
-                       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
-                                             ARM_PACKET_SIZE, &actual_len,
-                                             100);
-                       j = 0;
-               } else if (size < COMMAND_PACKET_SIZE) {
-                       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
-                                             j - COMMAND_PACKET_SIZE + size,
-                                             &actual_len, 100);
-               }
-       }
-
-       result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
-
-       release_firmware(fw_entry);
-       kfree(b);
-
-       return result;
-}
-
-static int ttusb_dec_init_stb(struct ttusb_dec *dec)
-{
-       int result;
-       unsigned int mode = 0, model = 0, version = 0;
-
-       dprintk("%s\n", __func__);
-
-       result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
-
-       if (!result) {
-               if (!mode) {
-                       if (version == 0xABCDEFAB)
-                               printk(KERN_INFO "ttusb_dec: no version "
-                                      "info in Firmware\n");
-                       else
-                               printk(KERN_INFO "ttusb_dec: Firmware "
-                                      "%x.%02x%c%c\n",
-                                      version >> 24, (version >> 16) & 0xff,
-                                      (version >> 8) & 0xff, version & 0xff);
-
-                       result = ttusb_dec_boot_dsp(dec);
-                       if (result)
-                               return result;
-                       else
-                               return 1;
-               } else {
-                       /* We can't trust the USB IDs that some firmwares
-                          give the box */
-                       switch (model) {
-                       case 0x00070001:
-                       case 0x00070008:
-                       case 0x0007000c:
-                               ttusb_dec_set_model(dec, TTUSB_DEC3000S);
-                               break;
-                       case 0x00070009:
-                       case 0x00070013:
-                               ttusb_dec_set_model(dec, TTUSB_DEC2000T);
-                               break;
-                       case 0x00070011:
-                               ttusb_dec_set_model(dec, TTUSB_DEC2540T);
-                               break;
-                       default:
-                               printk(KERN_ERR "%s: unknown model returned "
-                                      "by firmware (%08x) - please report\n",
-                                      __func__, model);
-                               return -1;
-                               break;
-                       }
-
-                       if (version >= 0x01770000)
-                               dec->can_playback = 1;
-
-                       return 0;
-               }
-       }
-       else
-               return result;
-}
-
-static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
-{
-       int result;
-
-       dprintk("%s\n", __func__);
-
-       if ((result = dvb_register_adapter(&dec->adapter,
-                                          dec->model_name, THIS_MODULE,
-                                          &dec->udev->dev,
-                                          adapter_nr)) < 0) {
-               printk("%s: dvb_register_adapter failed: error %d\n",
-                      __func__, result);
-
-               return result;
-       }
-
-       dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-
-       dec->demux.priv = (void *)dec;
-       dec->demux.filternum = 31;
-       dec->demux.feednum = 31;
-       dec->demux.start_feed = ttusb_dec_start_feed;
-       dec->demux.stop_feed = ttusb_dec_stop_feed;
-       dec->demux.write_to_decoder = NULL;
-
-       if ((result = dvb_dmx_init(&dec->demux)) < 0) {
-               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
-                      result);
-
-               dvb_unregister_adapter(&dec->adapter);
-
-               return result;
-       }
-
-       dec->dmxdev.filternum = 32;
-       dec->dmxdev.demux = &dec->demux.dmx;
-       dec->dmxdev.capabilities = 0;
-
-       if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
-               printk("%s: dvb_dmxdev_init failed: error %d\n",
-                      __func__, result);
-
-               dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(&dec->adapter);
-
-               return result;
-       }
-
-       dec->frontend.source = DMX_FRONTEND_0;
-
-       if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
-                                                 &dec->frontend)) < 0) {
-               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
-                      result);
-
-               dvb_dmxdev_release(&dec->dmxdev);
-               dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(&dec->adapter);
-
-               return result;
-       }
-
-       if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
-                                                     &dec->frontend)) < 0) {
-               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
-                      result);
-
-               dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
-               dvb_dmxdev_release(&dec->dmxdev);
-               dvb_dmx_release(&dec->demux);
-               dvb_unregister_adapter(&dec->adapter);
-
-               return result;
-       }
-
-       dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
-
-       return 0;
-}
-
-static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
-{
-       dprintk("%s\n", __func__);
-
-       dvb_net_release(&dec->dvb_net);
-       dec->demux.dmx.close(&dec->demux.dmx);
-       dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
-       dvb_dmxdev_release(&dec->dmxdev);
-       dvb_dmx_release(&dec->demux);
-       if (dec->fe) {
-               dvb_unregister_frontend(dec->fe);
-               if (dec->fe->ops.release)
-                       dec->fe->ops.release(dec->fe);
-       }
-       dvb_unregister_adapter(&dec->adapter);
-}
-
-static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
-{
-
-       dprintk("%s\n", __func__);
-       /* we have to check whether the irq URB is already submitted.
-         * As the irq is submitted after the interface is changed,
-         * this is the best method i figured out.
-         * Any others?*/
-       if (dec->interface == TTUSB_DEC_INTERFACE_IN)
-               usb_kill_urb(dec->irq_urb);
-
-       usb_free_urb(dec->irq_urb);
-
-       usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,
-                         dec->irq_buffer, dec->irq_dma_handle);
-
-       if (dec->rc_input_dev) {
-               input_unregister_device(dec->rc_input_dev);
-               dec->rc_input_dev = NULL;
-       }
-}
-
-
-static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
-{
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       dec->iso_stream_count = 0;
-
-       for (i = 0; i < ISO_BUF_COUNT; i++)
-               usb_kill_urb(dec->iso_urb[i]);
-
-       ttusb_dec_free_iso_urbs(dec);
-}
-
-static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
-{
-       struct list_head *item;
-       struct urb_frame *frame;
-
-       tasklet_kill(&dec->urb_tasklet);
-
-       while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
-               frame = list_entry(item, struct urb_frame, urb_frame_list);
-               list_del(&frame->urb_frame_list);
-               kfree(frame);
-       }
-}
-
-static void ttusb_dec_init_filters(struct ttusb_dec *dec)
-{
-       INIT_LIST_HEAD(&dec->filter_info_list);
-       spin_lock_init(&dec->filter_info_list_lock);
-}
-
-static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
-{
-       struct list_head *item;
-       struct filter_info *finfo;
-
-       while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
-               finfo = list_entry(item, struct filter_info, filter_info_list);
-               list_del(&finfo->filter_info_list);
-               kfree(finfo);
-       }
-}
-
-static int fe_send_command(struct dvb_frontend* fe, const u8 command,
-                          int param_length, const u8 params[],
-                          int *result_length, u8 cmd_result[])
-{
-       struct ttusb_dec* dec = fe->dvb->priv;
-       return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
-}
-
-static struct ttusbdecfe_config fe_config = {
-       .send_command = fe_send_command
-};
-
-static int ttusb_dec_probe(struct usb_interface *intf,
-                          const struct usb_device_id *id)
-{
-       struct usb_device *udev;
-       struct ttusb_dec *dec;
-
-       dprintk("%s\n", __func__);
-
-       udev = interface_to_usbdev(intf);
-
-       if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
-               printk("%s: couldn't allocate memory.\n", __func__);
-               return -ENOMEM;
-       }
-
-       usb_set_intfdata(intf, (void *)dec);
-
-       switch (id->idProduct) {
-       case 0x1006:
-               ttusb_dec_set_model(dec, TTUSB_DEC3000S);
-               break;
-
-       case 0x1008:
-               ttusb_dec_set_model(dec, TTUSB_DEC2000T);
-               break;
-
-       case 0x1009:
-               ttusb_dec_set_model(dec, TTUSB_DEC2540T);
-               break;
-       }
-
-       dec->udev = udev;
-
-       if (ttusb_dec_init_usb(dec))
-               return 0;
-       if (ttusb_dec_init_stb(dec)) {
-               ttusb_dec_exit_usb(dec);
-               return 0;
-       }
-       ttusb_dec_init_dvb(dec);
-
-       dec->adapter.priv = dec;
-       switch (id->idProduct) {
-       case 0x1006:
-               dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
-               break;
-
-       case 0x1008:
-       case 0x1009:
-               dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
-               break;
-       }
-
-       if (dec->fe == NULL) {
-               printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
-                      le16_to_cpu(dec->udev->descriptor.idVendor),
-                      le16_to_cpu(dec->udev->descriptor.idProduct));
-       } else {
-               if (dvb_register_frontend(&dec->adapter, dec->fe)) {
-                       printk("budget-ci: Frontend registration failed!\n");
-                       if (dec->fe->ops.release)
-                               dec->fe->ops.release(dec->fe);
-                       dec->fe = NULL;
-               }
-       }
-
-       ttusb_dec_init_v_pes(dec);
-       ttusb_dec_init_filters(dec);
-       ttusb_dec_init_tasklet(dec);
-
-       dec->active = 1;
-
-       ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
-
-       if (enable_rc)
-               ttusb_init_rc(dec);
-
-       return 0;
-}
-
-static void ttusb_dec_disconnect(struct usb_interface *intf)
-{
-       struct ttusb_dec *dec = usb_get_intfdata(intf);
-
-       usb_set_intfdata(intf, NULL);
-
-       dprintk("%s\n", __func__);
-
-       if (dec->active) {
-               ttusb_dec_exit_tasklet(dec);
-               ttusb_dec_exit_filters(dec);
-               if(enable_rc)
-                       ttusb_dec_exit_rc(dec);
-               ttusb_dec_exit_usb(dec);
-               ttusb_dec_exit_dvb(dec);
-       }
-
-       kfree(dec);
-}
-
-static void ttusb_dec_set_model(struct ttusb_dec *dec,
-                               enum ttusb_dec_model model)
-{
-       dec->model = model;
-
-       switch (model) {
-       case TTUSB_DEC2000T:
-               dec->model_name = "DEC2000-t";
-               dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
-               break;
-
-       case TTUSB_DEC2540T:
-               dec->model_name = "DEC2540-t";
-               dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
-               break;
-
-       case TTUSB_DEC3000S:
-               dec->model_name = "DEC3000-s";
-               dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
-               break;
-       }
-}
-
-static struct usb_device_id ttusb_dec_table[] = {
-       {USB_DEVICE(0x0b48, 0x1006)},   /* DEC3000-s */
-       /*{USB_DEVICE(0x0b48, 0x1007)},    Unconfirmed */
-       {USB_DEVICE(0x0b48, 0x1008)},   /* DEC2000-t */
-       {USB_DEVICE(0x0b48, 0x1009)},   /* DEC2540-t */
-       {}
-};
-
-static struct usb_driver ttusb_dec_driver = {
-       .name           = "ttusb-dec",
-       .probe          = ttusb_dec_probe,
-       .disconnect     = ttusb_dec_disconnect,
-       .id_table       = ttusb_dec_table,
-};
-
-module_usb_driver(ttusb_dec_driver);
-
-MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
-MODULE_DESCRIPTION(DRIVER_NAME);
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
deleted file mode 100644 (file)
index 5c45c9d..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * TTUSB DEC Frontend Driver
- *
- * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.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.
- *
- */
-
-#include "dvb_frontend.h"
-#include "ttusbdecfe.h"
-
-
-#define LOF_HI                 10600000
-#define LOF_LO                 9750000
-
-struct ttusbdecfe_state {
-
-       /* configuration settings */
-       const struct ttusbdecfe_config* config;
-
-       struct dvb_frontend frontend;
-
-       u8 hi_band;
-       u8 voltage;
-};
-
-
-static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
-       fe_status_t *status)
-{
-       *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
-               FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
-       return 0;
-}
-
-
-static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
-       fe_status_t *status)
-{
-       struct ttusbdecfe_state* state = fe->demodulator_priv;
-       u8 b[] = { 0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00 };
-       u8 result[4];
-       int len, ret;
-
-       *status=0;
-
-       ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
-       if(ret)
-               return ret;
-
-       if(len != 4) {
-               printk(KERN_ERR "%s: unexpected reply\n", __func__);
-               return -EIO;
-       }
-
-       switch(result[3]) {
-               case 1:  /* not tuned yet */
-               case 2:  /* no signal/no lock*/
-                       break;
-               case 3:  /* signal found and locked*/
-                       *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
-                       FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
-                       break;
-               case 4:
-                       *status = FE_TIMEDOUT;
-                       break;
-               default:
-                       pr_info("%s: returned unknown value: %d\n",
-                               __func__, result[3]);
-                       return -EIO;
-       }
-
-       return 0;
-}
-
-static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-       u8 b[] = { 0x00, 0x00, 0x00, 0x03,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x01,
-                  0x00, 0x00, 0x00, 0xff,
-                  0x00, 0x00, 0x00, 0xff };
-
-       __be32 freq = htonl(p->frequency / 1000);
-       memcpy(&b[4], &freq, sizeof (u32));
-       state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
-
-       return 0;
-}
-
-static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
-                                       struct dvb_frontend_tune_settings* fesettings)
-{
-               fesettings->min_delay_ms = 1500;
-               /* Drift compensation makes no sense for DVB-T */
-               fesettings->step_size = 0;
-               fesettings->max_drift = 0;
-               return 0;
-}
-
-static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-
-       u8 b[] = { 0x00, 0x00, 0x00, 0x01,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x01,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00 };
-       __be32 freq;
-       __be32 sym_rate;
-       __be32 band;
-       __be32 lnb_voltage;
-
-       freq = htonl(p->frequency +
-              (state->hi_band ? LOF_HI : LOF_LO));
-       memcpy(&b[4], &freq, sizeof(u32));
-       sym_rate = htonl(p->symbol_rate);
-       memcpy(&b[12], &sym_rate, sizeof(u32));
-       band = htonl(state->hi_band ? LOF_HI : LOF_LO);
-       memcpy(&b[24], &band, sizeof(u32));
-       lnb_voltage = htonl(state->voltage);
-       memcpy(&b[28], &lnb_voltage, sizeof(u32));
-
-       state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
-
-       return 0;
-}
-
-static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-       u8 b[] = { 0x00, 0xff, 0x00, 0x00,
-                  0x00, 0x00, 0x00, 0x00,
-                  0x00, 0x00 };
-
-       memcpy(&b[4], cmd->msg, cmd->msg_len);
-
-       state->config->send_command(fe, 0x72,
-                                   sizeof(b) - (6 - cmd->msg_len), b,
-                                   NULL, NULL);
-
-       return 0;
-}
-
-
-static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-
-       state->hi_band = (SEC_TONE_ON == tone);
-
-       return 0;
-}
-
-
-static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               state->voltage = 13;
-               break;
-       case SEC_VOLTAGE_18:
-               state->voltage = 18;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void ttusbdecfe_release(struct dvb_frontend* fe)
-{
-       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
-
-struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
-{
-       struct ttusbdecfe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       /* setup the state */
-       state->config = config;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
-
-struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
-{
-       struct ttusbdecfe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       /* setup the state */
-       state->config = config;
-       state->voltage = 0;
-       state->hi_band = 0;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
-               .frequency_min          = 51000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = ttusbdecfe_release,
-
-       .set_frontend = ttusbdecfe_dvbt_set_frontend,
-
-       .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
-
-       .read_status = ttusbdecfe_dvbt_read_status,
-};
-
-static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 125,
-               .symbol_rate_min        = 1000000,  /* guessed */
-               .symbol_rate_max        = 45000000, /* guessed */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK
-       },
-
-       .release = ttusbdecfe_release,
-
-       .set_frontend = ttusbdecfe_dvbs_set_frontend,
-
-       .read_status = ttusbdecfe_dvbs_read_status,
-
-       .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
-       .set_voltage = ttusbdecfe_dvbs_set_voltage,
-       .set_tone = ttusbdecfe_dvbs_set_tone,
-};
-
-MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
-MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
-EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
deleted file mode 100644 (file)
index 15ccc3d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * TTUSB DEC Driver
- *
- * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.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.
- *
- */
-
-#ifndef TTUSBDECFE_H
-#define TTUSBDECFE_H
-
-#include <linux/dvb/frontend.h>
-
-struct ttusbdecfe_config
-{
-       int (*send_command)(struct dvb_frontend* fe, const u8 command,
-                           int param_length, const u8 params[],
-                           int *result_length, u8 cmd_result[]);
-};
-
-extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config);
-
-extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config);
-
-#endif // TTUSBDECFE_H
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
new file mode 100644 (file)
index 0000000..70b1708
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# USB media device configuration
+#
+
+menuconfig MEDIA_USB_DRIVERS
+       bool "Supported DVB USB Adapters"
+        depends on USB
+        default y
+
+if MEDIA_USB_DRIVERS && DVB_CORE && I2C
+
+source "drivers/media/usb/dvb-usb/Kconfig"
+source "drivers/media/usb/dvb-usb-v2/Kconfig"
+source "drivers/media/usb/ttusb-budget/Kconfig"
+source "drivers/media/usb/ttusb-dec/Kconfig"
+source "drivers/media/usb/siano/Kconfig"
+
+endif
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
new file mode 100644 (file)
index 0000000..44e29f3
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the USB media device drivers
+#
+
+# DVB USB-only drivers
+obj-y := ttusb-dec/ ttusb-budget/ dvb-usb/ dvb-usb-v2/ siano/
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
new file mode 100644 (file)
index 0000000..276374f
--- /dev/null
@@ -0,0 +1,146 @@
+config DVB_USB_V2
+       tristate "Support for various USB DVB devices v2"
+       depends on DVB_CORE && USB && I2C && RC_CORE
+       help
+         By enabling this you will be able to choose the various supported
+         USB1.1 and USB2.0 DVB devices.
+
+         Almost every USB device needs a firmware, please look into
+         <file:Documentation/dvb/README.dvb-usb>.
+
+         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+         Say Y if you own a USB DVB device.
+
+config DVB_USB_CYPRESS_FIRMWARE
+       tristate "Cypress firmware helper routines"
+       depends on DVB_USB_V2
+
+config DVB_USB_AF9015
+       tristate "Afatech AF9015 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_AF9013
+       select DVB_PLL              if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_AF9035
+       tristate "Afatech AF9035 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_AF9033
+       select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Afatech AF9035 based DVB USB receiver.
+
+config DVB_USB_ANYSEE
+       tristate "Anysee DVB-T/C USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
+       select DVB_CX24116 if !DVB_FE_CUSTOMISE
+       select DVB_STV0900 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110 if !DVB_FE_CUSTOMISE
+       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
+       select DVB_CXD2820R if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Anysee E30, Anysee E30 Plus or
+         Anysee E30 C Plus DVB USB2.0 receiver.
+
+config DVB_USB_AU6610
+       tristate "Alcor Micro AU6610 USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
+
+config DVB_USB_AZ6007
+       tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_USB_CYPRESS_FIRMWARE
+       select DVB_DRXK if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the AZ6007 receivers like Terratec H7.
+
+config DVB_USB_CE6230
+       tristate "Intel CE6230 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
+
+config DVB_USB_EC168
+       tristate "E3C EC168 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_EC100
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
+
+config DVB_USB_GL861
+       tristate "Genesys Logic GL861 USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
+         receiver with USB ID 0db0:5581.
+
+config DVB_USB_IT913X
+       tristate "ITE IT913X DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_IT913X_FE
+       help
+         Say Y here to support the ITE IT913X DVB-T USB2.0
+
+config DVB_USB_LME2510
+       tristate "LME DM04/QQBOX DVB-S USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+       select DVB_TDA826X if !DVB_FE_CUSTOMISE
+       select DVB_STV0288 if !DVB_FE_CUSTOMISE
+       select DVB_IX2505V if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the LME DM04/QQBOX DVB-S USB2.0
+
+config DVB_USB_MXL111SF
+       tristate "MxL111SF DTV USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+       select DVB_LG2160 if !DVB_FE_CUSTOMISE
+       select VIDEO_TVEEPROM
+       help
+         Say Y here to support the MxL111SF USB2.0 DTV receiver.
+
+config DVB_USB_RTL28XXU
+       tristate "Realtek RTL28xxU DVB USB support"
+       depends on DVB_USB_V2 && EXPERIMENTAL
+       select DVB_RTL2830
+       select DVB_RTL2832
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Realtek RTL28xxU DVB USB receiver.
+
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
new file mode 100644 (file)
index 0000000..24248b3
--- /dev/null
@@ -0,0 +1,48 @@
+dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o
+obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o
+
+dvb_usb_cypress_firmware-objs = cypress_firmware.o
+obj-$(CONFIG_DVB_USB_CYPRESS_FIRMWARE) += dvb_usb_cypress_firmware.o
+
+dvb-usb-af9015-objs = af9015.o
+obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
+
+dvb-usb-af9035-objs = af9035.o
+obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
+
+dvb-usb-anysee-objs = anysee.o
+obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
+
+dvb-usb-au6610-objs = au6610.o
+obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
+
+dvb-usb-az6007-objs = az6007.o
+obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
+
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
+
+dvb-usb-ec168-objs = ec168.o
+obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
+
+dvb-usb-it913x-objs = it913x.o
+obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
+
+dvb-usb-lmedm04-objs = lmedm04.o
+obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
+
+dvb-usb-gl861-objs = gl861.o
+obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
+
+dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
+
+dvb-usb-rtl28xxu-objs = rtl28xxu.o
+obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
+ccflags-y += -I$(srctree)/drivers/media/common/tuners
+
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
new file mode 100644 (file)
index 0000000..e77429b
--- /dev/null
@@ -0,0 +1,1434 @@
+/*
+ * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ *    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 "af9015.h"
+
+static int dvb_usb_af9015_debug;
+module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+static int dvb_usb_af9015_remote;
+module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
+MODULE_PARM_DESC(remote, "select remote");
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+#define BUF_LEN 63
+#define REQ_HDR_LEN 8 /* send header size */
+#define ACK_HDR_LEN 2 /* rece header size */
+       struct af9015_state *state = d_to_priv(d);
+       int ret, wlen, rlen;
+       u8 buf[BUF_LEN];
+       u8 write = 1;
+
+       buf[0] = req->cmd;
+       buf[1] = state->seq++;
+       buf[2] = req->i2c_addr;
+       buf[3] = req->addr >> 8;
+       buf[4] = req->addr & 0xff;
+       buf[5] = req->mbox;
+       buf[6] = req->addr_len;
+       buf[7] = req->data_len;
+
+       switch (req->cmd) {
+       case GET_CONFIG:
+       case READ_MEMORY:
+       case RECONNECT_USB:
+               write = 0;
+               break;
+       case READ_I2C:
+               write = 0;
+               buf[2] |= 0x01; /* set I2C direction */
+       case WRITE_I2C:
+               buf[0] = READ_WRITE_I2C;
+               break;
+       case WRITE_MEMORY:
+               if (((req->addr & 0xff00) == 0xff00) ||
+                   ((req->addr & 0xff00) == 0xae00))
+                       buf[0] = WRITE_VIRTUAL_MEMORY;
+       case WRITE_VIRTUAL_MEMORY:
+       case COPY_FIRMWARE:
+       case DOWNLOAD_FIRMWARE:
+       case BOOT:
+               break;
+       default:
+               err("unknown command:%d", req->cmd);
+               ret = -1;
+               goto error;
+       }
+
+       /* buffer overflow check */
+       if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
+               (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
+               err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* write receives seq + status = 2 bytes
+          read receives seq + status + data = 2 + N bytes */
+       wlen = REQ_HDR_LEN;
+       rlen = ACK_HDR_LEN;
+       if (write) {
+               wlen += req->data_len;
+               memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
+       } else {
+               rlen += req->data_len;
+       }
+
+       /* no ack for these packets */
+       if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
+               rlen = 0;
+
+       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+       if (ret)
+               goto error;
+
+       /* check status */
+       if (rlen && buf[1]) {
+               err("command failed:%d", buf[1]);
+               ret = -1;
+               goto error;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (!write)
+               memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
+error:
+       return ret;
+}
+
+static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
+       u8 len)
+{
+       struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+               val};
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
+{
+       struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+               val};
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
+{
+       return af9015_write_regs(d, addr, &val, 1);
+}
+
+static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
+{
+       return af9015_read_regs(d, addr, val, 1);
+}
+
+static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+       u8 val)
+{
+       struct af9015_state *state = d_to_priv(d);
+       struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
+
+       if (addr == state->af9013_config[0].i2c_addr ||
+           addr == state->af9013_config[1].i2c_addr)
+               req.addr_len = 3;
+
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+       u8 *val)
+{
+       struct af9015_state *state = d_to_priv(d);
+       struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
+
+       if (addr == state->af9013_config[0].i2c_addr ||
+           addr == state->af9013_config[1].i2c_addr)
+               req.addr_len = 3;
+
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
+{
+       int ret;
+       u8 val, mask = 0x01;
+
+       ret = af9015_read_reg(d, addr, &val);
+       if (ret)
+               return ret;
+
+       mask <<= bit;
+       if (op) {
+               /* set bit */
+               val |= mask;
+       } else {
+               /* clear bit */
+               mask ^= 0xff;
+               val &= mask;
+       }
+
+       return af9015_write_reg(d, addr, val);
+}
+
+static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+       return af9015_do_reg_bit(d, addr, bit, 1);
+}
+
+static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+       return af9015_do_reg_bit(d, addr, bit, 0);
+}
+
+static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct af9015_state *state = d_to_priv(d);
+       int ret = 0, i = 0;
+       u16 addr;
+       u8 uninitialized_var(mbox), addr_len;
+       struct req_t req;
+
+/*
+The bus lock is needed because there is two tuners both using same I2C-address.
+Due to that the only way to select correct tuner is use demodulator I2C-gate.
+
+................................................
+. AF9015 includes integrated AF9013 demodulator.
+. ____________                   ____________  .                ____________
+.|     uC     |                 |   demod    | .               |    tuner   |
+.|------------|                 |------------| .               |------------|
+.|   AF9015   |                 |  AF9013/5  | .               |   MXL5003  |
+.|            |--+----I2C-------|-----/ -----|-.-----I2C-------|            |
+.|            |  |              | addr 0x38  | .               |  addr 0xc6 |
+.|____________|  |              |____________| .               |____________|
+.................|..............................
+                |               ____________                   ____________
+                |              |   demod    |                 |    tuner   |
+                |              |------------|                 |------------|
+                |              |   AF9013   |                 |   MXL5003  |
+                +----I2C-------|-----/ -----|-------I2C-------|            |
+                               | addr 0x3a  |                 |  addr 0xc6 |
+                               |____________|                 |____________|
+*/
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (msg[i].addr == state->af9013_config[0].i2c_addr ||
+                   msg[i].addr == state->af9013_config[1].i2c_addr) {
+                       addr = msg[i].buf[0] << 8;
+                       addr += msg[i].buf[1];
+                       mbox = msg[i].buf[2];
+                       addr_len = 3;
+               } else {
+                       addr = msg[i].buf[0];
+                       addr_len = 1;
+                       /* mbox is don't care in that case */
+               }
+
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].len > 3 || msg[i+1].len > 61) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
+                               req.cmd = READ_MEMORY;
+                       else
+                               req.cmd = READ_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i+1].len;
+                       req.data = &msg[i+1].buf[0];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 2;
+               } else if (msg[i].flags & I2C_M_RD) {
+                       if (msg[i].len > 61) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr) {
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       req.cmd = READ_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i].len;
+                       req.data = &msg[i].buf[0];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 1;
+               } else {
+                       if (msg[i].len > 21) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
+                               req.cmd = WRITE_MEMORY;
+                       else
+                               req.cmd = WRITE_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i].len-addr_len;
+                       req.data = &msg[i].buf[addr_len];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 1;
+               }
+               if (ret)
+                       goto error;
+
+       }
+       ret = i;
+
+error:
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static u32 af9015_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9015_i2c_algo = {
+       .master_xfer = af9015_i2c_xfer,
+       .functionality = af9015_i2c_func,
+};
+
+static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 reply;
+       struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
+
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               return ret;
+
+       deb_info("%s: reply:%02x\n", __func__, reply);
+       if (reply == 0x02)
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+}
+
+static int af9015_download_firmware(struct dvb_usb_device *d,
+       const struct firmware *fw)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int i, len, remaining, ret;
+       struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
+       u16 checksum = 0;
+
+       deb_info("%s:\n", __func__);
+
+       /* calc checksum */
+       for (i = 0; i < fw->size; i++)
+               checksum += fw->data[i];
+
+       state->firmware_size = fw->size;
+       state->firmware_checksum = checksum;
+
+       #define FW_ADDR 0x5100 /* firmware start address */
+       #define LEN_MAX 55 /* max packet size */
+       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+               len = remaining;
+               if (len > LEN_MAX)
+                       len = LEN_MAX;
+
+               req.data_len = len;
+               req.data = (u8 *) &fw->data[fw->size - remaining];
+               req.addr = FW_ADDR + fw->size - remaining;
+
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret) {
+                       err("firmware download failed:%d", ret);
+                       goto error;
+               }
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = BOOT;
+       req.data_len = 0;
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret) {
+               err("firmware boot failed:%d", ret);
+               goto error;
+       }
+
+error:
+       return ret;
+}
+
+/* hash (and dump) eeprom */
+static int af9015_eeprom_hash(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       static const unsigned int eeprom_size = 256;
+       unsigned int reg;
+       u8 val, *eeprom;
+       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
+
+       eeprom = kmalloc(eeprom_size, GFP_KERNEL);
+       if (eeprom == NULL)
+               return -ENOMEM;
+
+       for (reg = 0; reg < eeprom_size; reg++) {
+               req.addr = reg;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto free;
+
+               eeprom[reg] = val;
+       }
+
+       if (dvb_usb_af9015_debug & 0x01)
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
+                               eeprom_size);
+
+       BUG_ON(eeprom_size % 4);
+
+       state->eeprom_sum = 0;
+       for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
+               state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
+               state->eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
+       }
+
+       deb_info("%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum);
+
+       ret = 0;
+free:
+       kfree(eeprom);
+       return ret;
+}
+
+static int af9015_read_config(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 val, i, offset = 0;
+       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
+
+       deb_info("%s:\n", __func__);
+
+       /* IR remote controller */
+       req.addr = AF9015_EEPROM_IR_MODE;
+       /* first message will timeout often due to possible hw bug */
+       for (i = 0; i < 4; i++) {
+               ret = af9015_ctrl_msg(d, &req);
+               if (!ret)
+                       break;
+       }
+       if (ret)
+               goto error;
+
+       ret = af9015_eeprom_hash(d);
+       if (ret)
+               goto error;
+
+       deb_info("%s: IR mode=%d\n", __func__, val);
+       state->ir_mode = val;
+
+       /* TS mode - one or two receivers */
+       req.addr = AF9015_EEPROM_TS_MODE;
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       state->dual_mode = val;
+       deb_info("%s: TS mode=%d\n", __func__, state->dual_mode);
+
+       /* disable 2nd adapter because we don't have PID-filters */
+       if (d->udev->speed == USB_SPEED_FULL)
+               state->dual_mode = 0;
+
+       if (state->dual_mode) {
+               /* read 2nd demodulator I2C address */
+               req.addr = AF9015_EEPROM_DEMOD2_I2C;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[1].i2c_addr = val;
+       }
+
+       for (i = 0; i < state->dual_mode + 1; i++) {
+               if (i == 1)
+                       offset = AF9015_EEPROM_OFFSET;
+               /* xtal */
+               req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               switch (val) {
+               case 0:
+                       state->af9013_config[i].clock = 28800000;
+                       break;
+               case 1:
+                       state->af9013_config[i].clock = 20480000;
+                       break;
+               case 2:
+                       state->af9013_config[i].clock = 28000000;
+                       break;
+               case 3:
+                       state->af9013_config[i].clock = 25000000;
+                       break;
+               };
+               deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
+                               val, state->af9013_config[i].clock);
+
+               /* IF frequency */
+               req.addr = AF9015_EEPROM_IF1H + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[i].if_frequency = val << 8;
+
+               req.addr = AF9015_EEPROM_IF1L + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[i].if_frequency += val;
+               state->af9013_config[i].if_frequency *= 1000;
+               deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
+                               state->af9013_config[i].if_frequency);
+
+               /* MT2060 IF1 */
+               req.addr = AF9015_EEPROM_MT2060_IF1H  + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               state->mt2060_if1[i] = val << 8;
+               req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               state->mt2060_if1[i] += val;
+               deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
+                               state->mt2060_if1[i]);
+
+               /* tuner */
+               req.addr =  AF9015_EEPROM_TUNER_ID1 + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               switch (val) {
+               case AF9013_TUNER_ENV77H11D5:
+               case AF9013_TUNER_MT2060:
+               case AF9013_TUNER_QT1010:
+               case AF9013_TUNER_UNKNOWN:
+               case AF9013_TUNER_MT2060_2:
+               case AF9013_TUNER_TDA18271:
+               case AF9013_TUNER_QT1010A:
+               case AF9013_TUNER_TDA18218:
+                       state->af9013_config[i].spec_inv = 1;
+                       break;
+               case AF9013_TUNER_MXL5003D:
+               case AF9013_TUNER_MXL5005D:
+               case AF9013_TUNER_MXL5005R:
+               case AF9013_TUNER_MXL5007T:
+                       state->af9013_config[i].spec_inv = 0;
+                       break;
+               case AF9013_TUNER_MC44S803:
+                       state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+                       state->af9013_config[i].spec_inv = 1;
+                       break;
+               default:
+                       warn("tuner id=%d not supported, please report!", val);
+                       return -ENODEV;
+               };
+
+               state->af9013_config[i].tuner = val;
+               deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
+       }
+
+error:
+       if (ret)
+               err("eeprom read failed=%d", ret);
+
+       /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
+          content :-( Override some wrong values here. Ditto for the
+          AVerTV Red HD+ (A850T) device. */
+       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
+               ((le16_to_cpu(d->udev->descriptor.idProduct) ==
+                       USB_PID_AVERMEDIA_A850) ||
+               (le16_to_cpu(d->udev->descriptor.idProduct) ==
+                       USB_PID_AVERMEDIA_A850T))) {
+               deb_info("%s: AverMedia A850: overriding config\n", __func__);
+               /* disable dual mode */
+               state->dual_mode = 0;
+
+               /* set correct IF */
+               state->af9013_config[0].if_frequency = 4570000;
+       }
+
+       return ret;
+}
+
+static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+               struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
+
+       if (fe_to_d(fe)->udev->speed == USB_SPEED_FULL)
+               stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
+
+       return 0;
+}
+
+static int af9015_get_adapter_count(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       return state->dual_mode + 1;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->set_frontend[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_read_status(struct dvb_frontend *fe,
+       fe_status_t *status)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->read_status[fe_to_adap(fe)->id](fe, status);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->init[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->sleep[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->tuner_init[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+static int af9015_copy_firmware(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 fw_params[4];
+       u8 val, i;
+       struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
+               fw_params };
+       deb_info("%s:\n", __func__);
+
+       fw_params[0] = state->firmware_size >> 8;
+       fw_params[1] = state->firmware_size & 0xff;
+       fw_params[2] = state->firmware_checksum >> 8;
+       fw_params[3] = state->firmware_checksum & 0xff;
+
+       /* wait 2nd demodulator ready */
+       msleep(100);
+
+       ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                       0x98be, &val);
+       if (ret)
+               goto error;
+       else
+               deb_info("%s: firmware status:%02x\n", __func__, val);
+
+       if (val == 0x0c) /* fw is running, no need for download */
+               goto exit;
+
+       /* set I2C master clock to fast (to speed up firmware copy) */
+       ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
+       if (ret)
+               goto error;
+
+       msleep(50);
+
+       /* copy firmware */
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               err("firmware copy cmd failed:%d", ret);
+       deb_info("%s: firmware copy done\n", __func__);
+
+       /* set I2C master clock back to normal */
+       ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
+       if (ret)
+               goto error;
+
+       /* request boot firmware */
+       ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                       0xe205, 1);
+       deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
+       if (ret)
+               goto error;
+
+       for (i = 0; i < 15; i++) {
+               msleep(100);
+
+               /* check firmware status */
+               ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                               0x98be, &val);
+               deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
+                       __func__, ret, val);
+               if (ret)
+                       goto error;
+
+               if (val == 0x0c || val == 0x04) /* success or fail */
+                       break;
+       }
+
+       if (val == 0x04) {
+               err("firmware did not run");
+               ret = -1;
+       } else if (val != 0x0c) {
+               err("firmware boot timeout");
+               ret = -1;
+       }
+
+error:
+exit:
+       return ret;
+}
+
+static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct af9015_state *state = adap_to_priv(adap);
+
+       if (adap->id == 0) {
+               state->af9013_config[0].ts_mode = AF9013_TS_USB;
+               memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
+               state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
+               state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
+       } else if (adap->id == 1) {
+               state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
+               memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
+               state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
+               state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
+
+               /* copy firmware to 2nd demodulator */
+               if (state->dual_mode) {
+                       ret = af9015_copy_firmware(adap_to_d(adap));
+                       if (ret) {
+                               err("firmware copy to 2nd frontend " \
+                                       "failed, will disable it");
+                               state->dual_mode = 0;
+                               return -ENODEV;
+                       }
+               } else {
+                       return -ENODEV;
+               }
+       }
+
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(af9013_attach,
+               &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
+
+       /*
+        * AF9015 firmware does not like if it gets interrupted by I2C adapter
+        * request on some critical phases. During normal operation I2C adapter
+        * is used only 2nd demodulator and tuner on dual tuner devices.
+        * Override demodulator callbacks and use mutex for limit access to
+        * those "critical" paths to keep AF9015 happy.
+        */
+       if (adap->fe[0]) {
+               state->set_frontend[adap->id] =
+                       adap->fe[0]->ops.set_frontend;
+               adap->fe[0]->ops.set_frontend =
+                       af9015_af9013_set_frontend;
+
+               state->read_status[adap->id] =
+                       adap->fe[0]->ops.read_status;
+               adap->fe[0]->ops.read_status =
+                       af9015_af9013_read_status;
+
+               state->init[adap->id] = adap->fe[0]->ops.init;
+               adap->fe[0]->ops.init = af9015_af9013_init;
+
+               state->sleep[adap->id] = adap->fe[0]->ops.sleep;
+               adap->fe[0]->ops.sleep = af9015_af9013_sleep;
+       }
+
+       return adap->fe[0] == NULL ? -ENODEV : 0;
+}
+
+static struct mt2060_config af9015_mt2060_config = {
+       .i2c_address = 0xc0,
+       .clock_out = 0,
+};
+
+static struct qt1010_config af9015_qt1010_config = {
+       .i2c_address = 0xc4,
+};
+
+static struct tda18271_config af9015_tda18271_config = {
+       .gate = TDA18271_GATE_DIGITAL,
+       .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
+};
+
+static struct mxl5005s_config af9015_mxl5003_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_DEFAULT,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static struct mxl5005s_config af9015_mxl5005_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_OFF,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static struct mc44s803_config af9015_mc44s803_config = {
+       .i2c_address = 0xc0,
+       .dig_out = 1,
+};
+
+static struct tda18218_config af9015_tda18218_config = {
+       .i2c_address = 0xc0,
+       .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
+};
+
+static struct mxl5007t_config af9015_mxl5007t_config = {
+       .xtal_freq_hz = MxL_XTAL_24_MHZ,
+       .if_freq_hz = MxL_IF_4_57_MHZ,
+};
+
+static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct af9015_state *state = adap_to_priv(adap);
+       int ret;
+       deb_info("%s:\n", __func__);
+
+       switch (state->af9013_config[adap->id].tuner) {
+       case AF9013_TUNER_MT2060:
+       case AF9013_TUNER_MT2060_2:
+               ret = dvb_attach(mt2060_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
+                       state->mt2060_if1[adap->id])
+                       == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_QT1010:
+       case AF9013_TUNER_QT1010A:
+               ret = dvb_attach(qt1010_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_qt1010_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_TDA18271:
+               ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_tda18271_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_TDA18218:
+               ret = dvb_attach(tda18218_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_tda18218_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5003D:
+               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5005D:
+       case AF9013_TUNER_MXL5005R:
+               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_ENV77H11D5:
+               ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
+                       &adap_to_d(adap)->i2c_adap,
+                       DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MC44S803:
+               ret = dvb_attach(mc44s803_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5007T:
+               ret = dvb_attach(mxl5007t_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_UNKNOWN:
+       default:
+               ret = -ENODEV;
+               err("Unknown tuner id:%d",
+                       state->af9013_config[adap->id].tuner);
+       }
+
+       if (adap->fe[0]->ops.tuner_ops.init) {
+               state->tuner_init[adap->id] =
+                       adap->fe[0]->ops.tuner_ops.init;
+               adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
+       }
+
+       if (adap->fe[0]->ops.tuner_ops.sleep) {
+               state->tuner_sleep[adap->id] =
+                       adap->fe[0]->ops.tuner_ops.sleep;
+               adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
+       }
+
+       return ret;
+}
+
+static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+       deb_info("%s: onoff:%d\n", __func__, onoff);
+
+       if (onoff)
+               ret = af9015_set_reg_bit(adap_to_d(adap), 0xd503, 0);
+       else
+               ret = af9015_clear_reg_bit(adap_to_d(adap), 0xd503, 0);
+
+       return ret;
+}
+
+static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+       int onoff)
+{
+       int ret;
+       u8 idx;
+
+       deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
+               __func__, index, pid, onoff);
+
+       ret = af9015_write_reg(adap_to_d(adap), 0xd505, (pid & 0xff));
+       if (ret)
+               goto error;
+
+       ret = af9015_write_reg(adap_to_d(adap), 0xd506, (pid >> 8));
+       if (ret)
+               goto error;
+
+       idx = ((index & 0x1f) | (1 << 5));
+       ret = af9015_write_reg(adap_to_d(adap), 0xd504, idx);
+
+error:
+       return ret;
+}
+
+static int af9015_init_endpoint(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u16 frame_size;
+       u8  packet_size;
+       deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
+
+       if (d->udev->speed == USB_SPEED_FULL) {
+               frame_size = TS_USB11_FRAME_SIZE/4;
+               packet_size = TS_USB11_MAX_PACKET_SIZE/4;
+       } else {
+               frame_size = TS_USB20_FRAME_SIZE/4;
+               packet_size = TS_USB20_MAX_PACKET_SIZE/4;
+       }
+
+       ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
+       if (ret)
+               goto error;
+       ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
+       if (ret)
+               goto error;
+       ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
+               if (ret)
+                       goto error;
+       }
+       ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
+               if (ret)
+                       goto error;
+       }
+       /* EP4 xfer length */
+       ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
+       if (ret)
+               goto error;
+       /* EP5 xfer length */
+       ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
+               if (ret)
+                       goto error;
+       }
+
+       /* enable / disable mp2if2 */
+       if (state->dual_mode)
+               ret = af9015_set_reg_bit(d, 0xd50b, 0);
+       else
+               ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+
+error:
+       if (ret)
+               err("endpoint init failed:%d", ret);
+       return ret;
+}
+
+static int af9015_init(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       deb_info("%s:\n", __func__);
+
+       mutex_init(&state->fe_mutex);
+
+       /* init RC canary */
+       ret = af9015_write_reg(d, 0x98e9, 0xff);
+       if (ret)
+               goto error;
+
+       ret = af9015_init_endpoint(d);
+       if (ret)
+               goto error;
+
+error:
+       return ret;
+}
+
+struct af9015_rc_setup {
+       unsigned int id;
+       char *rc_codes;
+};
+
+static char *af9015_rc_setup_match(unsigned int id,
+       const struct af9015_rc_setup *table)
+{
+       for (; table->rc_codes; table++)
+               if (table->id == id)
+                       return table->rc_codes;
+       return NULL;
+}
+
+static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
+       { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
+       { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
+       { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
+       { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
+       { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
+       { }
+};
+
+static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
+       { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
+       { 0xa3703d00, RC_MAP_ALINK_DTU_M },
+       { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
+       { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
+       { }
+};
+
+static int af9015_rc_query(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 buf[17];
+
+       deb_info("%s:\n", __func__);
+
+       /* read registers needed to detect remote controller code */
+       ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       /* If any of these are non-zero, assume invalid data */
+       if (buf[1] || buf[2] || buf[3])
+               return ret;
+
+       /* Check for repeat of previous code */
+       if ((state->rc_repeat != buf[6] || buf[0]) &&
+                       !memcmp(&buf[12], state->rc_last, 4)) {
+               deb_rc("%s: key repeated\n", __func__);
+               rc_keydown(d->rc_dev, state->rc_keycode, 0);
+               state->rc_repeat = buf[6];
+               return ret;
+       }
+
+       /* Only process key if canary killed */
+       if (buf[16] != 0xff && buf[0] != 0x01) {
+               deb_rc("%s: key pressed %*ph\n", __func__, 4, buf + 12);
+
+               /* Reset the canary */
+               ret = af9015_write_reg(d, 0x98e9, 0xff);
+               if (ret)
+                       goto error;
+
+               /* Remember this key */
+               memcpy(state->rc_last, &buf[12], 4);
+               if (buf[14] == (u8) ~buf[15]) {
+                       if (buf[12] == (u8) ~buf[13]) {
+                               /* NEC */
+                               state->rc_keycode = buf[12] << 8 | buf[14];
+                       } else {
+                               /* NEC extended*/
+                               state->rc_keycode = buf[12] << 16 |
+                                       buf[13] << 8 | buf[14];
+                       }
+               } else {
+                       /* 32 bit NEC */
+                       state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
+                                       buf[14] << 8 | buf[15];
+               }
+               rc_keydown(d->rc_dev, state->rc_keycode, 0);
+       } else {
+               deb_rc("%s: no key press\n", __func__);
+               /* Invalidate last keypress */
+               /* Not really needed, but helps with debug */
+               state->rc_last[2] = state->rc_last[3];
+       }
+
+       state->rc_repeat = buf[6];
+       state->rc_failed = false;
+
+error:
+       if (ret) {
+               err("%s: failed:%d", __func__, ret);
+
+               /* allow random errors as dvb-usb will stop polling on error */
+               if (!state->rc_failed)
+                       ret = 0;
+
+               state->rc_failed = true;
+       }
+
+       return ret;
+}
+
+static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       struct af9015_state *state = d_to_priv(d);
+       u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
+
+       if (state->ir_mode == AF9015_IR_MODE_DISABLED)
+               return 0;
+
+       /* try to load remote based module param */
+       if (!rc->map_name)
+               rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
+                               af9015_rc_setup_modparam);
+
+       /* try to load remote based eeprom hash */
+       if (!rc->map_name)
+               rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
+                               af9015_rc_setup_hashes);
+
+       /* try to load remote based USB iManufacturer string */
+       if (!rc->map_name && vid == USB_VID_AFATECH) {
+               /* Check USB manufacturer and product strings and try
+                  to determine correct remote in case of chip vendor
+                  reference IDs are used.
+                  DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
+               char manufacturer[10];
+               memset(manufacturer, 0, sizeof(manufacturer));
+               usb_string(d->udev, d->udev->descriptor.iManufacturer,
+                       manufacturer, sizeof(manufacturer));
+               if (!strcmp("MSI", manufacturer)) {
+                       /* iManufacturer 1 MSI
+                          iProduct      2 MSI K-VOX */
+                       rc->map_name = af9015_rc_setup_match(
+                                       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+                                       af9015_rc_setup_modparam);
+               }
+       }
+
+       /* load empty to enable rc */
+       if (!rc->map_name)
+               rc->map_name = RC_MAP_EMPTY;
+
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query = af9015_rc_query;
+       rc->interval = 500;
+
+       return 0;
+}
+
+/* interface 0 is used by DVB-T receiver and
+   interface 1 is for remote controller (HID) */
+static struct dvb_usb_device_properties af9015_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct af9015_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9015_identify_state,
+       .firmware = "dvb-usb-af9015.fw",
+       .download_firmware = af9015_download_firmware,
+
+       .i2c_algo = &af9015_i2c_algo,
+       .read_config = af9015_read_config,
+       .frontend_attach = af9015_af9013_frontend_attach,
+       .tuner_attach = af9015_tuner_attach,
+       .init = af9015_init,
+       .get_rc_config = af9015_get_rc_config,
+       .get_stream_config = af9015_get_stream_config,
+
+       .get_adapter_count = af9015_get_adapter_count,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .pid_filter = af9015_pid_filter,
+                       .pid_filter_ctrl = af9015_pid_filter_ctrl,
+
+                       .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
+               },
+       },
+};
+
+static const struct usb_device_id af9015_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
+               &af9015_props, "Afatech AF9015 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
+               &af9015_props, "Afatech AF9015 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
+               &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
+       { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
+               &af9015_props, "Pinnacle PCTV 71e", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
+               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
+               &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
+       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
+               &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
+               &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
+               &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
+               &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
+       { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
+               &af9015_props, "Xtensions XD-380", NULL) },
+       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
+               &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
+               &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TELESTAR,  USB_PID_TELESTAR_STARSTICK_2,
+               &af9015_props, "Telestar Starstick 2", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
+               &af9015_props, "AVerMedia A309", NULL) },
+       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
+               &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
+               &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
+               &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
+               &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
+               &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
+               &af9015_props, "KWorld Digial MC-810", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
+               &af9015_props, "Genius TVGo DVB-T03", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
+               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
+               &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
+               &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
+               &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
+               &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
+               &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
+               &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
+               &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
+               &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
+               &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
+               &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
+               &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, af9015_id_table);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver af9015_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = af9015_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(af9015_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9015 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h
new file mode 100644 (file)
index 0000000..c6b304d
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ *    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 AF9015_H
+#define AF9015_H
+
+#include <linux/hash.h>
+#include "dvb_usb.h"
+#include "af9013.h"
+#include "dvb-pll.h"
+#include "mt2060.h"
+#include "qt1010.h"
+#include "tda18271.h"
+#include "mxl5005s.h"
+#include "mc44s803.h"
+#include "tda18218.h"
+#include "mxl5007t.h"
+
+#define DVB_USB_LOG_PREFIX "af9015"
+
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var, level, args...) \
+       do { if ((var & level)) printk(args); } while (0)
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+#endif
+
+#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
+#define deb_rc(args...)   dprintk(dvb_usb_af9015_debug, 0x02, args)
+
+#undef err
+#define err(format, arg...) \
+       printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) \
+       printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
+   We use smaller - about 1/4 from the original, 5 and 87. */
+#define TS_PACKET_SIZE            188
+
+#define TS_USB20_PACKET_COUNT      87
+#define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
+
+#define TS_USB11_PACKET_COUNT       5
+#define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
+
+#define TS_USB20_MAX_PACKET_SIZE  512
+#define TS_USB11_MAX_PACKET_SIZE   64
+
+#define AF9015_I2C_EEPROM  0xa0
+#define AF9015_I2C_DEMOD   0x38
+#define AF9015_USB_TIMEOUT 2000
+
+/* EEPROM locations */
+#define AF9015_EEPROM_IR_MODE        0x18
+#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
+#define AF9015_EEPROM_TS_MODE        0x31
+#define AF9015_EEPROM_DEMOD2_I2C     0x32
+
+#define AF9015_EEPROM_SAW_BW1        0x35
+#define AF9015_EEPROM_XTAL_TYPE1     0x36
+#define AF9015_EEPROM_SPEC_INV1      0x37
+#define AF9015_EEPROM_IF1L           0x38
+#define AF9015_EEPROM_IF1H           0x39
+#define AF9015_EEPROM_MT2060_IF1L    0x3a
+#define AF9015_EEPROM_MT2060_IF1H    0x3b
+#define AF9015_EEPROM_TUNER_ID1      0x3c
+
+#define AF9015_EEPROM_SAW_BW2        0x45
+#define AF9015_EEPROM_XTAL_TYPE2     0x46
+#define AF9015_EEPROM_SPEC_INV2      0x47
+#define AF9015_EEPROM_IF2L           0x48
+#define AF9015_EEPROM_IF2H           0x49
+#define AF9015_EEPROM_MT2060_IF2L    0x4a
+#define AF9015_EEPROM_MT2060_IF2H    0x4b
+#define AF9015_EEPROM_TUNER_ID2      0x4c
+
+#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
+
+struct req_t {
+       u8  cmd;       /* [0] */
+       /*  seq */     /* [1] */
+       u8  i2c_addr;  /* [2] */
+       u16 addr;      /* [3|4] */
+       u8  mbox;      /* [5] */
+       u8  addr_len;  /* [6] */
+       u8  data_len;  /* [7] */
+       u8  *data;
+};
+
+enum af9015_cmd {
+       GET_CONFIG           = 0x10,
+       DOWNLOAD_FIRMWARE    = 0x11,
+       BOOT                 = 0x13,
+       READ_MEMORY          = 0x20,
+       WRITE_MEMORY         = 0x21,
+       READ_WRITE_I2C       = 0x22,
+       COPY_FIRMWARE        = 0x23,
+       RECONNECT_USB        = 0x5a,
+       WRITE_VIRTUAL_MEMORY = 0x26,
+       GET_IR_CODE          = 0x27,
+       READ_I2C,
+       WRITE_I2C,
+};
+
+enum af9015_ir_mode {
+       AF9015_IR_MODE_DISABLED = 0,
+       AF9015_IR_MODE_HID,
+       AF9015_IR_MODE_RLC,
+       AF9015_IR_MODE_RC6,
+       AF9015_IR_MODE_POLLING, /* just guess */
+};
+
+struct af9015_state {
+       u8 ir_mode;
+       u8 rc_repeat;
+       u32 rc_keycode;
+       u8 rc_last[4];
+       bool rc_failed;
+       u8 dual_mode;
+       u8 seq; /* packet sequence number */
+       u16 mt2060_if1[2];
+       u16 firmware_size;
+       u16 firmware_checksum;
+       u32 eeprom_sum;
+       struct af9013_config af9013_config[2];
+
+       /* for demod callback override */
+       int (*set_frontend[2]) (struct dvb_frontend *fe);
+       int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
+       int (*init[2]) (struct dvb_frontend *fe);
+       int (*sleep[2]) (struct dvb_frontend *fe);
+       int (*tuner_init[2]) (struct dvb_frontend *fe);
+       int (*tuner_sleep[2]) (struct dvb_frontend *fe);
+       struct mutex fe_mutex;
+};
+
+enum af9015_remote {
+       AF9015_REMOTE_NONE                    = 0,
+/* 1 */        AF9015_REMOTE_A_LINK_DTU_M,
+       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+       AF9015_REMOTE_MYGICTV_U718,
+       AF9015_REMOTE_DIGITTRADE_DVB_T,
+/* 5 */        AF9015_REMOTE_AVERMEDIA_KS,
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
new file mode 100644 (file)
index 0000000..bb90b87
--- /dev/null
@@ -0,0 +1,1086 @@
+/*
+ * Afatech AF9035 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "af9035.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static u16 af9035_checksum(const u8 *buf, size_t len)
+{
+       size_t i;
+       u16 checksum = 0;
+
+       for (i = 1; i < len; i++) {
+               if (i % 2)
+                       checksum += buf[i] << 8;
+               else
+                       checksum += buf[i];
+       }
+       checksum = ~checksum;
+
+       return checksum;
+}
+
+static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
+{
+#define BUF_LEN 64
+#define REQ_HDR_LEN 4 /* send header size */
+#define ACK_HDR_LEN 3 /* rece header size */
+#define CHECKSUM_LEN 2
+#define USB_TIMEOUT 2000
+       struct state *state = d_to_priv(d);
+       int ret, wlen, rlen;
+       u8 buf[BUF_LEN];
+       u16 checksum, tmp_checksum;
+
+       /* buffer overflow check */
+       if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
+               req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
+               pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
+                               req->wlen, req->rlen);
+               return -EINVAL;
+       }
+
+       buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
+       buf[1] = req->mbox;
+       buf[2] = req->cmd;
+       buf[3] = state->seq++;
+       memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
+
+       wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
+       rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
+
+       /* calc and add checksum */
+       checksum = af9035_checksum(buf, buf[0] - 1);
+       buf[buf[0] - 1] = (checksum >> 8);
+       buf[buf[0] - 0] = (checksum & 0xff);
+
+       /* no ack for these packets */
+       if (req->cmd == CMD_FW_DL)
+               rlen = 0;
+
+       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+       if (ret)
+               goto err;
+
+       /* no ack for those packets */
+       if (req->cmd == CMD_FW_DL)
+               goto exit;
+
+       /* verify checksum */
+       checksum = af9035_checksum(buf, rlen - 2);
+       tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
+       if (tmp_checksum != checksum) {
+               pr_err("%s: command=%02x checksum mismatch (%04x != %04x)\n",
+                               KBUILD_MODNAME, req->cmd, tmp_checksum,
+                               checksum);
+               ret = -EIO;
+               goto err;
+       }
+
+       /* check status */
+       if (buf[2]) {
+               pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
+                               req->cmd, buf[2]);
+               ret = -EIO;
+               goto err;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (req->rlen)
+               memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
+
+exit:
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+/* write multiple registers */
+static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
+{
+       u8 wbuf[6 + len];
+       u8 mbox = (reg >> 16) & 0xff;
+       struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
+
+       wbuf[0] = len;
+       wbuf[1] = 2;
+       wbuf[2] = 0;
+       wbuf[3] = 0;
+       wbuf[4] = (reg >> 8) & 0xff;
+       wbuf[5] = (reg >> 0) & 0xff;
+       memcpy(&wbuf[6], val, len);
+
+       return af9035_ctrl_msg(d, &req);
+}
+
+/* read multiple registers */
+static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
+{
+       u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
+       u8 mbox = (reg >> 16) & 0xff;
+       struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
+
+       return af9035_ctrl_msg(d, &req);
+}
+
+/* write single register */
+static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
+{
+       return af9035_wr_regs(d, reg, &val, 1);
+}
+
+/* read single register */
+static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
+{
+       return af9035_rd_regs(d, reg, val, 1);
+}
+
+/* write single register with mask */
+static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
+               u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = af9035_rd_regs(d, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return af9035_wr_regs(d, reg, &val, 1);
+}
+
+static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct state *state = d_to_priv(d);
+       int ret;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       /*
+        * I2C sub header is 5 bytes long. Meaning of those bytes are:
+        * 0: data len
+        * 1: I2C addr << 1
+        * 2: reg addr len
+        *    byte 3 and 4 can be used as reg addr
+        * 3: reg addr MSB
+        *    used when reg addr len is set to 2
+        * 4: reg addr LSB
+        *    used when reg addr len is set to 1 or 2
+        *
+        * For the simplify we do not use register addr at all.
+        * NOTE: As a firmware knows tuner type there is very small possibility
+        * there could be some tuner I2C hacks done by firmware and this may
+        * lead problems if firmware expects those bytes are used.
+        */
+       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
+                       (msg[1].flags & I2C_M_RD)) {
+               if (msg[0].len > 40 || msg[1].len > 40) {
+                       /* TODO: correct limits > 40 */
+                       ret = -EOPNOTSUPP;
+               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
+                       /* integrated demod */
+                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+                       ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
+                                       msg[1].len);
+               } else {
+                       /* I2C */
+                       u8 buf[5 + msg[0].len];
+                       struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+                                       buf, msg[1].len, msg[1].buf };
+                       buf[0] = msg[1].len;
+                       buf[1] = msg[0].addr << 1;
+                       buf[2] = 0x00; /* reg addr len */
+                       buf[3] = 0x00; /* reg addr MSB */
+                       buf[4] = 0x00; /* reg addr LSB */
+                       memcpy(&buf[5], msg[0].buf, msg[0].len);
+                       ret = af9035_ctrl_msg(d, &req);
+               }
+       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
+               if (msg[0].len > 40) {
+                       /* TODO: correct limits > 40 */
+                       ret = -EOPNOTSUPP;
+               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
+                       /* integrated demod */
+                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
+                                       msg[0].len - 3);
+               } else {
+                       /* I2C */
+                       u8 buf[5 + msg[0].len];
+                       struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
+                                       0, NULL };
+                       buf[0] = msg[0].len;
+                       buf[1] = msg[0].addr << 1;
+                       buf[2] = 0x00; /* reg addr len */
+                       buf[3] = 0x00; /* reg addr MSB */
+                       buf[4] = 0x00; /* reg addr LSB */
+                       memcpy(&buf[5], msg[0].buf, msg[0].len);
+                       ret = af9035_ctrl_msg(d, &req);
+               }
+       } else {
+               /*
+                * We support only two kind of I2C transactions:
+                * 1) 1 x read + 1 x write
+                * 2) 1 x write
+                */
+               ret = -EOPNOTSUPP;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       if (ret < 0)
+               return ret;
+       else
+               return num;
+}
+
+static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9035_i2c_algo = {
+       .master_xfer = af9035_i2c_master_xfer,
+       .functionality = af9035_i2c_functionality,
+};
+
+static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 wbuf[1] = { 1 };
+       u8 rbuf[4];
+       struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
+                       sizeof(rbuf), rbuf };
+
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       pr_debug("%s: reply=%*ph\n", __func__, 4, rbuf);
+       if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_download_firmware(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, i, j, len;
+       u8 wbuf[1];
+       u8 rbuf[4];
+       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
+       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+       u8 hdr_core;
+       u16 hdr_addr, hdr_data_len, hdr_checksum;
+       #define MAX_DATA 58
+       #define HDR_SIZE 7
+
+       /*
+        * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
+        *
+        * byte 0: MCS 51 core
+        *  There are two inside the AF9035 (1=Link and 2=OFDM) with separate
+        *  address spaces
+        * byte 1-2: Big endian destination address
+        * byte 3-4: Big endian number of data bytes following the header
+        * byte 5-6: Big endian header checksum, apparently ignored by the chip
+        *  Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
+        */
+
+       for (i = fw->size; i > HDR_SIZE;) {
+               hdr_core = fw->data[fw->size - i + 0];
+               hdr_addr = fw->data[fw->size - i + 1] << 8;
+               hdr_addr |= fw->data[fw->size - i + 2] << 0;
+               hdr_data_len = fw->data[fw->size - i + 3] << 8;
+               hdr_data_len |= fw->data[fw->size - i + 4] << 0;
+               hdr_checksum = fw->data[fw->size - i + 5] << 8;
+               hdr_checksum |= fw->data[fw->size - i + 6] << 0;
+
+               pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
+                               __func__, hdr_core, hdr_addr, hdr_data_len,
+                               hdr_checksum);
+
+               if (((hdr_core != 1) && (hdr_core != 2)) ||
+                               (hdr_data_len > i)) {
+                       pr_debug("%s: bad firmware\n", __func__);
+                       break;
+               }
+
+               /* download begin packet */
+               req.cmd = CMD_FW_DL_BEGIN;
+               ret = af9035_ctrl_msg(d, &req);
+               if (ret < 0)
+                       goto err;
+
+               /* download firmware packet(s) */
+               for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
+                       len = j;
+                       if (len > MAX_DATA)
+                               len = MAX_DATA;
+                       req_fw_dl.wlen = len;
+                       req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
+                                       HDR_SIZE + hdr_data_len - j];
+                       ret = af9035_ctrl_msg(d, &req_fw_dl);
+                       if (ret < 0)
+                               goto err;
+               }
+
+               /* download end packet */
+               req.cmd = CMD_FW_DL_END;
+               ret = af9035_ctrl_msg(d, &req);
+               if (ret < 0)
+                       goto err;
+
+               i -= hdr_data_len + HDR_SIZE;
+
+               pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = CMD_FW_BOOT;
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       /* ensure firmware starts */
+       wbuf[0] = 1;
+       ret = af9035_ctrl_msg(d, &req_fw_ver);
+       if (ret < 0)
+               goto err;
+
+       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
+               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
+                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, i, i_prev;
+       u8 wbuf[1];
+       u8 rbuf[4];
+       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+       #define HDR_SIZE 7
+
+       /*
+        * There seems to be following firmware header. Meaning of bytes 0-3
+        * is unknown.
+        *
+        * 0: 3
+        * 1: 0, 1
+        * 2: 0
+        * 3: 1, 2, 3
+        * 4: addr MSB
+        * 5: addr LSB
+        * 6: count of data bytes ?
+        */
+
+       for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
+               if (i == fw->size ||
+                               (fw->data[i + 0] == 0x03 &&
+                               (fw->data[i + 1] == 0x00 ||
+                               fw->data[i + 1] == 0x01) &&
+                               fw->data[i + 2] == 0x00)) {
+                       req_fw_dl.wlen = i - i_prev;
+                       req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
+                       i_prev = i;
+                       ret = af9035_ctrl_msg(d, &req_fw_dl);
+                       if (ret < 0)
+                               goto err;
+
+                       pr_debug("%s: data uploaded=%d\n", __func__, i);
+               }
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = CMD_FW_BOOT;
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       /* ensure firmware starts */
+       wbuf[0] = 1;
+       ret = af9035_ctrl_msg(d, &req_fw_ver);
+       if (ret < 0)
+               goto err;
+
+       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
+               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
+                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_read_config(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i, eeprom_shift = 0;
+       u8 tmp;
+       u16 tmp16;
+
+       /* check if there is dual tuners */
+       ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
+       if (ret < 0)
+               goto err;
+
+       state->dual_mode = tmp;
+       pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
+
+       for (i = 0; i < state->dual_mode + 1; i++) {
+               /* tuner */
+               ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               state->af9033_config[i].tuner = tmp;
+               pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
+
+               switch (tmp) {
+               case AF9033_TUNER_TUA9001:
+               case AF9033_TUNER_FC0011:
+               case AF9033_TUNER_MXL5007T:
+               case AF9033_TUNER_TDA18218:
+                       state->af9033_config[i].spec_inv = 1;
+                       break;
+               default:
+                       pr_info("%s: tuner ID=%02x not supported, please " \
+                                       "report!", KBUILD_MODNAME, tmp);
+               };
+
+               /* tuner IF frequency */
+               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               tmp16 = tmp;
+
+               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               tmp16 |= tmp << 8;
+
+               pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
+
+               eeprom_shift = 0x10; /* shift for the 2nd tuner params */
+       }
+
+       /* get demod clock */
+       ret = af9035_rd_reg(d, 0x00d800, &tmp);
+       if (ret < 0)
+               goto err;
+
+       tmp = (tmp >> 0) & 0x0f;
+
+       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
+               state->af9033_config[i].clock = clock_lut[tmp];
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_read_config_it9135(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i;
+       u8 tmp;
+
+       state->dual_mode = false;
+
+       /* get demod clock */
+       ret = af9035_rd_reg(d, 0x00d800, &tmp);
+       if (ret < 0)
+               goto err;
+
+       tmp = (tmp >> 0) & 0x0f;
+
+       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
+               state->af9033_config[i].clock = clock_lut_it9135[tmp];
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
+               int cmd, int arg)
+{
+       int ret;
+
+       switch (cmd) {
+       case FC0011_FE_CALLBACK_POWER:
+               /* Tuner enable */
+               ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               /* LED */
+               ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 50000);
+               break;
+       case FC0011_FE_CALLBACK_RESET:
+               ret = af9035_wr_reg(d, 0xd8e9, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0xd8e8, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0xd8e7, 1);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 20000);
+
+               ret = af9035_wr_reg(d, 0xd8e7, 0);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 20000);
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
+{
+       struct state *state = d_to_priv(d);
+
+       switch (state->af9033_config[0].tuner) {
+       case AF9033_TUNER_FC0011:
+               return af9035_fc0011_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -ENODEV;
+}
+
+static int af9035_frontend_callback(void *adapter_priv, int component,
+                                   int cmd, int arg)
+{
+       struct i2c_adapter *adap = adapter_priv;
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+       switch (component) {
+       case DVB_FRONTEND_COMPONENT_TUNER:
+               return af9035_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+
+       if (!state->af9033_config[adap->id].tuner) {
+               /* unsupported tuner */
+               ret = -ENODEV;
+               goto err;
+       }
+
+       if (adap->id == 0) {
+               state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
+               state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
+
+               ret = af9035_wr_reg(d, 0x00417f,
+                               state->af9033_config[1].i2c_addr);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0x00d81a,
+                               state->dual_mode);
+               if (ret < 0)
+                       goto err;
+       }
+
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(af9033_attach,
+                       &state->af9033_config[adap->id], &d->i2c_adap);
+       if (adap->fe[0] == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       /* disable I2C-gate */
+       adap->fe[0]->ops.i2c_gate_ctrl = NULL;
+       adap->fe[0]->callback = af9035_frontend_callback;
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static struct tua9001_config af9035_tua9001_config = {
+       .i2c_addr = 0x60,
+};
+
+static const struct fc0011_config af9035_fc0011_config = {
+       .i2c_address = 0x60,
+};
+
+static struct mxl5007t_config af9035_mxl5007t_config = {
+       .xtal_freq_hz = MxL_XTAL_24_MHZ,
+       .if_freq_hz = MxL_IF_4_57_MHZ,
+       .invert_if = 0,
+       .loop_thru_enable = 0,
+       .clk_out_enable = 0,
+       .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
+};
+
+static struct tda18218_config af9035_tda18218_config = {
+       .i2c_address = 0x60,
+       .i2c_wr_max = 21,
+};
+
+static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       struct dvb_frontend *fe;
+
+       switch (state->af9033_config[adap->id].tuner) {
+       case AF9033_TUNER_TUA9001:
+               /* AF9035 gpiot3 = TUA9001 RESETN
+                  AF9035 gpiot2 = TUA9001 RXEN */
+
+               /* configure gpiot2 and gpiot2 as output */
+               ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* reset tuner */
+               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(2000, 20000);
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* activate tuner RX */
+               /* TODO: use callback for TUA9001 RXEN */
+               ret = af9035_wr_reg_mask(d, 0x00d8eb, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* attach tuner */
+               fe = dvb_attach(tua9001_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_tua9001_config);
+               break;
+       case AF9033_TUNER_FC0011:
+               fe = dvb_attach(fc0011_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_fc0011_config);
+               break;
+       case AF9033_TUNER_MXL5007T:
+               ret = af9035_wr_reg(d, 0x00d8e0, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8e1, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8df, 0);
+               if (ret < 0)
+                       goto err;
+
+               msleep(30);
+
+               ret = af9035_wr_reg(d, 0x00d8df, 1);
+               if (ret < 0)
+                       goto err;
+
+               msleep(300);
+
+               ret = af9035_wr_reg(d, 0x00d8c0, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8c1, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8bf, 0);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b4, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b5, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b3, 1);
+               if (ret < 0)
+                       goto err;
+
+               /* attach tuner */
+               fe = dvb_attach(mxl5007t_attach, adap->fe[0],
+                               &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
+               break;
+       case AF9033_TUNER_TDA18218:
+               /* attach tuner */
+               fe = dvb_attach(tda18218_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_tda18218_config);
+               break;
+       default:
+               fe = NULL;
+       }
+
+       if (fe == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_init(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i;
+       u16 frame_size = 87 * 188 / 4;
+       u8  packet_size = 512 / 4;
+       struct reg_val_mask tab[] = {
+               { 0x80f99d, 0x01, 0x01 },
+               { 0x80f9a4, 0x01, 0x01 },
+               { 0x00dd11, 0x00, 0x20 },
+               { 0x00dd11, 0x00, 0x40 },
+               { 0x00dd13, 0x00, 0x20 },
+               { 0x00dd13, 0x00, 0x40 },
+               { 0x00dd11, 0x20, 0x20 },
+               { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
+               { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
+               { 0x00dd0c, packet_size, 0xff},
+               { 0x00dd11, state->dual_mode << 6, 0x40 },
+               { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
+               { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
+               { 0x00dd0d, packet_size, 0xff },
+               { 0x80f9a3, 0x00, 0x01 },
+               { 0x80f9cd, 0x00, 0x01 },
+               { 0x80f99d, 0x00, 0x01 },
+               { 0x80f9a4, 0x00, 0x01 },
+       };
+
+       pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
+               __func__, d->udev->speed, frame_size, packet_size);
+
+       /* init endpoints */
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
+                               tab[i].mask);
+               if (ret < 0)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_rc_query(struct dvb_usb_device *d)
+{
+       unsigned int key;
+       unsigned char b[4];
+       int ret;
+       struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
+
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       if ((b[2] + b[3]) == 0xff) {
+               if ((b[0] + b[1]) == 0xff) {
+                       /* NEC */
+                       key = b[0] << 8 | b[2];
+               } else {
+                       /* ext. NEC */
+                       key = b[0] << 16 | b[1] << 8 | b[2];
+               }
+       } else {
+               key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
+       }
+
+       rc_keydown(d->rc_dev, key, 0);
+
+err:
+       /* ignore errors */
+       return 0;
+}
+
+static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       int ret;
+       u8 tmp;
+
+       ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
+       if (ret < 0)
+               goto err;
+
+       pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
+
+       /* don't activate rc if in HID mode or if not available */
+       if (tmp == 5) {
+               ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               pr_debug("%s: ir_type=%02x\n", __func__, tmp);
+
+               switch (tmp) {
+               case 0: /* NEC */
+               default:
+                       rc->allowed_protos = RC_TYPE_NEC;
+                       break;
+               case 1: /* RC6 */
+                       rc->allowed_protos = RC_TYPE_RC6;
+                       break;
+               }
+
+               rc->query = af9035_rc_query;
+               rc->interval = 500;
+
+               /* load empty to enable rc */
+               if (!rc->map_name)
+                       rc->map_name = RC_MAP_EMPTY;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+/* interface 0 is used by DVB-T receiver and
+   interface 1 is for remote controller (HID) */
+static const struct dvb_usb_device_properties af9035_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9035_identify_state,
+       .firmware = "dvb-usb-af9035-02.fw",
+       .download_firmware = af9035_download_firmware,
+
+       .i2c_algo = &af9035_i2c_algo,
+       .read_config = af9035_read_config,
+       .frontend_attach = af9035_frontend_attach,
+       .tuner_attach = af9035_tuner_attach,
+       .init = af9035_init,
+       .get_rc_config = af9035_get_rc_config,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+               },
+       },
+};
+
+static const struct dvb_usb_device_properties it9135_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9035_identify_state,
+       .firmware = "dvb-usb-it9135-01.fw",
+       .download_firmware = af9035_download_firmware_it9135,
+
+       .i2c_algo = &af9035_i2c_algo,
+       .read_config = af9035_read_config_it9135,
+       .frontend_attach = af9035_frontend_attach,
+       .tuner_attach = af9035_tuner_attach,
+       .init = af9035_init,
+       .get_rc_config = af9035_get_rc_config,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+               },
+       },
+};
+
+static const struct usb_device_id af9035_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
+               &af9035_props, "TerraTec Cinergy T Stick", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
+               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
+               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
+               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
+               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
+               &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, af9035_id_table);
+
+static struct usb_driver af9035_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = af9035_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(af9035_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9035 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
new file mode 100644 (file)
index 0000000..59ff69e
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Afatech AF9035 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef AF9035_H
+#define AF9035_H
+
+#include "dvb_usb.h"
+#include "af9033.h"
+#include "tua9001.h"
+#include "fc0011.h"
+#include "mxl5007t.h"
+#include "tda18218.h"
+
+struct reg_val {
+       u32 reg;
+       u8  val;
+};
+
+struct reg_val_mask {
+       u32 reg;
+       u8  val;
+       u8  mask;
+};
+
+struct usb_req {
+       u8  cmd;
+       u8  mbox;
+       u8  wlen;
+       u8  *wbuf;
+       u8  rlen;
+       u8  *rbuf;
+};
+
+struct state {
+       u8 seq; /* packet sequence number */
+       bool dual_mode;
+
+       struct af9033_config af9033_config[2];
+};
+
+u32 clock_lut[] = {
+       20480000, /*      FPGA */
+       16384000, /* 16.38 MHz */
+       20480000, /* 20.48 MHz */
+       36000000, /* 36.00 MHz */
+       30000000, /* 30.00 MHz */
+       26000000, /* 26.00 MHz */
+       28000000, /* 28.00 MHz */
+       32000000, /* 32.00 MHz */
+       34000000, /* 34.00 MHz */
+       24000000, /* 24.00 MHz */
+       22000000, /* 22.00 MHz */
+       12000000, /* 12.00 MHz */
+};
+
+u32 clock_lut_it9135[] = {
+       12000000, /* 12.00 MHz */
+       20480000, /* 20.48 MHz */
+       36000000, /* 36.00 MHz */
+       30000000, /* 30.00 MHz */
+       26000000, /* 26.00 MHz */
+       28000000, /* 28.00 MHz */
+       32000000, /* 32.00 MHz */
+       34000000, /* 34.00 MHz */
+       24000000, /* 24.00 MHz */
+       22000000, /* 22.00 MHz */
+};
+
+/* EEPROM locations */
+#define EEPROM_IR_MODE            0x430d
+#define EEPROM_DUAL_MODE          0x4326
+#define EEPROM_IR_TYPE            0x4329
+#define EEPROM_1_IFFREQ_L         0x432d
+#define EEPROM_1_IFFREQ_H         0x432e
+#define EEPROM_1_TUNER_ID         0x4331
+#define EEPROM_2_IFFREQ_L         0x433d
+#define EEPROM_2_IFFREQ_H         0x433e
+#define EEPROM_2_TUNER_ID         0x4341
+
+/* USB commands */
+#define CMD_MEM_RD                  0x00
+#define CMD_MEM_WR                  0x01
+#define CMD_I2C_RD                  0x02
+#define CMD_I2C_WR                  0x03
+#define CMD_IR_GET                  0x18
+#define CMD_FW_DL                   0x21
+#define CMD_FW_QUERYINFO            0x22
+#define CMD_FW_BOOT                 0x23
+#define CMD_FW_DL_BEGIN             0x24
+#define CMD_FW_DL_END               0x25
+#define CMD_FW_SCATTER_WR           0x29
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
new file mode 100644 (file)
index 0000000..fb3829a
--- /dev/null
@@ -0,0 +1,1324 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#include "anysee.h"
+#include "dvb-pll.h"
+#include "tda1002x.h"
+#include "mt352.h"
+#include "mt352_priv.h"
+#include "zl10353.h"
+#include "tda18212.h"
+#include "cx24116.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "isl6423.h"
+#include "cxd2820r.h"
+
+/* debug */
+static int dvb_usb_anysee_debug;
+module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static DEFINE_MUTEX(anysee_usb_mutex);
+
+static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
+       u8 *rbuf, u8 rlen)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int act_len, ret, i;
+       u8 buf[64];
+
+       memcpy(&buf[0], sbuf, slen);
+       buf[60] = state->seq++;
+
+       mutex_lock(&anysee_usb_mutex);
+
+       deb_xfer(">>> ");
+       debug_dump(buf, slen, deb_xfer);
+
+       /* We need receive one message more after dvb_usb_generic_rw due
+          to weird transaction flow, which is 1 x send + 2 x receive. */
+       ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
+       if (ret)
+               goto error_unlock;
+
+       /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
+        * (EPIPE, Broken pipe). Function supports currently msleep() as a
+        * parameter but I would not like to use it, since according to
+        * Documentation/timers/timers-howto.txt it should not be used such
+        * short, under < 20ms, sleeps. Repeating failed message would be
+        * better choice as not to add unwanted delays...
+        * Fixing that correctly is one of those or both;
+        * 1) use repeat if possible
+        * 2) add suitable delay
+        */
+
+       /* get answer, retry few times if error returned */
+       for (i = 0; i < 3; i++) {
+               /* receive 2nd answer */
+               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+                       d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
+                       &act_len, 2000);
+
+               if (ret) {
+                       deb_info("%s: recv bulk message failed: %d",
+                                       __func__, ret);
+               } else {
+                       deb_xfer("<<< ");
+                       debug_dump(buf, rlen, deb_xfer);
+
+                       if (buf[63] != 0x4f)
+                               deb_info("%s: cmd failed\n", __func__);
+
+                       break;
+               }
+       }
+
+       if (ret) {
+               /* all retries failed, it is fatal */
+               err("%s: recv bulk message failed: %d", __func__, ret);
+               goto error_unlock;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (rbuf && rlen)
+               memcpy(rbuf, buf, rlen);
+
+error_unlock:
+       mutex_unlock(&anysee_usb_mutex);
+
+       return ret;
+}
+
+static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
+{
+       u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
+       int ret;
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
+       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
+       return ret;
+}
+
+static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
+{
+       u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
+       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+/* write single register with mask */
+static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
+       u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = anysee_read_reg(d, reg, &tmp);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return anysee_write_reg(d, reg, val);
+}
+
+/* read single register with mask */
+static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
+       u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = anysee_read_reg(d, reg, &tmp);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
+{
+       u8 buf[] = {CMD_GET_HW_INFO};
+       return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
+}
+
+static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
+       deb_info("%s: onoff:%02x\n", __func__, onoff);
+       return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
+{
+       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
+       deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
+{
+       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
+       deb_info("%s: onoff:%02x\n", __func__, onoff);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+/* I2C */
+static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int ret = 0, inc, i = 0;
+       u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].len > 2 || msg[i+1].len > 60) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
+                       buf[0] = CMD_I2C_READ;
+                       buf[1] = (msg[i].addr << 1) | 0x01;
+                       buf[2] = msg[i].buf[0];
+                       buf[3] = msg[i].buf[1];
+                       buf[4] = msg[i].len-1;
+                       buf[5] = msg[i+1].len;
+                       ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
+                               msg[i+1].len);
+                       inc = 2;
+               } else {
+                       if (msg[i].len > 48) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
+                       buf[0] = CMD_I2C_WRITE;
+                       buf[1] = (msg[i].addr << 1);
+                       buf[2] = msg[i].len;
+                       buf[3] = 0x01;
+                       memcpy(&buf[4], msg[i].buf, msg[i].len);
+                       ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
+                       inc = 1;
+               }
+               if (ret)
+                       break;
+
+               i += inc;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret ? ret : i;
+}
+
+static u32 anysee_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm anysee_i2c_algo = {
+       .master_xfer   = anysee_master_xfer,
+       .functionality = anysee_i2c_func,
+};
+
+static int anysee_mt352_demod_init(struct dvb_frontend *fe)
+{
+       static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
+       static u8 reset[]          = { RESET,      0x80 };
+       static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
+       static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
+       static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
+       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+       mt352_write(fe, clock_config,   sizeof(clock_config));
+       udelay(200);
+       mt352_write(fe, reset,          sizeof(reset));
+       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+       return 0;
+}
+
+/* Callbacks for DVB USB */
+static struct tda10023_config anysee_tda10023_config = {
+       .demod_address = (0x1a >> 1),
+       .invert = 0,
+       .xtal   = 16000000,
+       .pll_m  = 11,
+       .pll_p  = 3,
+       .pll_n  = 1,
+       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
+       .deltaf = 0xfeeb,
+};
+
+static struct mt352_config anysee_mt352_config = {
+       .demod_address = (0x1e >> 1),
+       .demod_init    = anysee_mt352_demod_init,
+};
+
+static struct zl10353_config anysee_zl10353_config = {
+       .demod_address = (0x1e >> 1),
+       .parallel_ts = 1,
+};
+
+static struct zl10353_config anysee_zl10353_tda18212_config2 = {
+       .demod_address = (0x1e >> 1),
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+       .no_tuner = 1,
+       .if2 = 41500,
+};
+
+static struct zl10353_config anysee_zl10353_tda18212_config = {
+       .demod_address = (0x18 >> 1),
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+       .no_tuner = 1,
+       .if2 = 41500,
+};
+
+static struct tda10023_config anysee_tda10023_tda18212_config = {
+       .demod_address = (0x1a >> 1),
+       .xtal   = 16000000,
+       .pll_m  = 12,
+       .pll_p  = 3,
+       .pll_n  = 1,
+       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
+       .deltaf = 0xba02,
+};
+
+static struct tda18212_config anysee_tda18212_config = {
+       .i2c_address = (0xc0 >> 1),
+       .if_dvbt_6 = 4150,
+       .if_dvbt_7 = 4150,
+       .if_dvbt_8 = 4150,
+       .if_dvbc = 5000,
+};
+
+static struct tda18212_config anysee_tda18212_config2 = {
+       .i2c_address = 0x60 /* (0xc0 >> 1) */,
+       .if_dvbt_6 = 3550,
+       .if_dvbt_7 = 3700,
+       .if_dvbt_8 = 4150,
+       .if_dvbt2_6 = 3250,
+       .if_dvbt2_7 = 4000,
+       .if_dvbt2_8 = 4000,
+       .if_dvbc = 5000,
+};
+
+static struct cx24116_config anysee_cx24116_config = {
+       .demod_address = (0xaa >> 1),
+       .mpg_clk_pos_pol = 0x00,
+       .i2c_wr_max = 48,
+};
+
+static struct stv0900_config anysee_stv0900_config = {
+       .demod_address = (0xd0 >> 1),
+       .demod_mode = 0,
+       .xtal = 8000000,
+       .clkmode = 3,
+       .diseqc_mode = 2,
+       .tun1_maddress = 0,
+       .tun1_adc = 1, /* 1 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stv6110_config anysee_stv6110_config = {
+       .i2c_address = (0xc0 >> 1),
+       .mclk = 16000000,
+       .clk_div = 1,
+};
+
+static struct isl6423_config anysee_isl6423_config = {
+       .current_max = SEC_CURRENT_800m,
+       .curlim  = SEC_CURRENT_LIM_OFF,
+       .mod_extern = 1,
+       .addr = (0x10 >> 1),
+};
+
+static struct cxd2820r_config anysee_cxd2820r_config = {
+       .i2c_address = 0x6d, /* (0xda >> 1) */
+       .ts_mode = 0x38,
+};
+
+/*
+ * New USB device strings: Mfr=1, Product=2, SerialNumber=0
+ * Manufacturer: AMT.CO.KR
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
+ * PCB: ?
+ * parts: DNOS404ZH102A(MT352, DTT7579(?))
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
+ * PCB: PCB 507T (rev1.61)
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
+ * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
+ * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
+ *
+ * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
+ * PCB: 507CD (rev1.1)
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
+ * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
+ * IOD[0] ZL10353 1=enabled
+ * IOA[7] TS 0=enabled
+ * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
+ *
+ * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
+ * PCB: 507DC (rev0.2)
+ * parts: TDA10023, DTOS403IH102B TM, CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
+ * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
+ * IOD[0] TDA10023 1=enabled
+ *
+ * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
+ * PCB: 507SI (rev2.1)
+ * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
+ * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
+ * IOD[0] CX24116 1=enabled
+ *
+ * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev0.4)
+ * parts: TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ *
+ * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev1.1)
+ * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
+ * DVB-C:
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ * DVB-T:
+ * IOD[0] ZL10353 1=enabled
+ * IOE[0] tuner 0=enabled
+ * tuner is behind ZL10353 I2C-gate
+ *
+ * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
+ * PCB: 508TC (rev0.6)
+ * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[4] TDA18212 1=enabled
+ * DVB-C:
+ * IOD[6] ZL10353 0=disabled
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] IF 1=enabled
+ * DVB-T:
+ * IOD[5] TDA10023 0=disabled
+ * IOD[6] ZL10353 1=enabled
+ * IOE[0] IF 0=enabled
+ *
+ * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
+ * PCB: 508S2 (rev0.7)
+ * parts: DNBU10512IST(STV0903, STV6110), ISL6423
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] STV0903 1=enabled
+ *
+ * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
+ * PCB: 508T2C (rev0.3)
+ * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] CXD2820R 1=enabled
+ *
+ * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
+ * PCB: 508PTC (rev0.5)
+ * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[4] TDA18212 1=enabled
+ * DVB-C:
+ * IOD[6] ZL10353 0=disabled
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] IF 1=enabled
+ * DVB-T:
+ * IOD[5] TDA10023 0=disabled
+ * IOD[6] ZL10353 1=enabled
+ * IOE[0] IF 0=enabled
+ *
+ * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
+ * PCB: 508PS2 (rev0.4)
+ * parts: DNBU10512IST(STV0903, STV6110), ISL6423
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] STV0903 1=enabled
+ */
+
+static int anysee_read_config(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+       u8 hw_info[3];
+
+       /*
+        * Check which hardware we have.
+        * We must do this call two times to get reliable values (hw/fw bug).
+        */
+       ret = anysee_get_hw_info(d, hw_info);
+       if (ret)
+               goto error;
+
+       ret = anysee_get_hw_info(d, hw_info);
+       if (ret)
+               goto error;
+
+       /* Meaning of these info bytes are guessed. */
+       info("firmware version:%d.%d hardware id:%d",
+               hw_info[1], hw_info[2], hw_info[0]);
+
+       state->hw = hw_info[0];
+error:
+       return ret;
+}
+
+/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
+static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       /* enable / disable tuner access on IOE[4] */
+       return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
+}
+
+static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct anysee_state *state = fe_to_priv(fe);
+       struct dvb_usb_device *d = fe_to_d(fe);
+       int ret;
+
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       /* no frontend sleep control */
+       if (onoff == 0)
+               return 0;
+
+       switch (state->hw) {
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               if (fe->id == 0)  {
+                       /* disable DVB-T demod on IOD[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C tuner on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               } else {
+                       /* disable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T demod on IOD[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T tuner on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               if (fe->id == 0)  {
+                       /* disable DVB-T demod on IOD[6] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable IF route on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               } else {
+                       /* disable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T demod on IOD[6] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
+                       if (ret)
+                               goto error;
+
+                       /* enable IF route on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               }
+
+               break;
+       default:
+               ret = 0;
+       }
+
+error:
+       return ret;
+}
+
+static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct anysee_state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       u8 tmp;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = anysee_tda18212_config.i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = "\x00",
+               }, {
+                       .addr = anysee_tda18212_config.i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = 1,
+                       .buf = &tmp,
+               }
+       };
+
+       switch (state->hw) {
+       case ANYSEE_HW_507T: /* 2 */
+               /* E30 */
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
+                               &d->i2c_adap);
+               if (adap->fe[0])
+                       break;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507CD: /* 6 */
+               /* E30 Plus */
+
+               /* enable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* enable transport stream on IOA[7] */
+               ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507DC: /* 10 */
+               /* E30 C Plus */
+
+               /* enable DVB-C demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(tda10023_attach,
+                               &anysee_tda10023_config, &d->i2c_adap, 0x48);
+
+               break;
+       case ANYSEE_HW_507SI: /* 11 */
+               /* E30 S2 Plus */
+
+               /* enable DVB-S/S2 demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               /* enable tuner on IOE[4] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
+               if (ret)
+                       goto error;
+
+               /* probe TDA18212 */
+               tmp = 0;
+               ret = i2c_transfer(&d->i2c_adap, msg, 2);
+               if (ret == 2 && tmp == 0xc7)
+                       deb_info("%s: TDA18212 found\n", __func__);
+               else
+                       tmp = 0;
+
+               /* disable tuner on IOE[4] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
+               if (ret)
+                       goto error;
+
+               /* disable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               if (tmp == 0xc7) {
+                       /* TDA18212 config */
+                       adap->fe[0] = dvb_attach(tda10023_attach,
+                                       &anysee_tda10023_tda18212_config,
+                                       &d->i2c_adap, 0x48);
+
+                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+                       if (adap->fe[0])
+                               adap->fe[0]->ops.i2c_gate_ctrl =
+                                               anysee_i2c_gate_ctrl;
+               } else {
+                       /* PLL config */
+                       adap->fe[0] = dvb_attach(tda10023_attach,
+                                       &anysee_tda10023_config,
+                                       &d->i2c_adap, 0x48);
+               }
+
+               /* break out if first frontend attaching fails */
+               if (!adap->fe[0])
+                       break;
+
+               /* disable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               if (tmp == 0xc7) {
+                       /* TDA18212 config */
+                       adap->fe[1] = dvb_attach(zl10353_attach,
+                                       &anysee_zl10353_tda18212_config2,
+                                       &d->i2c_adap);
+
+                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+                       if (adap->fe[1])
+                               adap->fe[1]->ops.i2c_gate_ctrl =
+                                               anysee_i2c_gate_ctrl;
+               } else {
+                       /* PLL config */
+                       adap->fe[1] = dvb_attach(zl10353_attach,
+                                       &anysee_zl10353_config,
+                                       &d->i2c_adap);
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               /* disable DVB-T demod on IOD[6] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(tda10023_attach,
+                               &anysee_tda10023_tda18212_config,
+                               &d->i2c_adap, 0x48);
+
+               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+               if (adap->fe[0])
+                       adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
+
+               /* break out if first frontend attaching fails */
+               if (!adap->fe[0])
+                       break;
+
+               /* disable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-T demod on IOD[6] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[1] = dvb_attach(zl10353_attach,
+                               &anysee_zl10353_tda18212_config,
+                               &d->i2c_adap);
+
+               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+               if (adap->fe[1])
+                       adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
+
+               state->has_ci = true;
+
+               break;
+       case ANYSEE_HW_508S2: /* 19 */
+       case ANYSEE_HW_508PS2: /* 22 */
+               /* E7 S2 */
+               /* E7 PS2 */
+
+               /* enable DVB-S/S2 demod on IOE[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(stv0900_attach,
+                               &anysee_stv0900_config, &d->i2c_adap, 0);
+
+               state->has_ci = true;
+
+               break;
+       case ANYSEE_HW_508T2C: /* 20 */
+               /* E7 T2C */
+
+               /* enable DVB-T/T2/C demod on IOE[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(cxd2820r_attach,
+                               &anysee_cxd2820r_config, &d->i2c_adap);
+
+               state->has_ci = true;
+
+               break;
+       }
+
+       if (!adap->fe[0]) {
+               /* we have no frontend :-( */
+               ret = -ENODEV;
+               err("Unsupported Anysee version. " \
+                       "Please report the <linux-media@vger.kernel.org>.");
+       }
+error:
+       return ret;
+}
+
+static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct anysee_state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct dvb_frontend *fe;
+       int ret;
+       deb_info("%s: adap=%d\n", __func__, adap->id);
+
+       switch (state->hw) {
+       case ANYSEE_HW_507T: /* 2 */
+               /* E30 */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
+                               DVB_PLL_THOMSON_DTT7579);
+
+               break;
+       case ANYSEE_HW_507CD: /* 6 */
+               /* E30 Plus */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
+                               &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
+
+               break;
+       case ANYSEE_HW_507DC: /* 10 */
+               /* E30 C Plus */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+               break;
+       case ANYSEE_HW_507SI: /* 11 */
+               /* E30 S2 Plus */
+
+               /* attach LNB controller */
+               fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_isl6423_config);
+
+               break;
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               /* Try first attach TDA18212 silicon tuner on IOE[4], if that
+                * fails attach old simple PLL. */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config);
+
+               if (fe && adap->fe[1]) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(tda18212_attach, adap->fe[1],
+                                       &d->i2c_adap, &anysee_tda18212_config);
+                       break;
+               } else if (fe) {
+                       break;
+               }
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+               if (fe && adap->fe[1]) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(dvb_pll_attach, adap->fe[0],
+                                       (0xc0 >> 1), &d->i2c_adap,
+                                       DVB_PLL_SAMSUNG_DTOS403IH102A);
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config);
+
+               if (fe) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(tda18212_attach, adap->fe[1],
+                                       &d->i2c_adap, &anysee_tda18212_config);
+               }
+
+               break;
+       case ANYSEE_HW_508S2: /* 19 */
+       case ANYSEE_HW_508PS2: /* 22 */
+               /* E7 S2 */
+               /* E7 PS2 */
+
+               /* attach tuner */
+               fe = dvb_attach(stv6110_attach, adap->fe[0],
+                               &anysee_stv6110_config, &d->i2c_adap);
+
+               if (fe) {
+                       /* attach LNB controller */
+                       fe = dvb_attach(isl6423_attach, adap->fe[0],
+                                       &d->i2c_adap, &anysee_isl6423_config);
+               }
+
+               break;
+
+       case ANYSEE_HW_508T2C: /* 20 */
+               /* E7 T2C */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config2);
+
+               break;
+       default:
+               fe = NULL;
+       }
+
+       if (fe)
+               ret = 0;
+       else
+               ret = -ENODEV;
+
+       return ret;
+}
+
+static int anysee_rc_query(struct dvb_usb_device *d)
+{
+       u8 buf[] = {CMD_GET_IR_CODE};
+       u8 ircode[2];
+       int ret;
+
+       /* Remote controller is basic NEC using address byte 0x08.
+          Anysee device RC query returns only two bytes, status and code,
+          address byte is dropped. Also it does not return any value for
+          NEC RCs having address byte other than 0x08. Due to that, we
+          cannot use that device as standard NEC receiver.
+          It could be possible make hack which reads whole code directly
+          from device memory... */
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
+       if (ret)
+               return ret;
+
+       if (ircode[0]) {
+               deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
+               rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
+       }
+
+       return 0;
+}
+
+static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query          = anysee_rc_query;
+       rc->interval       = 250;  /* windows driver uses 500ms */
+
+       return 0;
+}
+
+static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+       int addr)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
+       u8 val;
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+       if (ret)
+               return ret;
+
+       return val;
+}
+
+static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+       int addr, u8 val)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
+       u8 addr)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
+       u8 val;
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+       if (ret)
+               return ret;
+
+       return val;
+}
+
+static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
+       u8 addr, u8 val)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       struct anysee_state *state = d_to_priv(d);
+
+       state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       msleep(300);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       msleep(30);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
+       int open)
+{
+       struct dvb_usb_device *d = ci->data;
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+       u8 tmp;
+
+       ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
+       if (ret)
+               return ret;
+
+       if (tmp == 0) {
+               ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
+               if (time_after(jiffies, state->ci_cam_ready))
+                       ret |= DVB_CA_EN50221_POLL_CAM_READY;
+       }
+
+       return ret;
+}
+
+static int anysee_ci_init(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+
+       state->ci.owner               = THIS_MODULE;
+       state->ci.read_attribute_mem  = anysee_ci_read_attribute_mem;
+       state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
+       state->ci.read_cam_control    = anysee_ci_read_cam_control;
+       state->ci.write_cam_control   = anysee_ci_write_cam_control;
+       state->ci.slot_reset          = anysee_ci_slot_reset;
+       state->ci.slot_shutdown       = anysee_ci_slot_shutdown;
+       state->ci.slot_ts_enable      = anysee_ci_slot_ts_enable;
+       state->ci.poll_slot_status    = anysee_ci_poll_slot_status;
+       state->ci.data                = d;
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
+       if (ret)
+               return ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
+       if (ret)
+               return ret;
+
+       ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void anysee_ci_release(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+
+       /* detach CI */
+       if (state->has_ci)
+               dvb_ca_en50221_release(&state->ci);
+
+       return;
+}
+
+static int anysee_init(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+
+       /* There is one interface with two alternate settings.
+          Alternate setting 0 is for bulk transfer.
+          Alternate setting 1 is for isochronous transfer.
+          We use bulk transfer (alternate setting 0). */
+       ret = usb_set_interface(d->udev, 0, 0);
+       if (ret)
+               return ret;
+
+       /* LED light */
+       ret = anysee_led_ctrl(d, 0x01, 0x03);
+       if (ret)
+               return ret;
+
+       /* enable IR */
+       ret = anysee_ir_ctrl(d, 1);
+       if (ret)
+               return ret;
+
+       /* attach CI */
+       if (state->has_ci) {
+               ret = anysee_ci_init(d);
+               if (ret) {
+                       state->has_ci = false;
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static void anysee_exit(struct dvb_usb_device *d)
+{
+       return anysee_ci_release(d);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties anysee_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct anysee_state),
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo         = &anysee_i2c_algo,
+       .read_config      = anysee_read_config,
+       .frontend_attach  = anysee_frontend_attach,
+       .tuner_attach     = anysee_tuner_attach,
+       .init             = anysee_init,
+       .get_rc_config    = anysee_get_rc_config,
+       .frontend_ctrl    = anysee_frontend_ctrl,
+       .streaming_ctrl   = anysee_streaming_ctrl,
+       .exit             = anysee_exit,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
+               }
+       }
+};
+
+static const struct usb_device_id anysee_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
+               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+       { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
+               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, anysee_id_table);
+
+static struct usb_driver anysee_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = anysee_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(anysee_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
new file mode 100644 (file)
index 0000000..dc40dcf
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#ifndef _DVB_USB_ANYSEE_H_
+#define _DVB_USB_ANYSEE_H_
+
+#define DVB_USB_LOG_PREFIX "anysee"
+#include "dvb_usb.h"
+#include "dvb_ca_en50221.h"
+
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var, level, args...) \
+       do { if ((var & level)) printk(args); } while (0)
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define debug_dump(b, l, func)
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+#endif
+
+#define debug_dump(b, l, func) {\
+       int loop_; \
+       for (loop_ = 0; loop_ < l; loop_++) \
+               func("%02x ", b[loop_]); \
+       func("\n");\
+}
+
+#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_anysee_debug, 0x04, args)
+#define deb_reg(args...)  dprintk(dvb_usb_anysee_debug, 0x08, args)
+#define deb_i2c(args...)  dprintk(dvb_usb_anysee_debug, 0x10, args)
+#define deb_fw(args...)   dprintk(dvb_usb_anysee_debug, 0x20, args)
+
+#undef err
+#define err(format, arg...)  printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+enum cmd {
+       CMD_I2C_READ            = 0x33,
+       CMD_I2C_WRITE           = 0x31,
+       CMD_REG_READ            = 0xb0,
+       CMD_REG_WRITE           = 0xb1,
+       CMD_STREAMING_CTRL      = 0x12,
+       CMD_LED_AND_IR_CTRL     = 0x16,
+       CMD_GET_IR_CODE         = 0x41,
+       CMD_GET_HW_INFO         = 0x19,
+       CMD_SMARTCARD           = 0x34,
+       CMD_CI                  = 0x37,
+};
+
+struct anysee_state {
+       u8 hw; /* PCB ID */
+       u8 seq;
+       u8 fe_id:1; /* frondend ID */
+       u8 has_ci:1;
+       struct dvb_ca_en50221 ci;
+       unsigned long ci_cam_ready; /* jiffies */
+};
+
+#define ANYSEE_HW_507T    2 /* E30 */
+#define ANYSEE_HW_507CD   6 /* E30 Plus */
+#define ANYSEE_HW_507DC  10 /* E30 C Plus */
+#define ANYSEE_HW_507SI  11 /* E30 S2 Plus */
+#define ANYSEE_HW_507FA  15 /* E30 Combo Plus / E30 C Plus */
+#define ANYSEE_HW_508TC  18 /* E7 TC */
+#define ANYSEE_HW_508S2  19 /* E7 S2 */
+#define ANYSEE_HW_508T2C 20 /* E7 T2C */
+#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
+#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
+
+#define REG_IOA       0x80 /* Port A (bit addressable) */
+#define REG_IOB       0x90 /* Port B (bit addressable) */
+#define REG_IOC       0xa0 /* Port C (bit addressable) */
+#define REG_IOD       0xb0 /* Port D (bit addressable) */
+#define REG_IOE       0xb1 /* Port E (NOT bit addressable) */
+#define REG_OEA       0xb2 /* Port A Output Enable */
+#define REG_OEB       0xb3 /* Port B Output Enable */
+#define REG_OEC       0xb4 /* Port C Output Enable */
+#define REG_OED       0xb5 /* Port D Output Enable */
+#define REG_OEE       0xb6 /* Port E Output Enable */
+
+#endif
+
+/***************************************************************************
+ * USB API description (reverse engineered)
+ ***************************************************************************
+
+Transaction flow:
+=================
+BULK[00001] >>> REQUEST PACKET 64 bytes
+BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
+BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
+
+General reply packet(s) are always used if not own reply defined.
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
+============================================================================
+|    00 | reply data (if any) from previous transaction
+|       | Just same reply packet as returned during previous transaction.
+|       | Needed only if reply is missed in previous transaction.
+|       | Just skip normally.
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
+============================================================================
+|    00 | reply data (if any)
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C WRITE REQUEST PACKET
+============================================================================
+|    00 | 0x31 I2C write command
+----------------------------------------------------------------------------
+|    01 | i2c address
+----------------------------------------------------------------------------
+|    02 | data length
+|       | 0x02 (for typical I2C reg / val pair)
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+| 04-   | data
+----------------------------------------------------------------------------
+|   -59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C READ REQUEST PACKET
+============================================================================
+|    00 | 0x33 I2C read command
+----------------------------------------------------------------------------
+|    01 | i2c address + 1
+----------------------------------------------------------------------------
+|    02 | register
+----------------------------------------------------------------------------
+|    03 | 0x00
+----------------------------------------------------------------------------
+|    04 | 0x00
+----------------------------------------------------------------------------
+|    05 | data length
+----------------------------------------------------------------------------
+| 06-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
+============================================================================
+|    00 | 0xb1 register write command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+|    04 | value
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
+============================================================================
+|    00 | 0xb0 register read command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | LED CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+|    01 | 0x01 (LED)
+----------------------------------------------------------------------------
+|    03 | 0x00 blink
+|       | 0x01 lights continuously
+----------------------------------------------------------------------------
+|    04 | blink interval
+|       | 0x00 fastest (looks like LED lights continuously)
+|       | 0xff slowest
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | IR CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+|    01 | 0x02 (IR)
+----------------------------------------------------------------------------
+|    03 | 0x00 IR disabled
+|       | 0x01 IR enabled
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | STREAMING CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x12 streaming control command
+----------------------------------------------------------------------------
+|    01 | 0x00 streaming disabled
+|       | 0x01 streaming enabled
+----------------------------------------------------------------------------
+|    02 | 0x00
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x41 remote control command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REPLY PACKET
+============================================================================
+|    00 | 0x00 code not received
+|       | 0x01 code received
+----------------------------------------------------------------------------
+|    01 | remote control code
+----------------------------------------------------------------------------
+| 02-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REQUEST PACKET
+============================================================================
+|    00 | 0x19 get hardware info command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REPLY PACKET
+============================================================================
+|    00 | hardware id
+----------------------------------------------------------------------------
+| 01-02 | firmware version
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | SMART CARD READER PACKET
+============================================================================
+|    00 | 0x34 smart card reader command
+----------------------------------------------------------------------------
+|    xx |
+----------------------------------------------------------------------------
+| xx-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+*/
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.c b/drivers/media/usb/dvb-usb-v2/au6610.c
new file mode 100644 (file)
index 0000000..05f2a86
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
+ *
+ * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 "au6610.h"
+#include "zl10353.h"
+#include "qt1010.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
+                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       int ret;
+       u16 index;
+       u8 *usb_buf;
+
+       /*
+        * allocate enough for all known requests,
+        * read returns 5 and write 6 bytes
+        */
+       usb_buf = kmalloc(6, GFP_KERNEL);
+       if (!usb_buf)
+               return -ENOMEM;
+
+       switch (wlen) {
+       case 1:
+               index = wbuf[0] << 8;
+               break;
+       case 2:
+               index = wbuf[0] << 8;
+               index += wbuf[1];
+               break;
+       default:
+               pr_err("%s: wlen = %d, aborting\n", KBUILD_MODNAME, wlen);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
+                             USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
+                             usb_buf, 6, AU6610_USB_TIMEOUT);
+       if (ret < 0)
+               goto error;
+
+       switch (operation) {
+       case AU6610_REQ_I2C_READ:
+       case AU6610_REQ_USB_READ:
+               /* requested value is always 5th byte in buffer */
+               rbuf[0] = usb_buf[4];
+       }
+error:
+       kfree(usb_buf);
+       return ret;
+}
+
+static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u8 request;
+       u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
+
+       if (wo) {
+               request = AU6610_REQ_I2C_WRITE;
+       } else { /* rw */
+               request = AU6610_REQ_I2C_READ;
+       }
+
+       return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
+}
+
+
+/* I2C */
+static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                          int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                          msg[i].len, msg[i+1].buf,
+                                          msg[i+1].len) < 0)
+                               break;
+                       i++;
+               } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                              msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+
+static u32 au6610_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm au6610_i2c_algo = {
+       .master_xfer   = au6610_i2c_xfer,
+       .functionality = au6610_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config au6610_zl10353_config = {
+       .demod_address = 0x0f,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct qt1010_config au6610_qt1010_config = {
+       .i2c_address = 0x62
+};
+
+static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(qt1010_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &au6610_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+static int au6610_init(struct dvb_usb_device *d)
+{
+       /* TODO: this functionality belongs likely to the streaming control */
+       /* bInterfaceNumber 0, bAlternateSetting 5 */
+       return usb_set_interface(d->udev, 0, 5);
+}
+
+static struct dvb_usb_device_properties au6610_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+
+       .i2c_algo = &au6610_i2c_algo,
+       .frontend_attach = au6610_zl10353_frontend_attach,
+       .tuner_attach = au6610_qt1010_tuner_attach,
+       .init = au6610_init,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
+               },
+       },
+};
+
+static const struct usb_device_id au6610_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
+               &au6610_props, "Sigmatek DVB-110", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, au6610_id_table);
+
+static struct usb_driver au6610_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = au6610_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(au6610_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.h b/drivers/media/usb/dvb-usb-v2/au6610.h
new file mode 100644 (file)
index 0000000..ea337bf
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
+ *
+ * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 AU6610_H
+#define AU6610_H
+#include "dvb_usb.h"
+
+#define AU6610_REQ_I2C_WRITE   0x14
+#define AU6610_REQ_I2C_READ    0x13
+#define AU6610_REQ_USB_WRITE   0x16
+#define AU6610_REQ_USB_READ    0x15
+
+#define AU6610_USB_TIMEOUT 1000
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
new file mode 100644 (file)
index 0000000..54f1221
--- /dev/null
@@ -0,0 +1,919 @@
+/*
+ * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
+ *
+ * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
+ *
+ * This driver was made publicly available by Terratec, at:
+ *     http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
+ * The original driver's license is GPL, as declared with MODULE_LICENSE()
+ *
+ * Copyright (c) 2010-2012 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *     Driver modified by in order to work with upstream drxk driver, and
+ *     tons of bugs got fixed, and converted to use dvb-usb-v2.
+ *
+ * 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 under version 2 of the License.
+ *
+ * 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.
+ */
+
+#include "drxk.h"
+#include "mt2063.h"
+#include "dvb_ca_en50221.h"
+#include "dvb_usb.h"
+#include "cypress_firmware.h"
+
+#define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw"
+
+static int az6007_xfer_debug;
+module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
+MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
+
+#define FX2_OED                        0xb5
+#define AZ6007_READ_DATA       0xb7
+#define AZ6007_I2C_RD          0xb9
+#define AZ6007_POWER           0xbc
+#define AZ6007_I2C_WR          0xbd
+#define FX2_SCON1              0xc0
+#define AZ6007_TS_THROUGH      0xc7
+#define AZ6007_READ_IR         0xb4
+
+struct az6007_device_state {
+       struct mutex            mutex;
+       struct mutex            ca_mutex;
+       struct dvb_ca_en50221   ca;
+       unsigned                warm:1;
+       int                     (*gate_ctrl) (struct dvb_frontend *, int);
+       unsigned char           data[4096];
+};
+
+static struct drxk_config terratec_h7_drxk = {
+       .adr = 0x29,
+       .parallel_ts = true,
+       .dynamic_clk = true,
+       .single_master = true,
+       .enable_merr_cfg = true,
+       .no_i2c_bridge = false,
+       .chunk_size = 64,
+       .mpeg_out_clk_strength = 0x02,
+       .qam_demod_parameter_count = 2,
+       .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
+};
+
+static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct az6007_device_state *st = fe_to_priv(fe);
+       struct dvb_usb_adapter *adap = fe->sec_priv;
+       int status = 0;
+
+       pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable");
+
+       if (!adap || !st)
+               return -EINVAL;
+
+       if (enable)
+               status = st->gate_ctrl(fe, 1);
+       else
+               status = st->gate_ctrl(fe, 0);
+
+       return status;
+}
+
+static struct mt2063_config az6007_mt2063_config = {
+       .tuner_address = 0x60,
+       .refclock = 36125000,
+};
+
+static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
+                           u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       ret = usb_control_msg(udev,
+                             usb_rcvctrlpipe(udev, 0),
+                             req,
+                             USB_TYPE_VENDOR | USB_DIR_IN,
+                             value, index, b, blen, 5000);
+       if (ret < 0) {
+               pr_warn("usb read operation failed. (%d)\n", ret);
+               return -EIO;
+       }
+
+       if (az6007_xfer_debug) {
+               printk(KERN_DEBUG "az6007: IN  req: %02x, value: %04x, index: %04x\n",
+                      req, value, index);
+               print_hex_dump_bytes("az6007: payload: ",
+                                    DUMP_PREFIX_NONE, b, blen);
+       }
+
+       return ret;
+}
+
+static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
+                           u16 index, u8 *b, int blen)
+{
+       struct az6007_device_state *st = d->priv;
+       int ret;
+
+       if (mutex_lock_interruptible(&st->mutex) < 0)
+               return -EAGAIN;
+
+       ret = __az6007_read(d->udev, req, value, index, b, blen);
+
+       mutex_unlock(&st->mutex);
+
+       return ret;
+}
+
+static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       if (az6007_xfer_debug) {
+               printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
+                      req, value, index);
+               print_hex_dump_bytes("az6007: payload: ",
+                                    DUMP_PREFIX_NONE, b, blen);
+       }
+
+       if (blen > 64) {
+               pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
+                      blen);
+               return -EOPNOTSUPP;
+       }
+
+       ret = usb_control_msg(udev,
+                             usb_sndctrlpipe(udev, 0),
+                             req,
+                             USB_TYPE_VENDOR | USB_DIR_OUT,
+                             value, index, b, blen, 5000);
+       if (ret != blen) {
+               pr_err("usb write operation failed. (%d)\n", ret);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
+                           u16 index, u8 *b, int blen)
+{
+       struct az6007_device_state *st = d->priv;
+       int ret;
+
+       if (mutex_lock_interruptible(&st->mutex) < 0)
+               return -EAGAIN;
+
+       ret = __az6007_write(d->udev, req, value, index, b, blen);
+
+       mutex_unlock(&st->mutex);
+
+       return ret;
+}
+
+static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+
+       pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable");
+
+       return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
+}
+
+/* remote control stuff (does not work with my box) */
+static int az6007_rc_query(struct dvb_usb_device *d)
+{
+       struct az6007_device_state *st = d_to_priv(d);
+       unsigned code = 0;
+
+       az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
+
+       if (st->data[1] == 0x44)
+               return 0;
+
+       if ((st->data[1] ^ st->data[2]) == 0xff)
+               code = st->data[1];
+       else
+               code = st->data[1] << 8 | st->data[2];
+
+       if ((st->data[3] ^ st->data[4]) == 0xff)
+               code = code << 8 | st->data[3];
+       else
+               code = code << 16 | st->data[3] << 8 | st->data[4];
+
+       rc_keydown(d->rc_dev, code, st->data[5]);
+
+       return 0;
+}
+
+static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
+                                       int slot,
+                                       int address)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC1;
+       value = address;
+       index = 0;
+       blen = 1;
+
+       ret = az6007_read(d, req, value, index, b, blen);
+       if (ret < 0) {
+               pr_warn("usb in operation failed. (%d)\n", ret);
+               ret = -EINVAL;
+       } else {
+               ret = b[0];
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
+                                        int slot,
+                                        int address,
+                                        u8 value)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret;
+       u8 req;
+       u16 value1;
+       u16 index;
+       int blen;
+
+       pr_debug("%s(), slot %d\n", __func__, slot);
+       if (slot != 0)
+               return -EINVAL;
+
+       mutex_lock(&state->ca_mutex);
+       req = 0xC2;
+       value1 = address;
+       index = value;
+       blen = 0;
+
+       ret = az6007_write(d, req, value1, index, NULL, blen);
+       if (ret != 0)
+               pr_warn("usb out operation failed. (%d)\n", ret);
+
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
+                                     int slot,
+                                     u8 address)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC3;
+       value = address;
+       index = 0;
+       blen = 2;
+
+       ret = az6007_read(d, req, value, index, b, blen);
+       if (ret < 0) {
+               pr_warn("usb in operation failed. (%d)\n", ret);
+               ret = -EINVAL;
+       } else {
+               if (b[0] == 0)
+                       pr_warn("Read CI IO error\n");
+
+               ret = b[1];
+               pr_debug("read cam data = %x from 0x%x\n", b[1], value);
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
+                                      int slot,
+                                      u8 address,
+                                      u8 value)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret;
+       u8 req;
+       u16 value1;
+       u16 index;
+       int blen;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       mutex_lock(&state->ca_mutex);
+       req = 0xC4;
+       value1 = address;
+       index = value;
+       blen = 0;
+
+       ret = az6007_write(d, req, value1, index, NULL, blen);
+       if (ret != 0) {
+               pr_warn("usb out operation failed. (%d)\n", ret);
+               goto failed;
+       }
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       req = 0xC8;
+       value = 0;
+       index = 0;
+       blen = 1;
+
+       ret = az6007_read(d, req, value, index, b, blen);
+       if (ret < 0) {
+               pr_warn("usb in operation failed. (%d)\n", ret);
+               ret = -EIO;
+       } else{
+               ret = b[0];
+       }
+       kfree(b);
+       return ret;
+}
+
+static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret, i;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC6;
+       value = 1;
+       index = 0;
+       blen = 0;
+
+       ret = az6007_write(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               pr_warn("usb out operation failed. (%d)\n", ret);
+               goto failed;
+       }
+
+       msleep(500);
+       req = 0xC6;
+       value = 0;
+       index = 0;
+       blen = 0;
+
+       ret = az6007_write(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               pr_warn("usb out operation failed. (%d)\n", ret);
+               goto failed;
+       }
+
+       for (i = 0; i < 15; i++) {
+               msleep(100);
+
+               if (CI_CamReady(ca, slot)) {
+                       pr_debug("CAM Ready\n");
+                       break;
+               }
+       }
+       msleep(5000);
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       return 0;
+}
+
+static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       pr_debug("%s()\n", __func__);
+       mutex_lock(&state->ca_mutex);
+       req = 0xC7;
+       value = 1;
+       index = 0;
+       blen = 0;
+
+       ret = az6007_write(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               pr_warn("usb out operation failed. (%d)\n", ret);
+               goto failed;
+       }
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6007_device_state *state = d_to_priv(d);
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC5;
+       value = 0;
+       index = 0;
+       blen = 1;
+
+       ret = az6007_read(d, req, value, index, b, blen);
+       if (ret < 0) {
+               pr_warn("usb in operation failed. (%d)\n", ret);
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       if (!ret && b[0] == 1) {
+               ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
+                     DVB_CA_EN50221_POLL_CAM_READY;
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+
+static void az6007_ci_uninit(struct dvb_usb_device *d)
+{
+       struct az6007_device_state *state;
+
+       pr_debug("%s()\n", __func__);
+
+       if (NULL == d)
+               return;
+
+       state = d_to_priv(d);
+       if (NULL == state)
+               return;
+
+       if (NULL == state->ca.data)
+               return;
+
+       dvb_ca_en50221_release(&state->ca);
+
+       memset(&state->ca, 0, sizeof(state->ca));
+}
+
+
+static int az6007_ci_init(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct az6007_device_state *state = adap_to_priv(adap);
+       int ret;
+
+       pr_debug("%s()\n", __func__);
+
+       mutex_init(&state->ca_mutex);
+       state->ca.owner                 = THIS_MODULE;
+       state->ca.read_attribute_mem    = az6007_ci_read_attribute_mem;
+       state->ca.write_attribute_mem   = az6007_ci_write_attribute_mem;
+       state->ca.read_cam_control      = az6007_ci_read_cam_control;
+       state->ca.write_cam_control     = az6007_ci_write_cam_control;
+       state->ca.slot_reset            = az6007_ci_slot_reset;
+       state->ca.slot_shutdown         = az6007_ci_slot_shutdown;
+       state->ca.slot_ts_enable        = az6007_ci_slot_ts_enable;
+       state->ca.poll_slot_status      = az6007_ci_poll_slot_status;
+       state->ca.data                  = d;
+
+       ret = dvb_ca_en50221_init(&adap->dvb_adap,
+                                 &state->ca,
+                                 0, /* flags */
+                                 1);/* n_slots */
+       if (ret != 0) {
+               pr_err("Cannot initialize CI: Error %d.\n", ret);
+               memset(&state->ca, 0, sizeof(state->ca));
+               return ret;
+       }
+
+       pr_debug("CI initialized.\n");
+
+       return 0;
+}
+
+static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct az6007_device_state *st = adap_to_priv(adap);
+       int ret;
+
+       ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
+       memcpy(mac, st->data, 6);
+
+       if (ret > 0)
+               pr_debug("%s: mac is %pM\n", __func__, mac);
+
+       return ret;
+}
+
+static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct az6007_device_state *st = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+
+       pr_debug("attaching demod drxk\n");
+
+       adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk,
+                                &d->i2c_adap);
+       if (!adap->fe[0])
+               return -EINVAL;
+
+       adap->fe[0]->sec_priv = adap;
+       st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
+       adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+
+       az6007_ci_init(adap);
+
+       return 0;
+}
+
+static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+
+       pr_debug("attaching tuner mt2063\n");
+
+       /* Attach mt2063 to DVB-C frontend */
+       if (adap->fe[0]->ops.i2c_gate_ctrl)
+               adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1);
+       if (!dvb_attach(mt2063_attach, adap->fe[0],
+                       &az6007_mt2063_config,
+                       &d->i2c_adap))
+               return -EINVAL;
+
+       if (adap->fe[0]->ops.i2c_gate_ctrl)
+               adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0);
+
+       return 0;
+}
+
+static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       struct az6007_device_state *state = d_to_priv(d);
+       int ret;
+
+       pr_debug("%s()\n", __func__);
+
+       if (!state->warm) {
+               mutex_init(&state->mutex);
+
+               ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
+               if (ret < 0)
+                       return ret;
+               msleep(60);
+               ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
+               if (ret < 0)
+                       return ret;
+               msleep(100);
+               ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
+               if (ret < 0)
+                       return ret;
+               msleep(20);
+               ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
+               if (ret < 0)
+                       return ret;
+
+               msleep(400);
+               ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
+               if (ret < 0)
+                       return ret;
+               msleep(150);
+               ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
+               if (ret < 0)
+                       return ret;
+               msleep(430);
+               ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
+               if (ret < 0)
+                       return ret;
+
+               state->warm = true;
+
+               return 0;
+       }
+
+       if (!onoff)
+               return 0;
+
+       az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
+       az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
+
+       return 0;
+}
+
+/* I2C */
+static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
+                          int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct az6007_device_state *st = d_to_priv(d);
+       int i, j, len;
+       int ret = 0;
+       u16 index;
+       u16 value;
+       int length;
+       u8 req, addr;
+
+       if (mutex_lock_interruptible(&st->mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               addr = msgs[i].addr << 1;
+               if (((i + 1) < num)
+                   && (msgs[i].len == 1)
+                   && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD)
+                   && (msgs[i + 1].flags & I2C_M_RD)
+                   && (msgs[i].addr == msgs[i + 1].addr)) {
+                       /*
+                        * A write + read xfer for the same address, where
+                        * the first xfer has just 1 byte length.
+                        * Need to join both into one operation
+                        */
+                       if (az6007_xfer_debug)
+                               printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n",
+                                      addr, msgs[i].len, msgs[i + 1].len);
+                       req = AZ6007_I2C_RD;
+                       index = msgs[i].buf[0];
+                       value = addr | (1 << 8);
+                       length = 6 + msgs[i + 1].len;
+                       len = msgs[i + 1].len;
+                       ret = __az6007_read(d->udev, req, value, index,
+                                           st->data, length);
+                       if (ret >= len) {
+                               for (j = 0; j < len; j++)
+                                       msgs[i + 1].buf[j] = st->data[j + 5];
+                       } else
+                               ret = -EIO;
+                       i++;
+               } else if (!(msgs[i].flags & I2C_M_RD)) {
+                       /* write bytes */
+                       if (az6007_xfer_debug)
+                               printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
+                                      addr, msgs[i].len);
+                       req = AZ6007_I2C_WR;
+                       index = msgs[i].buf[0];
+                       value = addr | (1 << 8);
+                       length = msgs[i].len - 1;
+                       len = msgs[i].len - 1;
+                       for (j = 0; j < len; j++)
+                               st->data[j] = msgs[i].buf[j + 1];
+                       ret =  __az6007_write(d->udev, req, value, index,
+                                             st->data, length);
+               } else {
+                       /* read bytes */
+                       if (az6007_xfer_debug)
+                               printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
+                                      addr, msgs[i].len);
+                       req = AZ6007_I2C_RD;
+                       index = msgs[i].buf[0];
+                       value = addr;
+                       length = msgs[i].len + 6;
+                       len = msgs[i].len;
+                       ret = __az6007_read(d->udev, req, value, index,
+                                           st->data, length);
+                       for (j = 0; j < len; j++)
+                               msgs[i].buf[j] = st->data[j + 5];
+               }
+               if (ret < 0)
+                       goto err;
+       }
+err:
+       mutex_unlock(&st->mutex);
+
+       if (ret < 0) {
+               pr_info("%s ERROR: %i\n", __func__, ret);
+               return ret;
+       }
+       return num;
+}
+
+static u32 az6007_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm az6007_i2c_algo = {
+       .master_xfer = az6007_i2c_xfer,
+       .functionality = az6007_i2c_func,
+};
+
+static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 *mac;
+
+       pr_debug("Identifying az6007 state\n");
+
+       mac = kmalloc(6, GFP_ATOMIC);
+       if (!mac)
+               return -ENOMEM;
+
+       /* Try to read the mac address */
+       ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
+       if (ret == 6)
+               ret = WARM;
+       else
+               ret = COLD;
+
+       kfree(mac);
+
+       if (ret == COLD) {
+               __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
+               __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
+               __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
+       }
+
+       pr_debug("Device is on %s state\n",
+                ret == WARM ? "warm" : "cold");
+       return ret;
+}
+
+static void az6007_usb_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       az6007_ci_uninit(d);
+       dvb_usbv2_disconnect(intf);
+}
+
+static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       pr_debug("Getting az6007 Remote Control properties\n");
+
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query          = az6007_rc_query;
+       rc->interval       = 400;
+
+       return 0;
+}
+
+static int az6007_download_firmware(struct dvb_usb_device *d,
+       const struct firmware *fw)
+{
+       pr_debug("Loading az6007 firmware\n");
+
+       return usbv2_cypress_load_firmware(d->udev, fw, CYPRESS_FX2);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties az6007_props = {
+       .driver_name         = KBUILD_MODNAME,
+       .owner               = THIS_MODULE,
+       .firmware            = AZ6007_FIRMWARE,
+
+       .adapter_nr          = adapter_nr,
+       .size_of_priv        = sizeof(struct az6007_device_state),
+       .i2c_algo            = &az6007_i2c_algo,
+       .tuner_attach        = az6007_tuner_attach,
+       .frontend_attach     = az6007_frontend_attach,
+       .streaming_ctrl      = az6007_streaming_ctrl,
+       .get_rc_config       = az6007_get_rc_config,
+       .read_mac_address    = az6007_read_mac_addr,
+       .download_firmware   = az6007_download_firmware,
+       .identify_state      = az6007_identify_state,
+       .power_ctrl          = az6007_power_ctrl,
+       .num_adapters        = 1,
+       .adapter             = {
+               { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
+       }
+};
+
+static struct usb_device_id az6007_usb_table[] = {
+       {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
+               &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
+       {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7,
+               &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
+       {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
+               &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
+       {0},
+};
+
+MODULE_DEVICE_TABLE(usb, az6007_usb_table);
+
+static int az6007_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+
+       az6007_ci_uninit(d);
+       return dvb_usbv2_suspend(intf, msg);
+}
+
+static int az6007_resume(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       struct dvb_usb_adapter *adap = &d->adapter[0];
+
+       az6007_ci_init(adap);
+       return dvb_usbv2_resume(intf);
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver az6007_usb_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = az6007_usb_table,
+       .probe          = dvb_usbv2_probe,
+       .disconnect     = az6007_usb_disconnect,
+       .no_dynamic_id  = 1,
+       .soft_unbind    = 1,
+       /*
+        * FIXME: need to implement reset_resume, likely with
+        * dvb-usb-v2 core support
+        */
+       .suspend        = az6007_suspend,
+       .resume         = az6007_resume,
+};
+
+module_usb_driver(az6007_usb_driver);
+
+MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(AZ6007_FIRMWARE);
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
new file mode 100644 (file)
index 0000000..84ff4a9
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Intel CE6230 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 "ce6230.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
+{
+       int ret;
+       unsigned int pipe;
+       u8 request;
+       u8 requesttype;
+       u16 value;
+       u16 index;
+       u8 *buf;
+
+       request = req->cmd;
+       value = req->value;
+       index = req->index;
+
+       switch (req->cmd) {
+       case I2C_READ:
+       case DEMOD_READ:
+       case REG_READ:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               break;
+       case I2C_WRITE:
+       case DEMOD_WRITE:
+       case REG_WRITE:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               break;
+       default:
+               pr_debug("%s: unknown command=%02x\n", __func__, req->cmd);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       buf = kmalloc(req->data_len, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+               /* write */
+               memcpy(buf, req->data, req->data_len);
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {
+               /* read */
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
+                       buf, req->data_len, CE6230_USB_TIMEOUT);
+
+       ce6230_debug_dump(request, requesttype, value, index, buf,
+                       req->data_len);
+
+       if (ret < 0)
+               pr_err("%s: usb_control_msg() failed=%d\n", KBUILD_MODNAME,
+                               ret);
+       else
+               ret = 0;
+
+       /* read request, copy returned data to return buf */
+       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+               memcpy(req->data, buf, req->data_len);
+
+       kfree(buf);
+error:
+       return ret;
+}
+
+/* I2C */
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int ret = 0, i = 0;
+       struct usb_req req;
+
+       if (num > 2)
+               return -EOPNOTSUPP;
+
+       memset(&req, 0, sizeof(req));
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].addr ==
+                               ce6230_zl10353_config.demod_address) {
+                               req.cmd = DEMOD_READ;
+                               req.value = msg[i].addr >> 1;
+                               req.index = msg[i].buf[0];
+                               req.data_len = msg[i+1].len;
+                               req.data = &msg[i+1].buf[0];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       } else {
+                               pr_err("%s: I2C read not implemented\n",
+                                               KBUILD_MODNAME);
+                               ret = -EOPNOTSUPP;
+                       }
+                       i += 2;
+               } else {
+                       if (msg[i].addr ==
+                               ce6230_zl10353_config.demod_address) {
+                               req.cmd = DEMOD_WRITE;
+                               req.value = msg[i].addr >> 1;
+                               req.index = msg[i].buf[0];
+                               req.data_len = msg[i].len-1;
+                               req.data = &msg[i].buf[1];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       } else {
+                               req.cmd = I2C_WRITE;
+                               req.value = 0x2000 + (msg[i].addr >> 1);
+                               req.index = 0x0000;
+                               req.data_len = msg[i].len;
+                               req.data = &msg[i].buf[0];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       }
+                       i += 1;
+               }
+               if (ret)
+                       break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algorithm = {
+       .master_xfer   = ce6230_i2c_master_xfer,
+       .functionality = ce6230_i2c_functionality,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+       .demod_address = 0x1e,
+       .adc_clock = 450000,
+       .if2 = 45700,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+       .clock_ctl_1 = 0x34,
+       .pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+
+       adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_DEFAULT,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+
+       pr_debug("%s:\n", __func__);
+
+       ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+       return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+
+       pr_debug("%s: onoff=%d\n", __func__, onoff);
+
+       /* InterfaceNumber 1 / AlternateSetting 0     idle
+          InterfaceNumber 1 / AlternateSetting 1     streaming */
+       ret = usb_set_interface(d->udev, 1, onoff);
+       if (ret)
+               pr_err("%s: usb_set_interface() failed=%d\n", KBUILD_MODNAME,
+                               ret);
+
+       return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .bInterfaceNumber = 1,
+
+       .i2c_algo = &ce6230_i2c_algorithm,
+       .power_ctrl = ce6230_power_ctrl,
+       .frontend_attach = ce6230_zl10353_frontend_attach,
+       .tuner_attach = ce6230_mxl5003s_tuner_attach,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 6,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = (16 * 512),
+                                       }
+                               }
+                       },
+               }
+       },
+};
+
+static const struct usb_device_id ce6230_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
+               &ce6230_props, "Intel CE9500 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
+               &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, ce6230_id_table);
+
+static struct usb_driver ce6230_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = ce6230_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(ce6230_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Intel CE6230 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.h b/drivers/media/usb/dvb-usb-v2/ce6230.h
new file mode 100644 (file)
index 0000000..42d7544
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Intel CE6230 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 CE6230_H
+#define CE6230_H
+
+#include "dvb_usb.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+#define ce6230_debug_dump(r, t, v, i, b, l) { \
+       char *direction; \
+       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+               direction = ">>>"; \
+       else \
+               direction = "<<<"; \
+       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s [%d bytes]\n", \
+                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
+                       l & 0xff, l >> 8, direction, l); \
+}
+
+#define CE6230_USB_TIMEOUT 1000
+
+struct usb_req {
+       u8  cmd;       /* [1] */
+       u16 value;     /* [2|3] */
+       u16 index;     /* [4|5] */
+       u16 data_len;  /* [6|7] */
+       u8  *data;
+};
+
+enum ce6230_cmd {
+       CONFIG_READ          = 0xd0, /* rd 0 (unclear) */
+       UNKNOWN_WRITE        = 0xc7, /* wr 7 (unclear) */
+       I2C_READ             = 0xd9, /* rd 9 (unclear) */
+       I2C_WRITE            = 0xca, /* wr a */
+       DEMOD_READ           = 0xdb, /* rd b */
+       DEMOD_WRITE          = 0xcc, /* wr c */
+       REG_READ             = 0xde, /* rd e */
+       REG_WRITE            = 0xcf, /* wr f */
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.c b/drivers/media/usb/dvb-usb-v2/cypress_firmware.c
new file mode 100644 (file)
index 0000000..9f7c970
--- /dev/null
@@ -0,0 +1,125 @@
+/*  cypress_firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#include "dvb_usb.h"
+#include "cypress_firmware.h"
+
+struct usb_cypress_controller {
+       u8 id;
+       const char *name;       /* name of the usb controller */
+       u16 cs_reg;             /* needs to be restarted,
+                                * when the firmware has been downloaded */
+};
+
+static const struct usb_cypress_controller cypress[] = {
+       { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
+       { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
+       { .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cs_reg = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
+               u8 len)
+{
+       return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                       0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
+}
+
+int usbv2_cypress_load_firmware(struct usb_device *udev,
+               const struct firmware *fw, int type)
+{
+       struct hexline hx;
+       u8 reset;
+       int ret, pos = 0;
+
+       /* stop the CPU */
+       reset = 1;
+       ret = usb_cypress_writemem(udev, cypress[type].cs_reg, &reset, 1);
+       if (ret != 1)
+               pr_err("%s: could not stop the USB controller CPU",
+                               KBUILD_MODNAME);
+
+       while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) {
+               pr_debug("%s: writing to address %04x (buffer: %02x %02x)\n",
+                               __func__, hx.addr, hx.len, hx.chk);
+
+               ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len);
+               if (ret != hx.len) {
+                       pr_err("%s: error while transferring firmware " \
+                                       "(transferred size=%d, block size=%d)",
+                                       KBUILD_MODNAME, ret, hx.len);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       if (ret < 0) {
+               pr_err("%s: firmware download failed at %d with %d",
+                               KBUILD_MODNAME, pos, ret);
+               return ret;
+       }
+
+       if (ret == 0) {
+               /* restart the CPU */
+               reset = 0;
+               if (ret || usb_cypress_writemem(
+                               udev, cypress[type].cs_reg, &reset, 1) != 1) {
+                       pr_err("%s: could not restart the USB controller CPU",
+                                       KBUILD_MODNAME);
+                       ret = -EINVAL;
+               }
+       } else
+               ret = -EIO;
+
+       return ret;
+}
+EXPORT_SYMBOL(usbv2_cypress_load_firmware);
+
+int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
+               int *pos)
+{
+       u8 *b = (u8 *) &fw->data[*pos];
+       int data_offs = 4;
+
+       if (*pos >= fw->size)
+               return 0;
+
+       memset(hx, 0, sizeof(struct hexline));
+
+       hx->len = b[0];
+
+       if ((*pos + hx->len + 4) >= fw->size)
+               return -EINVAL;
+
+       hx->addr = b[1] | (b[2] << 8);
+       hx->type = b[3];
+
+       if (hx->type == 0x04) {
+               /* b[4] and b[5] are the Extended linear address record data
+                * field */
+               hx->addr |= (b[4] << 24) | (b[5] << 16);
+               /*
+               hx->len -= 2;
+               data_offs += 2;
+               */
+       }
+       memcpy(hx->data, &b[data_offs], hx->len);
+       hx->chk = b[hx->len + data_offs];
+
+       *pos += hx->len + 5;
+
+       return *pos;
+}
+EXPORT_SYMBOL(dvb_usbv2_get_hexline);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Cypress firmware download");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.h b/drivers/media/usb/dvb-usb-v2/cypress_firmware.h
new file mode 100644 (file)
index 0000000..80085fd
--- /dev/null
@@ -0,0 +1,31 @@
+/* cypress_firmware.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#ifndef CYPRESS_FIRMWARE_H
+#define CYPRESS_FIRMWARE_H
+
+#define CYPRESS_AN2135  0
+#define CYPRESS_AN2235  1
+#define CYPRESS_FX2     2
+
+/* commonly used firmware download types and function */
+struct hexline {
+       u8 len;
+       u32 addr;
+       u8 type;
+       u8 data[255];
+       u8 chk;
+};
+extern int usbv2_cypress_load_firmware(struct usb_device *,
+               const struct firmware *, int);
+extern int dvb_usbv2_get_hexline(const struct firmware *,
+               struct hexline *, int *);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
new file mode 100644 (file)
index 0000000..79b3b8b
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_H
+#define DVB_USB_H
+
+#include <linux/usb/input.h>
+#include <linux/firmware.h>
+#include <media/rc-core.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+#include "dvb-usb-ids.h"
+
+/*
+ * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
+ *
+ * |-- device
+ * |   |-- adapter0
+ * |   |   |-- frontend0
+ * |   |   |-- frontend1
+ * |   |   `-- frontend2
+ * |   `-- adapter1
+ * |       |-- frontend0
+ * |       |-- frontend1
+ * |       `-- frontend2
+ *
+ *
+ * Commonly used variable names:
+ * d = pointer to device (struct dvb_usb_device *)
+ * adap = pointer to adapter (struct dvb_usb_adapter *)
+ * fe = pointer to frontend (struct dvb_frontend *)
+ *
+ * Use macros defined in that file to resolve needed pointers.
+ */
+
+/* helper macros for every DVB USB driver use */
+#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
+               adapter[adap->id]))
+#define adap_to_priv(adap) (adap_to_d(adap)->priv)
+#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
+#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
+#define fe_to_priv(fe) (fe_to_d(fe)->priv)
+#define d_to_priv(d) (d->priv)
+
+#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
+       .type = USB_BULK, \
+       .count = count_, \
+       .endpoint = endpoint_, \
+       .u = { \
+               .bulk = { \
+                       .buffersize = size_, \
+               } \
+       } \
+}
+
+#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
+       .type = USB_ISOC, \
+       .count = count_, \
+       .endpoint = endpoint_, \
+       .u = { \
+               .isoc = { \
+                       .framesperurb = frames_, \
+                       .framesize = size_,\
+                       .interval = interval_, \
+               } \
+       } \
+}
+
+#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
+       .idVendor = (vend), \
+       .idProduct = (prod), \
+       .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
+               .props = (props_), \
+               .name = (name_), \
+               .rc_map = (rc), \
+       })
+
+struct dvb_usb_device;
+struct dvb_usb_adapter;
+
+/**
+ * structure for carrying all needed data from the device driver to the general
+ * dvb usb routines
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @props: structure containing all device properties
+ */
+struct dvb_usb_driver_info {
+       const char *name;
+       const char *rc_map;
+       const struct dvb_usb_device_properties *props;
+};
+
+/**
+ * structure for remote controller configuration
+ * @map_name: name of rc codes table
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
+ * @query: called to query an event from the device
+ * @interval: time in ms between two queries
+ * @driver_type: used to point if a device supports raw mode
+ * @bulk_mode: device supports bulk mode for rc (disable polling mode)
+ */
+struct dvb_usb_rc {
+       const char *map_name;
+       u64 allowed_protos;
+       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*query) (struct dvb_usb_device *d);
+       unsigned int interval;
+       const enum rc_driver_type driver_type;
+       bool bulk_mode;
+};
+
+/**
+ * usb streaming configration for adapter
+ * @type: urb type
+ * @count: count of used urbs
+ * @endpoint: stream usb endpoint number
+ */
+struct usb_data_stream_properties {
+#define USB_BULK  1
+#define USB_ISOC  2
+       u8 type;
+       u8 count;
+       u8 endpoint;
+
+       union {
+               struct {
+                       unsigned int buffersize; /* per URB */
+               } bulk;
+               struct {
+                       int framesperurb;
+                       int framesize;
+                       int interval;
+               } isoc;
+       } u;
+};
+
+/**
+ * properties of dvb usb device adapter
+ * @caps: adapter capabilities
+ * @pid_filter_count: pid count of adapter pid-filter
+ * @pid_filter_ctrl: called to enable/disable pid-filter
+ * @pid_filter: called to set/unset pid for filtering
+ * @stream: adapter usb stream configuration
+ */
+#define MAX_NO_OF_FE_PER_ADAP 3
+struct dvb_usb_adapter_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
+       u8 caps;
+
+       u8 pid_filter_count;
+       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+       int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
+
+       struct usb_data_stream_properties stream;
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
+ * @driver_name: name of the owning driver module
+ * @owner: owner of the dvb_adapter
+ * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
+ * @bInterfaceNumber: usb interface number driver binds
+ * @size_of_priv: bytes allocated for the driver private data
+ * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
+ * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
+ *  receive
+ * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
+ * @identify_state: called to determine the firmware state (cold or warm) and
+ *  return possible firmware file name to be loaded
+ * @firmware: name of the firmware file to be loaded
+ * @download_firmware: called to download the firmware
+ * @i2c_algo: i2c_algorithm if the device has i2c-adapter
+ * @num_adapters: dvb usb device adapter count
+ * @get_adapter_count: called to resolve adapter count
+ * @adapter: array of all adapter properties of device
+ * @power_ctrl: called to enable/disable power of the device
+ * @read_config: called to resolve device configuration
+ * @read_mac_address: called to resolve adapter mac-address
+ * @frontend_attach: called to attach the possible frontends
+ * @tuner_attach: called to attach the possible tuners
+ * @frontend_ctrl: called to power on/off active frontend
+ * @streaming_ctrl: called to start/stop the usb streaming of adapter
+ * @init: called after adapters are created in order to finalize device
+ *  configuration
+ * @exit: called when driver is unloaded
+ * @get_rc_config: called to resolve used remote controller configuration
+ * @get_stream_config: called to resolve input and output stream configuration
+ *  of the adapter just before streaming is started. input stream is transport
+ *  stream from the demodulator and output stream is usb stream to host.
+ */
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
+       const char *driver_name;
+       struct module *owner;
+       short *adapter_nr;
+
+       u8 bInterfaceNumber;
+       unsigned int size_of_priv;
+       u8 generic_bulk_ctrl_endpoint;
+       u8 generic_bulk_ctrl_endpoint_response;
+       unsigned int generic_bulk_ctrl_delay;
+
+#define WARM                  0
+#define COLD                  1
+       int (*identify_state) (struct dvb_usb_device *, const char **);
+       const char *firmware;
+#define RECONNECTS_USB        1
+       int (*download_firmware) (struct dvb_usb_device *,
+                       const struct firmware *);
+
+       struct i2c_algorithm *i2c_algo;
+
+       unsigned int num_adapters;
+       int (*get_adapter_count) (struct dvb_usb_device *);
+       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+       int (*power_ctrl) (struct dvb_usb_device *, int);
+       int (*read_config) (struct dvb_usb_device *d);
+       int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
+       int (*frontend_attach) (struct dvb_usb_adapter *);
+       int (*tuner_attach) (struct dvb_usb_adapter *);
+       int (*frontend_ctrl) (struct dvb_frontend *, int);
+       int (*streaming_ctrl) (struct dvb_frontend *, int);
+       int (*init) (struct dvb_usb_device *);
+       void (*exit) (struct dvb_usb_device *);
+       int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
+#define DVB_USB_FE_TS_TYPE_188        0
+#define DVB_USB_FE_TS_TYPE_204        1
+#define DVB_USB_FE_TS_TYPE_RAW        2
+       int (*get_stream_config) (struct dvb_frontend *,  u8 *,
+                       struct usb_data_stream_properties *);
+};
+
+/**
+ * generic object of an usb stream
+ * @buf_num: number of buffer allocated
+ * @buf_size: size of each buffer in buf_list
+ * @buf_list: array containing all allocate buffers for streaming
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list
+ *
+ * @urbs_initialized: number of URBs initialized
+ * @urbs_submitted: number of URBs submitted
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+       struct usb_device *udev;
+       struct usb_data_stream_properties props;
+
+#define USB_STATE_INIT    0x00
+#define USB_STATE_URB_BUF 0x01
+       u8 state;
+
+       void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       int            buf_num;
+       unsigned long  buf_size;
+       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+       int urbs_initialized;
+       int urbs_submitted;
+
+       void *user_priv;
+};
+
+/**
+ * dvb adapter object on dvb usb device
+ * @props: pointer to adapter properties
+ * @stream: adapter the usb data stream
+ * @id: index of this adapter (starting with 0)
+ * @ts_type: transport stream, input stream, type
+ * @pid_filtering: is hardware pid_filtering used or not
+ * @feed_count: current feed count
+ * @max_feed_count: maimum feed count device can handle
+ * @dvb_adap: adapter dvb_adapter
+ * @dmxdev: adapter dmxdev
+ * @demux: adapter software demuxer
+ * @dvb_net: adapter dvb_net interfaces
+ * @sync_mutex: mutex used to sync control and streaming of the adapter
+ * @fe: adapter frontends
+ * @fe_init: rerouted frontend-init function
+ * @fe_sleep: rerouted frontend-sleep function
+ */
+struct dvb_usb_adapter {
+       const struct dvb_usb_adapter_properties *props;
+       struct usb_data_stream stream;
+       u8 id;
+       u8 ts_type;
+       bool pid_filtering;
+       u8 feed_count;
+       u8 max_feed_count;
+       s8 active_fe;
+
+       /* dvb */
+       struct dvb_adapter   dvb_adap;
+       struct dmxdev        dmxdev;
+       struct dvb_demux     demux;
+       struct dvb_net       dvb_net;
+       struct mutex         sync_mutex;
+
+       struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
+       int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+       int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+};
+
+/**
+ * dvb usb device object
+ * @props: device properties
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @udev: pointer to the device's struct usb_device
+ * @intf: pointer to the device's usb interface
+ * @rc: remote controller configuration
+ * @probe_work: work to defer .probe()
+ * @powered: indicated whether the device is power or not
+ * @usb_mutex: mutex for usb control messages
+ * @i2c_mutex: mutex for i2c-transfers
+ * @i2c_adap: device's i2c-adapter
+ * @rc_dev: rc device for the remote control
+ * @rc_query_work: work for polling remote
+ * @priv: private data of the actual driver (allocate by dvb usb, size defined
+ *  in size_of_priv of dvb_usb_properties).
+ */
+struct dvb_usb_device {
+       const struct dvb_usb_device_properties *props;
+       const char *name;
+       const char *rc_map;
+
+       struct usb_device *udev;
+       struct usb_interface *intf;
+       struct dvb_usb_rc rc;
+       struct work_struct probe_work;
+       pid_t work_pid;
+       int powered;
+
+       /* locking */
+       struct mutex usb_mutex;
+
+       /* i2c */
+       struct mutex i2c_mutex;
+       struct i2c_adapter i2c_adap;
+
+       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+
+       /* remote control */
+       struct rc_dev *rc_dev;
+       char rc_phys[64];
+       struct delayed_work rc_query_work;
+
+       void *priv;
+};
+
+extern int dvb_usbv2_probe(struct usb_interface *,
+               const struct usb_device_id *);
+extern void dvb_usbv2_disconnect(struct usb_interface *);
+extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
+extern int dvb_usbv2_resume(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
+extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h b/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
new file mode 100644 (file)
index 0000000..45f0709
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_COMMON_H
+#define DVB_USB_COMMON_H
+
+#include "dvb_usb.h"
+
+/* commonly used  methods */
+extern int usb_urb_initv2(struct usb_data_stream *stream,
+               const struct usb_data_stream_properties *props);
+extern int usb_urb_exitv2(struct usb_data_stream *stream);
+extern int usb_urb_submitv2(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props);
+extern int usb_urb_killv2(struct usb_data_stream *stream);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
new file mode 100644 (file)
index 0000000..a72f9c7
--- /dev/null
@@ -0,0 +1,997 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+int dvb_usbv2_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling,
+               "disable remote control polling (default: 0)");
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
+               int, 0444);
+MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
+               "PID filter, if any (default: 0)");
+
+static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
+{
+       int ret;
+       const struct firmware *fw;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (!d->props->download_firmware) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       ret = request_firmware(&fw, name, &d->udev->dev);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
+                               "'%s'. Please see linux/Documentation/dvb/ " \
+                               "for more details on firmware-problems. " \
+                               "Status %d\n", KBUILD_MODNAME, name, ret);
+               goto err;
+       }
+
+       dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
+                       KBUILD_MODNAME, name);
+
+       ret = d->props->download_firmware(d, fw);
+       release_firmware(fw);
+       if (ret < 0)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
+{
+       int ret;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (!d->props->i2c_algo)
+               return 0;
+
+       strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
+       d->i2c_adap.algo = d->props->i2c_algo;
+       d->i2c_adap.dev.parent = &d->udev->dev;
+       i2c_set_adapdata(&d->i2c_adap, d);
+
+       ret = i2c_add_adapter(&d->i2c_adap);
+       if (ret < 0) {
+               d->i2c_adap.algo = NULL;
+               dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (d->i2c_adap.algo)
+               i2c_del_adapter(&d->i2c_adap);
+
+       return 0;
+}
+
+static void dvb_usb_read_remote_control(struct work_struct *work)
+{
+       struct dvb_usb_device *d = container_of(work,
+                       struct dvb_usb_device, rc_query_work.work);
+       int ret;
+
+       /*
+        * When the parameter has been set to 1 via sysfs while the
+        * driver was running, or when bulk mode is enabled after IR init.
+        */
+       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
+               return;
+
+       ret = d->rc.query(d);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               return; /* stop polling */
+       }
+
+       schedule_delayed_work(&d->rc_query_work,
+                       msecs_to_jiffies(d->rc.interval));
+}
+
+static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
+{
+       int ret;
+       struct rc_dev *dev;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
+               return 0;
+
+       d->rc.map_name = d->rc_map;
+       ret = d->props->get_rc_config(d, &d->rc);
+       if (ret < 0)
+               goto err;
+
+       /* disable rc when there is no keymap defined */
+       if (!d->rc.map_name)
+               return 0;
+
+       dev = rc_allocate_device();
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev->dev.parent = &d->udev->dev;
+       dev->input_name = d->name;
+       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+       dev->input_phys = d->rc_phys;
+       usb_to_input_id(d->udev, &dev->input_id);
+       /* TODO: likely RC-core should took const char * */
+       dev->driver_name = (char *) d->props->driver_name;
+       dev->map_name = d->rc.map_name;
+       dev->driver_type = d->rc.driver_type;
+       dev->allowed_protos = d->rc.allowed_protos;
+       dev->change_protocol = d->rc.change_protocol;
+       dev->priv = d;
+
+       ret = rc_register_device(dev);
+       if (ret < 0) {
+               rc_free_device(dev);
+               goto err;
+       }
+
+       d->rc_dev = dev;
+
+       /* start polling if needed */
+       if (d->rc.query && !d->rc.bulk_mode) {
+               /* initialize a work queue for handling polling */
+               INIT_DELAYED_WORK(&d->rc_query_work,
+                               dvb_usb_read_remote_control);
+               dev_info(&d->udev->dev, "%s: schedule remote query interval " \
+                               "to %d msecs\n", KBUILD_MODNAME,
+                               d->rc.interval);
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (d->rc_dev) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+               rc_unregister_device(d->rc_dev);
+               d->rc_dev = NULL;
+       }
+
+       return 0;
+}
+
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_204(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
+}
+
+int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       adap->stream.udev = adap_to_d(adap)->udev;
+       adap->stream.user_priv = adap;
+       adap->stream.complete = dvb_usb_data_complete;
+
+       return usb_urb_initv2(&adap->stream, &adap->props->stream);
+}
+
+int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       return usb_urb_exitv2(&adap->stream);
+}
+
+static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
+               int count)
+{
+       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
+                       "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
+                       __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
+                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
+                       dvbdmxfeed->pid, dvbdmxfeed->index,
+                       (count == 1) ? "on" : "off");
+
+       if (adap->active_fe == -1)
+               return -EINVAL;
+
+       adap->feed_count += count;
+
+       /* stop feeding if it is last pid */
+       if (adap->feed_count == 0) {
+               dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
+               usb_urb_killv2(&adap->stream);
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(
+                                       adap->fe[adap->active_fe], 0);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+               mutex_unlock(&adap->sync_mutex);
+       }
+
+       /* activate the pid on the device pid filter */
+       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                       adap->pid_filtering &&
+                       adap->props->pid_filter)
+               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
+                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
+                       if (ret < 0)
+                               dev_err(&d->udev->dev, "%s: pid_filter() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+
+       /* start feeding if it is first pid */
+       if (adap->feed_count == 1 && count == 1) {
+               struct usb_data_stream_properties stream_props;
+               mutex_lock(&adap->sync_mutex);
+               dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
+
+               /* resolve input and output streaming paramters */
+               if (d->props->get_stream_config) {
+                       memcpy(&stream_props, &adap->props->stream,
+                               sizeof(struct usb_data_stream_properties));
+                       ret = d->props->get_stream_config(
+                                       adap->fe[adap->active_fe],
+                                       &adap->ts_type, &stream_props);
+                       if (ret < 0)
+                               goto err_mutex_unlock;
+               } else {
+                       stream_props = adap->props->stream;
+               }
+
+               switch (adap->ts_type) {
+               case DVB_USB_FE_TS_TYPE_204:
+                       adap->stream.complete = dvb_usb_data_complete_204;
+                       break;
+               case DVB_USB_FE_TS_TYPE_RAW:
+                       adap->stream.complete = dvb_usb_data_complete_raw;
+                       break;
+               case DVB_USB_FE_TS_TYPE_188:
+               default:
+                       adap->stream.complete = dvb_usb_data_complete;
+                       break;
+               }
+
+               usb_urb_submitv2(&adap->stream, &stream_props);
+
+               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                               adap->props->caps &
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+                               adap->props->pid_filter_ctrl) {
+                       ret = adap->props->pid_filter_ctrl(adap,
+                                       adap->pid_filtering);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: " \
+                                               "pid_filter_ctrl() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(
+                                       adap->fe[adap->active_fe], 1);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+       }
+
+       return 0;
+err_mutex_unlock:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
+}
+
+int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
+                       &d->udev->dev, d->props->adapter_nr);
+       if (ret < 0) {
+               dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
+                               __func__, ret);
+               goto err_dvb_register_adapter;
+       }
+
+       adap->dvb_adap.priv = adap;
+
+       if (d->props->read_mac_address) {
+               ret = d->props->read_mac_address(adap,
+                               adap->dvb_adap.proposed_mac);
+               if (ret < 0)
+                       goto err_dvb_dmx_init;
+
+               dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
+                               KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
+       }
+
+       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       adap->demux.priv             = adap;
+       adap->demux.filternum        = 0;
+       adap->demux.filternum        = adap->max_feed_count;
+       adap->demux.feednum          = adap->demux.filternum;
+       adap->demux.start_feed       = dvb_usb_start_feed;
+       adap->demux.stop_feed        = dvb_usb_stop_feed;
+       adap->demux.write_to_decoder = NULL;
+       ret = dvb_dmx_init(&adap->demux);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_dmx_init;
+       }
+
+       adap->dmxdev.filternum       = adap->demux.filternum;
+       adap->dmxdev.demux           = &adap->demux.dmx;
+       adap->dmxdev.capabilities    = 0;
+       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_dmxdev_init;
+       }
+
+       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_net_init;
+       }
+
+       mutex_init(&adap->sync_mutex);
+
+       return 0;
+err_dvb_net_init:
+       dvb_dmxdev_release(&adap->dmxdev);
+err_dvb_dmxdev_init:
+       dvb_dmx_release(&adap->demux);
+err_dvb_dmx_init:
+       dvb_unregister_adapter(&adap->dvb_adap);
+err_dvb_register_adapter:
+       adap->dvb_adap.priv = NULL;
+       return ret;
+}
+
+int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       if (adap->dvb_adap.priv) {
+               dvb_net_release(&adap->dvb_net);
+               adap->demux.dmx.close(&adap->demux.dmx);
+               dvb_dmxdev_release(&adap->dmxdev);
+               dvb_dmx_release(&adap->demux);
+               dvb_unregister_adapter(&adap->dvb_adap);
+       }
+
+       return 0;
+}
+
+int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+
+       if (onoff)
+               d->powered++;
+       else
+               d->powered--;
+
+       if (d->powered == 0 || (onoff && d->powered == 1)) {
+               /* when switching from 1 to 0 or from 0 to 1 */
+               dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
+               if (d->props->power_ctrl) {
+                       ret = d->props->power_ctrl(d, onoff);
+                       if (ret < 0)
+                               goto err;
+               }
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_fe_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+                       fe->id);
+
+       ret = dvb_usbv2_device_power_ctrl(d, 1);
+       if (ret < 0)
+               goto err;
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 1);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (adap->fe_init[fe->id]) {
+               ret = adap->fe_init[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       adap->active_fe = fe->id;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+                       fe->id);
+
+       if (adap->fe_sleep[fe->id]) {
+               ret = adap->fe_sleep[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 0);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_device_power_ctrl(d, 0);
+       if (ret < 0)
+               goto err;
+
+       adap->active_fe = -1;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
+{
+       int ret, i, count_registered = 0;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+       memset(adap->fe, 0, sizeof(adap->fe));
+       adap->active_fe = -1;
+
+       if (d->props->frontend_attach) {
+               ret = d->props->frontend_attach(adap);
+               if (ret < 0) {
+                       dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
+                                       "failed=%d\n", __func__, ret);
+                       goto err_dvb_frontend_detach;
+               }
+       } else {
+               dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
+                               __func__);
+               ret = 0;
+               goto err;
+       }
+
+       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
+               adap->fe[i]->id = i;
+               /* re-assign sleep and wakeup functions */
+               adap->fe_init[i] = adap->fe[i]->ops.init;
+               adap->fe[i]->ops.init = dvb_usb_fe_init;
+               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
+               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
+
+               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
+               if (ret < 0) {
+                       dev_err(&d->udev->dev, "%s: frontend%d registration " \
+                                       "failed\n", KBUILD_MODNAME, i);
+                       goto err_dvb_unregister_frontend;
+               }
+
+               count_registered++;
+       }
+
+       if (d->props->tuner_attach) {
+               ret = d->props->tuner_attach(adap);
+               if (ret < 0) {
+                       dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
+                                       __func__, ret);
+                       goto err_dvb_unregister_frontend;
+               }
+       }
+
+       return 0;
+
+err_dvb_unregister_frontend:
+       for (i = count_registered - 1; i >= 0; i--)
+               dvb_unregister_frontend(adap->fe[i]);
+
+err_dvb_frontend_detach:
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i])
+                       dvb_frontend_detach(adap->fe[i]);
+       }
+
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+{
+       int i;
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i]) {
+                       dvb_unregister_frontend(adap->fe[i]);
+                       dvb_frontend_detach(adap->fe[i]);
+               }
+       }
+
+       return 0;
+}
+
+static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
+{
+       struct dvb_usb_adapter *adap;
+       int ret, i, adapter_count;
+
+       /* resolve adapter count */
+       adapter_count = d->props->num_adapters;
+       if (d->props->get_adapter_count) {
+               ret = d->props->get_adapter_count(d);
+               if (ret < 0)
+                       goto err;
+
+               adapter_count = ret;
+       }
+
+       for (i = 0; i < adapter_count; i++) {
+               adap = &d->adapter[i];
+               adap->id = i;
+               adap->props = &d->props->adapter[i];
+
+               /* speed - when running at FULL speed we need a HW PID filter */
+               if (d->udev->speed == USB_SPEED_FULL &&
+                               !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+                       dev_err(&d->udev->dev, "%s: this USB2.0 device " \
+                                       "cannot be run on a USB1.1 port (it " \
+                                       "lacks a hardware PID filter)\n",
+                                       KBUILD_MODNAME);
+                       ret = -ENODEV;
+                       goto err;
+               } else if ((d->udev->speed == USB_SPEED_FULL &&
+                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+                               (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+                       dev_info(&d->udev->dev, "%s: will use the device's " \
+                                       "hardware PID filter " \
+                                       "(table count: %d)\n", KBUILD_MODNAME,
+                                       adap->props->pid_filter_count);
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props->pid_filter_count;
+               } else {
+                       dev_info(&d->udev->dev, "%s: will pass the complete " \
+                                       "MPEG2 transport stream to the " \
+                                       "software demuxer\n", KBUILD_MODNAME);
+                       adap->pid_filtering  = 0;
+                       adap->max_feed_count = 255;
+               }
+
+               if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
+                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+                       dev_info(&d->udev->dev, "%s: PID filter enabled by " \
+                                       "module option\n", KBUILD_MODNAME);
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props->pid_filter_count;
+               }
+
+               ret = dvb_usbv2_adapter_stream_init(adap);
+               if (ret)
+                       goto err;
+
+               ret = dvb_usbv2_adapter_dvb_init(adap);
+               if (ret)
+                       goto err;
+
+               ret = dvb_usbv2_adapter_frontend_init(adap);
+               if (ret)
+                       goto err;
+
+               /* use exclusive FE lock if there is multiple shared FEs */
+               if (adap->fe[1])
+                       adap->dvb_adap.mfe_shared = 1;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
+{
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+               if (d->adapter[i].props) {
+                       dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
+                       dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
+                       dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
+               }
+       }
+
+       return 0;
+}
+
+/* general initialization functions */
+static int dvb_usbv2_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       dvb_usbv2_remote_exit(d);
+       dvb_usbv2_adapter_exit(d);
+       dvb_usbv2_i2c_exit(d);
+       kfree(d->priv);
+       kfree(d);
+
+       return 0;
+}
+
+static int dvb_usbv2_init(struct dvb_usb_device *d)
+{
+       int ret;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       dvb_usbv2_device_power_ctrl(d, 1);
+
+       if (d->props->read_config) {
+               ret = d->props->read_config(d);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_i2c_init(d);
+       if (ret < 0)
+               goto err;
+
+       ret = dvb_usbv2_adapter_init(d);
+       if (ret < 0)
+               goto err;
+
+       if (d->props->init) {
+               ret = d->props->init(d);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_remote_init(d);
+       if (ret < 0)
+               goto err;
+
+       dvb_usbv2_device_power_ctrl(d, 0);
+
+       return 0;
+err:
+       dvb_usbv2_device_power_ctrl(d, 0);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+/*
+ * udev, which is used for the firmware downloading, requires we cannot
+ * block during module_init(). module_init() calls USB probe() which
+ * is this routine. Due to that we delay actual operation using workqueue
+ * and return always success here.
+ */
+static void dvb_usbv2_init_work(struct work_struct *work)
+{
+       int ret;
+       struct dvb_usb_device *d =
+                       container_of(work, struct dvb_usb_device, probe_work);
+
+       d->work_pid = current->pid;
+       dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
+
+       if (d->props->size_of_priv) {
+               d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
+               if (!d->priv) {
+                       dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
+                                       KBUILD_MODNAME);
+                       ret = -ENOMEM;
+                       goto err_usb_driver_release_interface;
+               }
+       }
+
+       if (d->props->identify_state) {
+               const char *name = NULL;
+               ret = d->props->identify_state(d, &name);
+               if (ret == 0) {
+                       ;
+               } else if (ret == COLD) {
+                       dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
+                                       "state\n", KBUILD_MODNAME, d->name);
+
+                       if (!name)
+                               name = d->props->firmware;
+
+                       ret = dvb_usbv2_download_firmware(d, name);
+                       if (ret == 0) {
+                               /* device is warm, continue initialization */
+                               ;
+                       } else if (ret == RECONNECTS_USB) {
+                               /*
+                                * USB core will call disconnect() and then
+                                * probe() as device reconnects itself from the
+                                * USB bus. disconnect() will release all driver
+                                * resources and probe() is called for 'new'
+                                * device. As 'new' device is warm we should
+                                * never go here again.
+                                */
+                               return;
+                       } else {
+                               /*
+                                * Unexpected error. We must unregister driver
+                                * manually from the device, because device is
+                                * already register by returning from probe()
+                                * with success. usb_driver_release_interface()
+                                * finally calls disconnect() in order to free
+                                * resources.
+                                */
+                               goto err_usb_driver_release_interface;
+                       }
+               } else {
+                       goto err_usb_driver_release_interface;
+               }
+       }
+
+       dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
+                       KBUILD_MODNAME, d->name);
+
+       ret = dvb_usbv2_init(d);
+       if (ret < 0)
+               goto err_usb_driver_release_interface;
+
+       dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
+                       "connected\n", KBUILD_MODNAME, d->name);
+
+       return;
+err_usb_driver_release_interface:
+       dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
+                       KBUILD_MODNAME, d->name, ret);
+       usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
+                       d->intf);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return;
+}
+
+int dvb_usbv2_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       int ret;
+       struct dvb_usb_device *d;
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct dvb_usb_driver_info *driver_info =
+                       (struct dvb_usb_driver_info *) id->driver_info;
+
+       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+                       intf->cur_altsetting->desc.bInterfaceNumber);
+
+       if (!id->driver_info) {
+               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+       if (!d) {
+               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       d->name = driver_info->name;
+       d->rc_map = driver_info->rc_map;
+       d->udev = udev;
+       d->intf = intf;
+       d->props = driver_info->props;
+
+       if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
+                       d->props->bInterfaceNumber) {
+               ret = -ENODEV;
+               goto err_kfree;
+       }
+
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
+       INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
+       usb_set_intfdata(intf, d);
+       ret = schedule_work(&d->probe_work);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
+                               KBUILD_MODNAME);
+               goto err_kfree;
+       }
+
+       return 0;
+err_kfree:
+       kfree(d);
+err:
+       dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_probe);
+
+void dvb_usbv2_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       const char *name = d->name;
+       struct device dev = d->udev->dev;
+       dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
+                       current->pid, d->work_pid);
+
+       /* ensure initialization work is finished until release resources */
+       if (d->work_pid != current->pid)
+               cancel_work_sync(&d->probe_work);
+
+       if (d->props->exit)
+               d->props->exit(d);
+
+       dvb_usbv2_exit(d);
+
+       dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
+                       KBUILD_MODNAME, name);
+}
+EXPORT_SYMBOL(dvb_usbv2_disconnect);
+
+int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* stop remote controller poll */
+       if (d->rc.query && !d->rc.bulk_mode)
+               cancel_delayed_work_sync(&d->rc_query_work);
+
+       /* stop streaming */
+       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+               if (d->adapter[i].dvb_adap.priv &&
+                               d->adapter[i].active_fe != -1)
+                       usb_urb_killv2(&d->adapter[i].stream);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(dvb_usbv2_suspend);
+
+int dvb_usbv2_resume(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* start streaming */
+       for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
+               if (d->adapter[i].dvb_adap.priv &&
+                               d->adapter[i].active_fe != -1)
+                       usb_urb_submitv2(&d->adapter[i].stream, NULL);
+       }
+
+       /* start remote controller poll */
+       if (d->rc.query && !d->rc.bulk_mode)
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+
+       return 0;
+}
+EXPORT_SYMBOL(dvb_usbv2_resume);
+
+MODULE_VERSION("2.0");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("DVB USB common");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
new file mode 100644 (file)
index 0000000..0431bee
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+               u16 rlen)
+{
+       int ret, actual_length;
+
+       if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
+                       !d->props->generic_bulk_ctrl_endpoint_response) {
+               dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
+               return -EINVAL;
+       }
+
+       ret = mutex_lock_interruptible(&d->usb_mutex);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
+
+       ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
+                       d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
+                       &actual_length, 2000);
+       if (ret < 0)
+               dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+       else
+               ret = actual_length != wlen ? -EIO : 0;
+
+       /* an answer is expected, and no error before */
+       if (!ret && rbuf && rlen) {
+               if (d->props->generic_bulk_ctrl_delay)
+                       usleep_range(d->props->generic_bulk_ctrl_delay,
+                                       d->props->generic_bulk_ctrl_delay
+                                       + 20000);
+
+               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+                               d->props->generic_bulk_ctrl_endpoint_response),
+                               rbuf, rlen, &actual_length, 2000);
+               if (ret)
+                       dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
+                                       "failed=%d\n", KBUILD_MODNAME, ret);
+
+               dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
+                               actual_length, rbuf);
+       }
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_rw);
+
+int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+       return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
new file mode 100644 (file)
index 0000000..ab77622
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 "ec168.h"
+#include "ec100.h"
+#include "mxl5005s.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
+{
+       int ret;
+       unsigned int pipe;
+       u8 request, requesttype;
+       u8 *buf;
+
+       switch (req->cmd) {
+       case DOWNLOAD_FIRMWARE:
+       case GPIO:
+       case WRITE_I2C:
+       case STREAMING_CTRL:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = req->cmd;
+               break;
+       case READ_I2C:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = req->cmd;
+               break;
+       case GET_CONFIG:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = CONFIG;
+               break;
+       case SET_CONFIG:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = CONFIG;
+               break;
+       case WRITE_DEMOD:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = DEMOD_RW;
+               break;
+       case READ_DEMOD:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = DEMOD_RW;
+               break;
+       default:
+               pr_err("%s: unknown command=%02x\n", KBUILD_MODNAME, req->cmd);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       buf = kmalloc(req->size, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+               /* write */
+               memcpy(buf, req->data, req->size);
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {
+               /* read */
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
+               req->index, buf, req->size, EC168_USB_TIMEOUT);
+
+       ec168_debug_dump(request, requesttype, req->value, req->index, buf,
+               req->size);
+
+       if (ret < 0)
+               goto err_dealloc;
+       else
+               ret = 0;
+
+       /* read request, copy returned data to return buf */
+       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+               memcpy(req->data, buf, req->size);
+
+       kfree(buf);
+       return ret;
+
+err_dealloc:
+       kfree(buf);
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+/* I2C */
+static struct ec100_config ec168_ec100_config;
+
+static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct ec168_req req;
+       int i = 0;
+       int ret;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].addr == ec168_ec100_config.demod_address) {
+                               req.cmd = READ_DEMOD;
+                               req.value = 0;
+                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
+                               req.size = msg[i+1].len; /* bytes to read */
+                               req.data = &msg[i+1].buf[0];
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 2;
+                       } else {
+                               pr_err("%s: I2C read not implemented\n",
+                                               KBUILD_MODNAME);
+                               ret = -EOPNOTSUPP;
+                               i += 2;
+                       }
+               } else {
+                       if (msg[i].addr == ec168_ec100_config.demod_address) {
+                               req.cmd = WRITE_DEMOD;
+                               req.value = msg[i].buf[1]; /* val */
+                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
+                               req.size = 0;
+                               req.data = NULL;
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 1;
+                       } else {
+                               req.cmd = WRITE_I2C;
+                               req.value = msg[i].buf[0]; /* val */
+                               req.index = 0x0100 + msg[i].addr; /* I2C addr */
+                               req.size = msg[i].len-1;
+                               req.data = &msg[i].buf[1];
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 1;
+                       }
+               }
+               if (ret)
+                       goto error;
+
+       }
+       ret = i;
+
+error:
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 ec168_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ec168_i2c_algo = {
+       .master_xfer   = ec168_i2c_xfer,
+       .functionality = ec168_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 reply;
+       struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
+       pr_debug("%s:\n", __func__);
+
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       pr_debug("%s: reply=%02x\n", __func__, reply);
+
+       if (reply == 0x01)
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec168_download_firmware(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, len, remaining;
+       struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
+       pr_debug("%s:\n", __func__);
+
+       #define LEN_MAX 2048 /* max packet size */
+       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+               len = remaining;
+               if (len > LEN_MAX)
+                       len = LEN_MAX;
+
+               req.size = len;
+               req.data = (u8 *) &fw->data[fw->size - remaining];
+               req.index = fw->size - remaining;
+
+               ret = ec168_ctrl_msg(d, &req);
+               if (ret) {
+                       pr_err("%s: firmware download failed=%d\n",
+                                       KBUILD_MODNAME, ret);
+                       goto error;
+               }
+       }
+
+       req.size = 0;
+
+       /* set "warm"? */
+       req.cmd = SET_CONFIG;
+       req.value = 0;
+       req.index = 0x0001;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       /* really needed - no idea what does */
+       req.cmd = GPIO;
+       req.value = 0;
+       req.index = 0x0206;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       /* activate tuner I2C? */
+       req.cmd = WRITE_I2C;
+       req.value = 0;
+       req.index = 0x00c6;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static struct ec100_config ec168_ec100_config = {
+       .demod_address = 0xff, /* not real address, demod is integrated */
+};
+
+static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+       adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct mxl5005s_config ec168_mxl5003s_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_OFF,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+       return dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
+}
+
+static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
+       pr_debug("%s: onoff=%d\n", __func__, onoff);
+       if (onoff)
+               req.index = 0x0102;
+       return ec168_ctrl_msg(fe_to_d(fe), &req);
+}
+
+/* DVB USB Driver stuff */
+/* bInterfaceNumber 0 is HID
+ * bInterfaceNumber 1 is DVB-T */
+static struct dvb_usb_device_properties ec168_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .bInterfaceNumber = 1,
+
+       .identify_state = ec168_identify_state,
+       .firmware = "dvb-usb-ec168.fw",
+       .download_firmware = ec168_download_firmware,
+
+       .i2c_algo = &ec168_i2c_algo,
+       .frontend_attach = ec168_ec100_frontend_attach,
+       .tuner_attach = ec168_mxl5003s_tuner_attach,
+       .streaming_ctrl = ec168_streaming_ctrl,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
+               }
+       },
+};
+
+static const struct dvb_usb_driver_info ec168_driver_info = {
+       .name = "E3C EC168 reference design",
+       .props = &ec168_props,
+};
+
+static const struct usb_device_id ec168_id[] = {
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       {}
+};
+MODULE_DEVICE_TABLE(usb, ec168_id);
+
+static struct usb_driver ec168_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = ec168_id,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(ec168_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC168 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.h b/drivers/media/usb/dvb-usb-v2/ec168.h
new file mode 100644 (file)
index 0000000..9181236
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 EC168_H
+#define EC168_H
+
+#include "dvb_usb.h"
+
+#define ec168_debug_dump(r, t, v, i, b, l) { \
+       char *direction; \
+       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+               direction = ">>>"; \
+       else \
+               direction = "<<<"; \
+       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s\n", \
+                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
+                       l & 0xff, l >> 8, direction); \
+}
+
+#define EC168_USB_TIMEOUT 1000
+
+struct ec168_req {
+       u8  cmd;       /* [1] */
+       u16 value;     /* [2|3] */
+       u16 index;     /* [4|5] */
+       u16 size;      /* [6|7] */
+       u8  *data;
+};
+
+enum ec168_cmd {
+       DOWNLOAD_FIRMWARE    = 0x00,
+       CONFIG               = 0x01,
+       DEMOD_RW             = 0x03,
+       GPIO                 = 0x04,
+       STREAMING_CTRL       = 0x10,
+       READ_I2C             = 0x20,
+       WRITE_I2C            = 0x21,
+       HID_DOWNLOAD         = 0x30,
+       GET_CONFIG,
+       SET_CONFIG,
+       READ_DEMOD,
+       WRITE_DEMOD,
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
new file mode 100644 (file)
index 0000000..cf29f43
--- /dev/null
@@ -0,0 +1,175 @@
+/* DVB USB compliant linux driver for GL861 USB2.0 devices.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gl861.h"
+
+#include "zl10353.h"
+#include "qt1010.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u16 index;
+       u16 value = addr << (8 + 1);
+       int wo = (rbuf == NULL || rlen == 0); /* write-only */
+       u8 req, type;
+
+       if (wo) {
+               req = GL861_REQ_I2C_WRITE;
+               type = GL861_WRITE;
+       } else { /* rw */
+               req = GL861_REQ_I2C_READ;
+               type = GL861_READ;
+       }
+
+       switch (wlen) {
+       case 1:
+               index = wbuf[0];
+               break;
+       case 2:
+               index = wbuf[0];
+               value = value + wbuf[1];
+               break;
+       default:
+               pr_err("%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen);
+               return -EINVAL;
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
+                              value, index, rbuf, rlen, 2000);
+}
+
+/* I2C */
+static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                         int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
+                               msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
+                               break;
+                       i++;
+               } else
+                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                         msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 gl861_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm gl861_i2c_algo = {
+       .master_xfer   = gl861_i2c_xfer,
+       .functionality = gl861_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config gl861_zl10353_config = {
+       .demod_address = 0x0f,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
+{
+
+       adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
+               &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static struct qt1010_config gl861_qt1010_config = {
+       .i2c_address = 0x62
+};
+
+static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(qt1010_attach,
+                         adap->fe[0], &adap_to_d(adap)->i2c_adap,
+                         &gl861_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+static int gl861_init(struct dvb_usb_device *d)
+{
+       /*
+        * There is 2 interfaces. Interface 0 is for TV and interface 1 is
+        * for HID remote controller. Interface 0 has 2 alternate settings.
+        * For some reason we need to set interface explicitly, defaulted
+        * as alternate setting 1?
+        */
+       return usb_set_interface(d->udev, 0, 0);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties gl861_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+
+       .i2c_algo = &gl861_i2c_algo,
+       .frontend_attach = gl861_frontend_attach,
+       .tuner_attach = gl861_tuner_attach,
+       .init = gl861_init,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
+               }
+       }
+};
+
+static const struct usb_device_id gl861_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
+               &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
+       { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
+               &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, gl861_id_table);
+
+static struct usb_driver gl861_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = gl861_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(gl861_usb_driver);
+
+MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
+MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.h b/drivers/media/usb/dvb-usb-v2/gl861.h
new file mode 100644 (file)
index 0000000..b0b80d8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _DVB_USB_GL861_H_
+#define _DVB_USB_GL861_H_
+
+#include "dvb_usb.h"
+
+#define GL861_WRITE            0x40
+#define GL861_READ             0xc0
+
+#define GL861_REQ_I2C_WRITE    0x01
+#define GL861_REQ_I2C_READ     0x02
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
new file mode 100644 (file)
index 0000000..695f910
--- /dev/null
@@ -0,0 +1,799 @@
+/*
+ * DVB USB compliant linux driver for ITE IT9135 and IT9137
+ *
+ * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
+ * IT9135 (C) ITE Tech Inc.
+ * IT9137 (C) ITE Tech Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ * see Documentation/dvb/it9137.txt for firmware information
+ *
+ */
+#define DVB_USB_LOG_PREFIX "it913x"
+
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
+
+#include "dvb_usb.h"
+#include "it913x-fe.h"
+
+/* debug */
+static int dvb_usb_it913x_debug;
+#define it_debug(var, level, args...) \
+       do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \
+} while (0)
+#define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args)
+#define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args)
+
+module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+static int dvb_usb_it913x_firmware;
+module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
+       "1=IT9137 2=IT9135 V1 3=IT9135 V2");
+#define FW_IT9137 "dvb-usb-it9137-01.fw"
+#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
+#define FW_IT9135_V2 "dvb-usb-it9135-02.fw"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct it913x_state {
+       struct ite_config it913x_config;
+       u8 pid_filter_onoff;
+       bool proprietary_ir;
+       int cmd_counter;
+};
+
+static u16 check_sum(u8 *p, u8 len)
+{
+       u16 sum = 0;
+       u8 i = 1;
+       while (i < len)
+               sum += (i++ & 1) ? (*p++) << 8 : *p++;
+       return ~sum;
+}
+
+static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro,
+                       u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
+{
+       struct it913x_state *st = d->priv;
+       int ret = 0, i, buf_size = 1;
+       u8 *buff;
+       u8 rlen;
+       u16 chk_sum;
+
+       buff = kzalloc(256, GFP_KERNEL);
+       if (!buff) {
+               info("USB Buffer Failed");
+               return -ENOMEM;
+       }
+
+       buff[buf_size++] = pro;
+       buff[buf_size++] = cmd;
+       buff[buf_size++] = st->cmd_counter;
+
+       switch (mode) {
+       case READ_LONG:
+       case WRITE_LONG:
+               buff[buf_size++] = len;
+               buff[buf_size++] = 2;
+               buff[buf_size++] = (reg >> 24);
+               buff[buf_size++] = (reg >> 16) & 0xff;
+               buff[buf_size++] = (reg >> 8) & 0xff;
+               buff[buf_size++] = reg & 0xff;
+       break;
+       case READ_SHORT:
+               buff[buf_size++] = addr;
+               break;
+       case WRITE_SHORT:
+               buff[buf_size++] = len;
+               buff[buf_size++] = addr;
+               buff[buf_size++] = (reg >> 8) & 0xff;
+               buff[buf_size++] = reg & 0xff;
+       break;
+       case READ_DATA:
+       case WRITE_DATA:
+               break;
+       case WRITE_CMD:
+               mode = 7;
+               break;
+       default:
+               kfree(buff);
+               return -EINVAL;
+       }
+
+       if (mode & 1) {
+               for (i = 0; i < len ; i++)
+                       buff[buf_size++] = data[i];
+       }
+       chk_sum = check_sum(&buff[1], buf_size);
+
+       buff[buf_size++] = chk_sum >> 8;
+       buff[0] = buf_size;
+       buff[buf_size++] = (chk_sum & 0xff);
+
+       ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ?
+                       5 : len + 5);
+       if (ret < 0)
+               goto error;
+
+       rlen = (mode & 0x1) ? 0x1 : len;
+
+       if (mode & 1)
+               ret = buff[2];
+       else
+               memcpy(data, &buff[3], rlen);
+
+       st->cmd_counter++;
+
+error: kfree(buff);
+
+       return ret;
+}
+
+static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data)
+{
+       int ret;
+       u8 b[1];
+       b[0] = data;
+       ret = it913x_io(d, WRITE_LONG, pro,
+                       CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
+
+       return ret;
+}
+
+static int it913x_read_reg(struct dvb_usb_device *d, u32 reg)
+{
+       int ret;
+       u8 data[1];
+
+       ret = it913x_io(d, READ_LONG, DEV_0,
+                       CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data));
+
+       return (ret < 0) ? ret : data[0];
+}
+
+static int it913x_query(struct dvb_usb_device *d, u8 pro)
+{
+       struct it913x_state *st = d->priv;
+       int ret, i;
+       u8 data[4];
+       u8 ver;
+
+       for (i = 0; i < 5; i++) {
+               ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ,
+                       0x1222, 0, &data[0], 3);
+               ver = data[0];
+               if (ver > 0 && ver < 3)
+                       break;
+               msleep(100);
+       }
+
+       if (ver < 1 || ver > 2) {
+               info("Failed to identify chip version applying 1");
+               st->it913x_config.chip_ver = 0x1;
+               st->it913x_config.chip_type = 0x9135;
+               return 0;
+       }
+
+       st->it913x_config.chip_ver = ver;
+       st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
+
+       info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver,
+               st->it913x_config.chip_type);
+
+       ret = it913x_io(d, READ_SHORT, pro,
+                       CMD_QUERYINFO, 0, 0x1, &data[0], 4);
+
+       st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) |
+                       (data[2] << 8) | data[3];
+
+       return ret;
+}
+
+static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct it913x_state *st = adap_to_priv(adap);
+       int ret;
+       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+       mutex_lock(&d->i2c_mutex);
+
+       deb_info(1, "PID_C  (%02x)", onoff);
+
+       ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff);
+
+       mutex_unlock(&d->i2c_mutex);
+       return ret;
+}
+
+static int it913x_pid_filter(struct dvb_usb_adapter *adap,
+               int index, u16 pid, int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct it913x_state *st = adap_to_priv(adap);
+       int ret;
+       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+       mutex_lock(&d->i2c_mutex);
+
+       deb_info(1, "PID_F  (%02x)", onoff);
+
+       ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff));
+
+       ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8));
+
+       ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff);
+
+       ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f));
+
+       if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
+                       ret |= it913x_wr_reg(d , pro, PID_EN, !onoff);
+                       st->pid_filter_onoff = !onoff;
+       } else
+               st->pid_filter_onoff =
+                       adap->pid_filtering;
+
+       mutex_unlock(&d->i2c_mutex);
+       return 0;
+}
+
+
+static int it913x_return_status(struct dvb_usb_device *d)
+{
+       struct it913x_state *st = d->priv;
+       int ret = it913x_query(d, DEV_0);
+       if (st->it913x_config.firmware > 0)
+               info("Firmware Version %d", st->it913x_config.firmware);
+
+       return ret;
+}
+
+static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       static u8 data[256];
+       int ret;
+       u32 reg;
+       u8 pro;
+
+       mutex_lock(&d->i2c_mutex);
+
+       deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
+
+       pro = (msg[0].addr & 0x2) ?  DEV_0_DMOD : 0x0;
+       pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
+       memcpy(data, msg[0].buf, msg[0].len);
+       reg = (data[0] << 24) + (data[1] << 16) +
+                       (data[2] << 8) + data[3];
+       if (num == 2) {
+               ret = it913x_io(d, READ_LONG, pro,
+                       CMD_DEMOD_READ, reg, 0, data, msg[1].len);
+               memcpy(msg[1].buf, data, msg[1].len);
+       } else
+               ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE,
+                       reg, 0, &data[4], msg[0].len - 4);
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static u32 it913x_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm it913x_i2c_algo = {
+       .master_xfer   = it913x_i2c_xfer,
+       .functionality = it913x_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+#define IT913X_POLL 250
+static int it913x_rc_query(struct dvb_usb_device *d)
+{
+       u8 ibuf[4];
+       int ret;
+       u32 key;
+       /* Avoid conflict with frontends*/
+       mutex_lock(&d->i2c_mutex);
+
+       ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET,
+               0, 0, &ibuf[0], sizeof(ibuf));
+
+       if ((ibuf[2] + ibuf[3]) == 0xff) {
+               key = ibuf[2];
+               key += ibuf[0] << 16;
+               key += ibuf[1] << 8;
+               deb_info(1, "NEC Extended Key =%08x", key);
+               if (d->rc_dev != NULL)
+                       rc_keydown(d->rc_dev, key, 0);
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+/* Firmware sets raw */
+static const char fw_it9135_v1[] = FW_IT9135_V1;
+static const char fw_it9135_v2[] = FW_IT9135_V2;
+static const char fw_it9137[] = FW_IT9137;
+
+static void ite_get_firmware_name(struct dvb_usb_device *d,
+       const char **name)
+{
+       struct it913x_state *st = d->priv;
+       int sw;
+       /* auto switch */
+       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2)
+               sw = IT9137_FW;
+       else if (st->it913x_config.chip_ver == 1)
+               sw = IT9135_V1_FW;
+       else
+               sw = IT9135_V2_FW;
+
+       /* force switch */
+       if (dvb_usb_it913x_firmware != IT9135_AUTO)
+               sw = dvb_usb_it913x_firmware;
+
+       switch (sw) {
+       case IT9135_V1_FW:
+               st->it913x_config.firmware_ver = 1;
+               st->it913x_config.adc_x2 = 1;
+               st->it913x_config.read_slevel = false;
+               *name = fw_it9135_v1;
+               break;
+       case IT9135_V2_FW:
+               st->it913x_config.firmware_ver = 1;
+               st->it913x_config.adc_x2 = 1;
+               st->it913x_config.read_slevel = false;
+               *name = fw_it9135_v2;
+               switch (st->it913x_config.tuner_id_0) {
+               case IT9135_61:
+               case IT9135_62:
+                       break;
+               default:
+                       info("Unknown tuner ID applying default 0x60");
+               case IT9135_60:
+                       st->it913x_config.tuner_id_0 = IT9135_60;
+               }
+               break;
+       case IT9137_FW:
+       default:
+               st->it913x_config.firmware_ver = 0;
+               st->it913x_config.adc_x2 = 0;
+               st->it913x_config.read_slevel = true;
+               *name = fw_it9137;
+       }
+
+       return;
+}
+
+#define TS_MPEG_PKT_SIZE       188
+#define EP_LOW                 21
+#define TS_BUFFER_SIZE_PID     (EP_LOW*TS_MPEG_PKT_SIZE)
+#define EP_HIGH                        348
+#define TS_BUFFER_SIZE_MAX     (EP_HIGH*TS_MPEG_PKT_SIZE)
+
+static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+               struct usb_data_stream_properties *stream)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       if (adap->pid_filtering)
+               stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID;
+       else
+               stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX;
+
+       return 0;
+}
+
+static int it913x_select_config(struct dvb_usb_device *d)
+{
+       struct it913x_state *st = d->priv;
+       int ret, reg;
+
+       ret = it913x_return_status(d);
+       if (ret < 0)
+               return ret;
+
+       if (st->it913x_config.chip_ver == 0x02
+                       && st->it913x_config.chip_type == 0x9135)
+               reg = it913x_read_reg(d, 0x461d);
+       else
+               reg = it913x_read_reg(d, 0x461b);
+
+       if (reg < 0)
+               return reg;
+
+       if (reg == 0) {
+               st->it913x_config.dual_mode = 0;
+               st->it913x_config.tuner_id_0 = IT9135_38;
+               st->proprietary_ir = true;
+       } else {
+               /* TS mode */
+               reg =  it913x_read_reg(d, 0x49c5);
+               if (reg < 0)
+                       return reg;
+               st->it913x_config.dual_mode = reg;
+
+               /* IR mode type */
+               reg = it913x_read_reg(d, 0x49ac);
+               if (reg < 0)
+                       return reg;
+               if (reg == 5) {
+                       info("Remote propriety (raw) mode");
+                       st->proprietary_ir = true;
+               } else if (reg == 1) {
+                       info("Remote HID mode NOT SUPPORTED");
+                       st->proprietary_ir = false;
+               }
+
+               /* Tuner_id */
+               reg = it913x_read_reg(d, 0x49d0);
+               if (reg < 0)
+                       return reg;
+               st->it913x_config.tuner_id_0 = reg;
+       }
+
+       info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode,
+               st->it913x_config.tuner_id_0);
+
+       return ret;
+}
+
+static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct it913x_state *st = fe_to_priv(fe);
+       int ret = 0;
+       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+       deb_info(1, "STM  (%02x)", onoff);
+
+       if (!onoff) {
+               mutex_lock(&d->i2c_mutex);
+
+               ret = it913x_wr_reg(d, pro, PID_RST, 0x1);
+
+               mutex_unlock(&d->i2c_mutex);
+               st->pid_filter_onoff =
+                       adap->pid_filtering;
+
+       }
+
+       return ret;
+}
+
+static int it913x_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       struct it913x_state *st = d->priv;
+       int ret;
+       u8 reg;
+
+       /* Read and select config */
+       ret = it913x_select_config(d);
+       if (ret < 0)
+               return ret;
+
+       ite_get_firmware_name(d, name);
+
+       if (st->it913x_config.firmware > 0)
+               return WARM;
+
+       if (st->it913x_config.dual_mode) {
+               st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0);
+               ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1);
+               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1);
+               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
+               msleep(50);
+               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0);
+               msleep(50);
+               reg = it913x_read_reg(d, GPIOH1_O);
+               if (reg == 0) {
+                       ret |= it913x_wr_reg(d, DEV_0,  GPIOH1_O, 0x1);
+                       ret |= it913x_return_status(d);
+                       if (ret != 0)
+                               ret = it913x_wr_reg(d, DEV_0,
+                                       GPIOH1_O, 0x0);
+               }
+       }
+
+       reg = it913x_read_reg(d, IO_MUX_POWER_CLK);
+
+       if (st->it913x_config.dual_mode) {
+               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
+               if (st->it913x_config.firmware_ver == 1)
+                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x1);
+               else
+                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x1);
+       } else {
+               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0);
+               if (st->it913x_config.firmware_ver == 1)
+                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x0);
+               else
+                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x0);
+       }
+
+       ret |= it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
+
+       return (ret < 0) ? ret : COLD;
+}
+
+static int it913x_download_firmware(struct dvb_usb_device *d,
+                                       const struct firmware *fw)
+{
+       struct it913x_state *st = d->priv;
+       int ret = 0, i = 0, pos = 0;
+       u8 packet_size, min_pkt;
+       u8 *fw_data;
+
+       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
+
+       info("FRM Starting Firmware Download");
+
+       /* Multi firmware loader */
+       /* This uses scatter write firmware headers */
+       /* The firmware must start with 03 XX 00 */
+       /* and be the extact firmware length */
+
+       if (st->it913x_config.chip_ver == 2)
+               min_pkt = 0x11;
+       else
+               min_pkt = 0x19;
+
+       while (i <= fw->size) {
+               if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
+                       || (i == fw->size)) {
+                       packet_size = i - pos;
+                       if ((packet_size > min_pkt) || (i == fw->size)) {
+                               fw_data = (u8 *)(fw->data + pos);
+                               pos += packet_size;
+                               if (packet_size > 0) {
+                                       ret = it913x_io(d, WRITE_DATA,
+                                               DEV_0, CMD_SCATTER_WRITE, 0,
+                                               0, fw_data, packet_size);
+                                       if (ret < 0)
+                                               break;
+                               }
+                               udelay(1000);
+                       }
+               }
+               i++;
+       }
+
+       if (ret < 0)
+               info("FRM Firmware Download Failed (%d)" , ret);
+       else
+               info("FRM Firmware Download Completed - Resetting Device");
+
+       msleep(30);
+
+       ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
+       if (ret < 0)
+               info("FRM Device not responding to reboot");
+
+       ret = it913x_return_status(d);
+       if (st->it913x_config.firmware == 0) {
+               info("FRM Failed to reboot device");
+               return -ENODEV;
+       }
+
+       msleep(30);
+
+       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_400);
+
+       msleep(30);
+
+       /* Tuner function */
+       if (st->it913x_config.dual_mode)
+               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0);
+       else
+               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68);
+
+       if ((st->it913x_config.chip_ver == 1) &&
+               (st->it913x_config.chip_type == 0x9135)) {
+               ret |= it913x_wr_reg(d, DEV_0,  PADODPU, 0x0);
+               ret |= it913x_wr_reg(d, DEV_0,  AGC_O_D, 0x0);
+               if (st->it913x_config.dual_mode) {
+                       ret |= it913x_wr_reg(d, DEV_1,  PADODPU, 0x0);
+                       ret |= it913x_wr_reg(d, DEV_1,  AGC_O_D, 0x0);
+               }
+       }
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_name(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       const char *desc = d->name;
+       char *fe_name[] = {"_1", "_2", "_3", "_4"};
+       char *name = adap->fe[0]->ops.info.name;
+
+       strlcpy(name, desc, 128);
+       strlcat(name, fe_name[adap->id], 128);
+
+       return 0;
+}
+
+static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct it913x_state *st = d->priv;
+       int ret = 0;
+       u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
+       u16 ep_size = adap->stream.buf_size / 4;
+       u8 pkt_size = 0x80;
+
+       if (d->udev->speed != USB_SPEED_HIGH)
+               pkt_size = 0x10;
+
+       st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK);
+
+       adap->fe[0] = dvb_attach(it913x_fe_attach,
+               &d->i2c_adap, adap_addr, &st->it913x_config);
+
+       if (adap->id == 0 && adap->fe[0]) {
+               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
+               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
+               it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
+               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
+               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
+                                       ep_size & 0xff);
+               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
+               ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
+       } else if (adap->id == 1 && adap->fe[0]) {
+               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
+               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
+                                       ep_size & 0xff);
+               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
+               it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1);
+               it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
+               it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
+               it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
+               it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
+               it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
+               ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
+       } else
+               return -ENODEV;
+
+       ret |= it913x_name(adap);
+
+       return ret;
+}
+
+/* DVB USB Driver */
+static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       struct it913x_state *st = d->priv;
+
+       if (st->proprietary_ir == false) {
+               rc->map_name = NULL;
+               return 0;
+       }
+
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query = it913x_rc_query;
+       rc->interval = 250;
+
+       return 0;
+}
+
+static int it913x_get_adapter_count(struct dvb_usb_device *d)
+{
+       struct it913x_state *st = d->priv;
+       if (st->it913x_config.dual_mode)
+               return 2;
+       return 1;
+}
+
+static struct dvb_usb_device_properties it913x_properties = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .bInterfaceNumber = 0,
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct it913x_state),
+
+       .identify_state = it913x_identify_state,
+       .i2c_algo = &it913x_i2c_algo,
+
+       .download_firmware = it913x_download_firmware,
+
+       .frontend_attach  = it913x_frontend_attach,
+       .get_rc_config = it913x_get_rc_config,
+       .get_stream_config = it913x_get_stream_config,
+       .get_adapter_count = it913x_get_adapter_count,
+       .streaming_ctrl   = it913x_streaming_ctrl,
+
+
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .pid_filter = it913x_pid_filter,
+                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
+                       .stream =
+                       DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX),
+               },
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .pid_filter = it913x_pid_filter,
+                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
+                       .stream =
+                       DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX),
+               }
+       }
+};
+
+static const struct usb_device_id it913x_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
+               &it913x_properties, "Kworld UB499-2T T09(IT9137)",
+                       RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
+               &it913x_properties, "ITE 9135 Generic",
+                       RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
+               &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)",
+                       RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
+               &it913x_properties, "ITE 9135(9005) Generic",
+                       RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
+               &it913x_properties, "ITE 9135(9006) Generic",
+                       RC_MAP_IT913X_V1) },
+       {}              /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, it913x_id_table);
+
+static struct usb_driver it913x_driver = {
+       .name           = KBUILD_MODNAME,
+       .probe          = dvb_usbv2_probe,
+       .disconnect     = dvb_usbv2_disconnect,
+       .suspend        = dvb_usbv2_suspend,
+       .resume         = dvb_usbv2_resume,
+       .id_table       = it913x_id_table,
+};
+
+module_usb_driver(it913x_driver);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("it913x USB 2 Driver");
+MODULE_VERSION("1.32");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FW_IT9135_V1);
+MODULE_FIRMWARE(FW_IT9135_V2);
+MODULE_FIRMWARE(FW_IT9137);
+
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
new file mode 100644 (file)
index 0000000..c41d9d9
--- /dev/null
@@ -0,0 +1,1369 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
+ *                             LME2510C + LG TDQY-P001F
+ *                             LME2510C + BS2F7HZ0194
+ *                             LME2510 + LG TDQY-P001F
+ *                             LME2510 + BS2F7HZ0194
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MV001F (LME2510+LGTDQY-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * MV0194 (LME2510+SHARP:BS2F7HZ0194)
+ * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
+ *
+ * MVB0194 (LME2510C+SHARP0194)
+ *
+ * LME2510C + M88RS2000
+ *
+ * For firmware see Documentation/dvb/lmedm04.txt
+ *
+ * I2C addresses:
+ * 0xd0 - STV0288      - Demodulator
+ * 0xc0 - Sharp IX2505V        - Tuner
+ * --
+ * 0x1c - TDA10086   - Demodulator
+ * 0xc0 - TDA8263    - Tuner
+ * --
+ * 0xd0 - STV0299      - Demodulator
+ * 0xc0 - IX2410       - Tuner
+ *
+ *
+ * VID = 3344  PID LME2510=1122 LME2510C=1120
+ *
+ * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
+ * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ * Known Issues :
+ *     LME2510: Non Intel USB chipsets fail to maintain High Speed on
+ * Boot or Hot Plug.
+ *
+ * QQbox suffers from noise on LNB voltage.
+ *
+ *     LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
+ * with other tuners. After a cold reset streaming will not start.
+ *
+ * M88RS2000 suffers from loss of lock.
+ */
+#define DVB_USB_LOG_PREFIX "LME2510(C)"
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
+
+#include "dvb_usb.h"
+#include "lmedm04.h"
+#include "tda826x.h"
+#include "tda10086.h"
+#include "stv0288.h"
+#include "ix2505v.h"
+#include "stv0299.h"
+#include "dvb-pll.h"
+#include "z0194a.h"
+#include "m88rs2000.h"
+
+
+#define LME2510_C_S7395        "dvb-usb-lme2510c-s7395.fw";
+#define LME2510_C_LG   "dvb-usb-lme2510c-lg.fw";
+#define LME2510_C_S0194        "dvb-usb-lme2510c-s0194.fw";
+#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
+#define LME2510_LG     "dvb-usb-lme2510-lg.fw";
+#define LME2510_S0194  "dvb-usb-lme2510-s0194.fw";
+
+/* debug */
+static int dvb_usb_lme2510_debug;
+#define lme_debug(var, level, args...) do { \
+       if ((var >= level)) \
+               pr_debug(DVB_USB_LOG_PREFIX": " args); \
+} while (0)
+#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
+#define debug_data_snipet(level, name, p) \
+        deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
+               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
+                       *(p+5), *(p+6), *(p+7));
+#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
+
+module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+static int dvb_usb_lme2510_firmware;
+module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
+
+static int pid_filter;
+module_param_named(pid, pid_filter, int, 0644);
+MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
+
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define TUNER_DEFAULT  0x0
+#define TUNER_LG       0x1
+#define TUNER_S7395    0x2
+#define TUNER_S0194    0x3
+#define TUNER_RS2000   0x4
+
+struct lme2510_state {
+       u8 id;
+       u8 tuner_config;
+       u8 signal_lock;
+       u8 signal_level;
+       u8 signal_sn;
+       u8 time_key;
+       u8 last_key;
+       u8 key_timeout;
+       u8 i2c_talk_onoff;
+       u8 i2c_gate;
+       u8 i2c_tuner_gate_w;
+       u8 i2c_tuner_gate_r;
+       u8 i2c_tuner_addr;
+       u8 stream_on;
+       u8 pid_size;
+       u8 pid_off;
+       void *buffer;
+       struct urb *lme_urb;
+       void *usb_buffer;
+       int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
+       u8 dvb_usb_lme2510_firmware;
+};
+
+static int lme2510_bulk_write(struct usb_device *dev,
+                               u8 *snd, int len, u8 pipe)
+{
+       int ret, actual_l;
+
+       ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
+                               snd, len , &actual_l, 100);
+       return ret;
+}
+
+static int lme2510_bulk_read(struct usb_device *dev,
+                               u8 *rev, int len, u8 pipe)
+{
+       int ret, actual_l;
+
+       ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
+                                rev, len , &actual_l, 200);
+       return ret;
+}
+
+static int lme2510_usb_talk(struct dvb_usb_device *d,
+               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       struct lme2510_state *st = d->priv;
+       u8 *buff;
+       int ret = 0;
+
+       if (st->usb_buffer == NULL) {
+               st->usb_buffer = kmalloc(64, GFP_KERNEL);
+               if (st->usb_buffer == NULL) {
+                       info("MEM Error no memory");
+                       return -ENOMEM;
+               }
+       }
+       buff = st->usb_buffer;
+
+       ret = mutex_lock_interruptible(&d->usb_mutex);
+
+       if (ret < 0)
+               return -EAGAIN;
+
+       /* the read/write capped at 64 */
+       memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
+
+       ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
+
+       ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
+                       rlen : 64 , 0x01);
+
+       if (rlen > 0)
+               memcpy(rbuf, buff, rlen);
+
+       mutex_unlock(&d->usb_mutex);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int lme2510_stream_restart(struct dvb_usb_device *d)
+{
+       struct lme2510_state *st = d->priv;
+       u8 all_pids[] = LME_ALL_PIDS;
+       u8 stream_on[] = LME_ST_ON_W;
+       int ret;
+       u8 rbuff[1];
+       if (st->pid_off)
+               ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
+                       rbuff, sizeof(rbuff));
+       /*Restart Stream Command*/
+       ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+                       rbuff, sizeof(rbuff));
+       return ret;
+}
+
+static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
+{
+       struct lme2510_state *st = d->priv;
+       static u8 pid_buff[] = LME_ZERO_PID;
+       static u8 rbuf[1];
+       u8 pid_no = index * 2;
+       u8 pid_len = pid_no + 2;
+       int ret = 0;
+       deb_info(1, "PID Setting Pid %04x", pid_out);
+
+       if (st->pid_size == 0)
+               ret |= lme2510_stream_restart(d);
+
+       pid_buff[2] = pid_no;
+       pid_buff[3] = (u8)pid_out & 0xff;
+       pid_buff[4] = pid_no + 1;
+       pid_buff[5] = (u8)(pid_out >> 8);
+
+       if (pid_len > st->pid_size)
+               st->pid_size = pid_len;
+       pid_buff[7] = 0x80 + st->pid_size;
+
+       ret |= lme2510_usb_talk(d, pid_buff ,
+               sizeof(pid_buff) , rbuf, sizeof(rbuf));
+
+       if (st->stream_on)
+               ret |= lme2510_stream_restart(d);
+
+       return ret;
+}
+
+static void lme2510_int_response(struct urb *lme_urb)
+{
+       struct dvb_usb_adapter *adap = lme_urb->context;
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 *ibuf, *rbuf;
+       int i = 0, offset;
+       u32 key;
+
+       switch (lme_urb->status) {
+       case 0:
+       case -ETIMEDOUT:
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:
+               info("Error %x", lme_urb->status);
+               break;
+       }
+
+       rbuf = (u8 *) lme_urb->transfer_buffer;
+
+       offset = ((lme_urb->actual_length/8) > 4)
+                       ? 4 : (lme_urb->actual_length/8) ;
+
+       for (i = 0; i < offset; ++i) {
+               ibuf = (u8 *)&rbuf[i*8];
+               deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
+               offset, i, ibuf[0], ibuf[1]);
+
+               switch (ibuf[0]) {
+               case 0xaa:
+                       debug_data_snipet(1, "INT Remote data snipet", ibuf);
+                       if ((ibuf[4] + ibuf[5]) == 0xff) {
+                               key = ibuf[5];
+                               key += (ibuf[3] > 0)
+                                       ? (ibuf[3] ^ 0xff) << 8 : 0;
+                               key += (ibuf[2] ^ 0xff) << 16;
+                               deb_info(1, "INT Key =%08x", key);
+                               if (adap_to_d(adap)->rc_dev != NULL)
+                                       rc_keydown(adap_to_d(adap)->rc_dev,
+                                               key, 0);
+                       }
+                       break;
+               case 0xbb:
+                       switch (st->tuner_config) {
+                       case TUNER_LG:
+                               if (ibuf[2] > 0)
+                                       st->signal_lock = ibuf[2];
+                               st->signal_level = ibuf[4];
+                               st->signal_sn = ibuf[3];
+                               st->time_key = ibuf[7];
+                               break;
+                       case TUNER_S7395:
+                       case TUNER_S0194:
+                               /* Tweak for earlier firmware*/
+                               if (ibuf[1] == 0x03) {
+                                       if (ibuf[2] > 1)
+                                               st->signal_lock = ibuf[2];
+                                       st->signal_level = ibuf[3];
+                                       st->signal_sn = ibuf[4];
+                               } else {
+                                       st->signal_level = ibuf[4];
+                                       st->signal_sn = ibuf[5];
+                                       st->signal_lock =
+                                               (st->signal_lock & 0xf7) +
+                                               ((ibuf[2] & 0x01) << 0x03);
+                               }
+                               break;
+                       case TUNER_RS2000:
+                               if (ibuf[1] == 0x3 &&  ibuf[6] == 0xff)
+                                       st->signal_lock = 0xff;
+                               else
+                                       st->signal_lock = 0x00;
+                               st->signal_level = ibuf[5];
+                               st->signal_sn = ibuf[4];
+                               st->time_key = ibuf[7];
+                       default:
+                               break;
+                       }
+                       debug_data_snipet(5, "INT Remote data snipet in", ibuf);
+               break;
+               case 0xcc:
+                       debug_data_snipet(1, "INT Control data snipet", ibuf);
+                       break;
+               default:
+                       debug_data_snipet(1, "INT Unknown data snipet", ibuf);
+               break;
+               }
+       }
+       usb_submit_urb(lme_urb, GFP_ATOMIC);
+}
+
+static int lme2510_int_read(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *lme_int = adap_to_priv(adap);
+
+       lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+       if (lme_int->lme_urb == NULL)
+                       return -ENOMEM;
+
+       lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
+                                       &lme_int->lme_urb->transfer_dma);
+
+       if (lme_int->buffer == NULL)
+                       return -ENOMEM;
+
+       usb_fill_int_urb(lme_int->lme_urb,
+                               d->udev,
+                               usb_rcvintpipe(d->udev, 0xa),
+                               lme_int->buffer,
+                               128,
+                               lme2510_int_response,
+                               adap,
+                               8);
+
+       lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
+       info("INT Interrupt Service Started");
+
+       return 0;
+}
+
+static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 clear_pid_reg[] = LME_ALL_PIDS;
+       static u8 rbuf[1];
+       int ret = 0;
+
+       deb_info(1, "PID Clearing Filter");
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (!onoff) {
+               ret |= lme2510_usb_talk(d, clear_pid_reg,
+                       sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
+               st->pid_off = true;
+       } else
+               st->pid_off = false;
+
+       st->pid_size = 0;
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return 0;
+}
+
+static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+       int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret = 0;
+
+       deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
+               pid, index, onoff);
+
+       if (onoff) {
+               mutex_lock(&d->i2c_mutex);
+               ret |= lme2510_enable_pid(d, index, pid);
+               mutex_unlock(&d->i2c_mutex);
+       }
+
+
+       return ret;
+}
+
+
+static int lme2510_return_status(struct dvb_usb_device *d)
+{
+       int ret = 0;
+       u8 *data;
+
+       data = kzalloc(10, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+                       0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
+       info("Firmware Status: %x (%x)", ret , data[2]);
+
+       ret = (ret < 0) ? -ENODEV : data[2];
+       kfree(data);
+       return ret;
+}
+
+static int lme2510_msg(struct dvb_usb_device *d,
+               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       int ret = 0;
+       struct lme2510_state *st = d->priv;
+
+       if (st->i2c_talk_onoff == 1) {
+
+               ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+
+               switch (st->tuner_config) {
+               case TUNER_LG:
+                       if (wbuf[2] == 0x1c) {
+                               if (wbuf[3] == 0x0e) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x10)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                                       msleep(80);
+                               }
+                       }
+                       break;
+               case TUNER_S7395:
+                       if (wbuf[2] == 0xd0) {
+                               if (wbuf[3] == 0x24) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x8)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                               }
+                       }
+                       break;
+               case TUNER_S0194:
+                       if (wbuf[2] == 0xd0) {
+                               if (wbuf[3] == 0x1b) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x8)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                               }
+                       }
+                       break;
+               case TUNER_RS2000:
+               default:
+                       break;
+               }
+       } else {
+               /* TODO rewrite this section */
+               switch (st->tuner_config) {
+               case TUNER_LG:
+                       switch (wbuf[3]) {
+                       case 0x0e:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x43:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_level;
+                               break;
+                       case 0x1c:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x15:
+                       case 0x16:
+                       case 0x17:
+                       case 0x18:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_S7395:
+                       switch (wbuf[3]) {
+                       case 0x10:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = (st->signal_level & 0x80)
+                                               ? 0 : (st->signal_level * 2);
+                               break;
+                       case 0x2d:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x24:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x2e:
+                       case 0x26:
+                       case 0x27:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_S0194:
+                       switch (wbuf[3]) {
+                       case 0x18:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = (st->signal_level & 0x80)
+                                               ? 0 : (st->signal_level * 2);
+                               break;
+                       case 0x24:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x1b:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x19:
+                       case 0x25:
+                       case 0x1e:
+                       case 0x1d:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_RS2000:
+                       switch (wbuf[3]) {
+                       case 0x8c:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0xff;
+                               if (st->last_key == st->time_key) {
+                                       st->key_timeout++;
+                                       if (st->key_timeout > 5)
+                                               rbuf[1] = 0;
+                               } else
+                                       st->key_timeout = 0;
+                               st->last_key = st->time_key;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+               default:
+                       break;
+               }
+
+               deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
+                               wbuf[3], rbuf[1]);
+
+       }
+
+       return ret;
+}
+
+
+static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct lme2510_state *st = d->priv;
+       static u8 obuf[64], ibuf[64];
+       int i, read, read_o;
+       u16 len;
+       u8 gate = st->i2c_gate;
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (gate == 0)
+               gate = 5;
+
+       for (i = 0; i < num; i++) {
+               read_o = 1 & (msg[i].flags & I2C_M_RD);
+               read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+               read |= read_o;
+               gate = (msg[i].addr == st->i2c_tuner_addr)
+                       ? (read)        ? st->i2c_tuner_gate_r
+                                       : st->i2c_tuner_gate_w
+                       : st->i2c_gate;
+               obuf[0] = gate | (read << 7);
+
+               if (gate == 5)
+                       obuf[1] = (read) ? 2 : msg[i].len + 1;
+               else
+                       obuf[1] = msg[i].len + read + 1;
+
+               obuf[2] = msg[i].addr;
+               if (read) {
+                       if (read_o)
+                               len = 3;
+                       else {
+                               memcpy(&obuf[3], msg[i].buf, msg[i].len);
+                               obuf[msg[i].len+3] = msg[i+1].len;
+                               len = msg[i].len+4;
+                       }
+               } else {
+                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
+                       len = msg[i].len+3;
+               }
+
+               if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
+                       deb_info(1, "i2c transfer failed.");
+                       mutex_unlock(&d->i2c_mutex);
+                       return -EAGAIN;
+               }
+
+               if (read) {
+                       if (read_o)
+                               memcpy(msg[i].buf, &ibuf[1], msg[i].len);
+                       else {
+                               memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
+                               i++;
+                       }
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm lme2510_i2c_algo = {
+       .master_xfer   = lme2510_i2c_xfer,
+       .functionality = lme2510_i2c_func,
+};
+
+static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 clear_reg_3[] = LME_ALL_PIDS;
+       static u8 rbuf[1];
+       int ret = 0, rlen = sizeof(rbuf);
+
+       deb_info(1, "STM  (%02x)", onoff);
+
+       /* Streaming is started by FE_HAS_LOCK */
+       if (onoff == 1)
+               st->stream_on = 1;
+       else {
+               deb_info(1, "STM Steam Off");
+               /* mutex is here only to avoid collision with I2C */
+               mutex_lock(&d->i2c_mutex);
+
+               ret = lme2510_usb_talk(d, clear_reg_3,
+                               sizeof(clear_reg_3), rbuf, rlen);
+               st->stream_on = 0;
+               st->i2c_talk_onoff = 1;
+
+               mutex_unlock(&d->i2c_mutex);
+       }
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static u8 check_sum(u8 *p, u8 len)
+{
+       u8 sum = 0;
+       while (len--)
+               sum += *p++;
+       return sum;
+}
+
+static int lme2510_download_firmware(struct dvb_usb_device *d,
+                                       const struct firmware *fw)
+{
+       int ret = 0;
+       u8 *data;
+       u16 j, wlen, len_in, start, end;
+       u8 packet_size, dlen, i;
+       u8 *fw_data;
+
+       packet_size = 0x31;
+       len_in = 1;
+
+       data = kzalloc(128, GFP_KERNEL);
+       if (!data) {
+               info("FRM Could not start Firmware Download"\
+                       "(Buffer allocation failed)");
+               return -ENOMEM;
+       }
+
+       info("FRM Starting Firmware Download");
+
+       for (i = 1; i < 3; i++) {
+               start = (i == 1) ? 0 : 512;
+               end = (i == 1) ? 512 : fw->size;
+               for (j = start; j < end; j += (packet_size+1)) {
+                       fw_data = (u8 *)(fw->data + j);
+                       if ((end - j) > packet_size) {
+                               data[0] = i;
+                               dlen = packet_size;
+                       } else {
+                               data[0] = i | 0x80;
+                               dlen = (u8)(end - j)-1;
+                       }
+                       data[1] = dlen;
+                       memcpy(&data[2], fw_data, dlen+1);
+                       wlen = (u8) dlen + 4;
+                       data[wlen-1] = check_sum(fw_data, dlen+1);
+                       deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
+                               data[dlen+2], data[dlen+3]);
+                       lme2510_usb_talk(d, data, wlen, data, len_in);
+                       ret |= (data[0] == 0x88) ? 0 : -1;
+               }
+       }
+
+       data[0] = 0x8a;
+       len_in = 1;
+       msleep(2000);
+       lme2510_usb_talk(d, data, len_in, data, len_in);
+       msleep(400);
+
+       if (ret < 0)
+               info("FRM Firmware Download Failed (%04x)" , ret);
+       else
+               info("FRM Firmware Download Completed - Resetting Device");
+
+       kfree(data);
+       return RECONNECTS_USB;
+}
+
+static void lme_coldreset(struct dvb_usb_device *d)
+{
+       u8 data[1] = {0};
+       data[0] = 0x0a;
+       info("FRM Firmware Cold Reset");
+
+       lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
+
+       return;
+}
+
+static const char fw_c_s7395[] = LME2510_C_S7395;
+static const char fw_c_lg[] = LME2510_C_LG;
+static const char fw_c_s0194[] = LME2510_C_S0194;
+static const char fw_c_rs2000[] = LME2510_C_RS2000;
+static const char fw_lg[] = LME2510_LG;
+static const char fw_s0194[] = LME2510_S0194;
+
+const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
+{
+       struct lme2510_state *st = d->priv;
+       struct usb_device *udev = d->udev;
+       const struct firmware *fw = NULL;
+       const char *fw_lme;
+       int ret = 0;
+
+       cold = (cold > 0) ? (cold & 1) : 0;
+
+       switch (le16_to_cpu(udev->descriptor.idProduct)) {
+       case 0x1122:
+               switch (st->dvb_usb_lme2510_firmware) {
+               default:
+                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
+               case TUNER_S0194:
+                       fw_lme = fw_s0194;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0) {
+                               cold = 0;
+                               break;
+                       }
+                       st->dvb_usb_lme2510_firmware = TUNER_LG;
+               case TUNER_LG:
+                       fw_lme = fw_lg;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+                       break;
+               }
+               break;
+       case 0x1120:
+               switch (st->dvb_usb_lme2510_firmware) {
+               default:
+                       st->dvb_usb_lme2510_firmware = TUNER_S7395;
+               case TUNER_S7395:
+                       fw_lme = fw_c_s7395;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0) {
+                               cold = 0;
+                               break;
+                       }
+                       st->dvb_usb_lme2510_firmware = TUNER_LG;
+               case TUNER_LG:
+                       fw_lme = fw_c_lg;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
+               case TUNER_S0194:
+                       fw_lme = fw_c_s0194;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+                       cold = 0;
+                       break;
+               }
+               break;
+       case 0x22f0:
+               fw_lme = fw_c_rs2000;
+               st->dvb_usb_lme2510_firmware = TUNER_RS2000;
+               break;
+       default:
+               fw_lme = fw_c_s7395;
+       }
+
+       release_firmware(fw);
+
+       if (cold) {
+               dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
+               info("FRM Changing to %s firmware", fw_lme);
+               lme_coldreset(d);
+               return NULL;
+       }
+
+       return fw_lme;
+}
+
+static int lme2510_kill_urb(struct usb_data_stream *stream)
+{
+       int i;
+
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               deb_info(3, "killing URB no. %d.", i);
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+
+       return 0;
+}
+
+static struct tda10086_config tda10086_config = {
+       .demod_address = 0x1c,
+       .invert = 0,
+       .diseqc_tone = 1,
+       .xtal_freq = TDA10086_XTAL_16M,
+};
+
+static struct stv0288_config lme_config = {
+       .demod_address = 0xd0,
+       .min_delay_ms = 15,
+       .inittab = s7395_inittab,
+};
+
+static struct ix2505v_config lme_tuner = {
+       .tuner_address = 0xc0,
+       .min_delay_ms = 100,
+       .tuner_gain = 0x0,
+       .tuner_chargepump = 0x3,
+};
+
+static struct stv0299_config sharp_z0194_config = {
+       .demod_address = 0xd0,
+       .inittab = sharp_z0194a_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .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 int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
+       int caller)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = d->priv;
+
+       mutex_lock(&d->i2c_mutex);
+       if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
+               st->i2c_talk_onoff = 0;
+               lme2510_stream_restart(d);
+       }
+       mutex_unlock(&d->i2c_mutex);
+
+       return 0;
+}
+
+static struct m88rs2000_config m88rs2000_config = {
+       .demod_addr = 0xd0,
+       .tuner_addr = 0xc0,
+       .set_ts_params = dm04_rs2000_set_ts_param,
+};
+
+static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
+                                       fe_sec_voltage_t voltage)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+       struct lme2510_state *st = fe_to_priv(fe);
+       static u8 voltage_low[] = LME_VOLTAGE_L;
+       static u8 voltage_high[] = LME_VOLTAGE_H;
+       static u8 rbuf[1];
+       int ret = 0, len = 3, rlen = 1;
+
+       mutex_lock(&d->i2c_mutex);
+
+       switch (voltage) {
+       case SEC_VOLTAGE_18:
+               ret |= lme2510_usb_talk(d,
+                       voltage_high, len, rbuf, rlen);
+               break;
+
+       case SEC_VOLTAGE_OFF:
+       case SEC_VOLTAGE_13:
+       default:
+               ret |= lme2510_usb_talk(d,
+                               voltage_low, len, rbuf, rlen);
+               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       if (st->tuner_config == TUNER_RS2000)
+               if (st->fe_set_voltage)
+                       st->fe_set_voltage(fe, voltage);
+
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       struct lme2510_state *st = fe_to_priv(fe);
+
+       *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
+
+       return 0;
+}
+
+static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lme2510_state *st = fe_to_priv(fe);
+
+       *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
+
+       return 0;
+}
+
+static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       *ber = 0;
+
+       return 0;
+}
+
+static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+
+       return 0;
+}
+
+static int lme_name(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       const char *desc = d->name;
+       char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
+                               " SHARP:BS2F7HZ0194", " RS2000"};
+       char *name = adap->fe[0]->ops.info.name;
+
+       strlcpy(name, desc, 128);
+       strlcat(name, fe_name[st->tuner_config], 128);
+
+       return 0;
+}
+
+static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = d->priv;
+       int ret = 0;
+
+       st->i2c_talk_onoff = 1;
+       switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
+       case 0x1122:
+       case 0x1120:
+               st->i2c_gate = 4;
+               adap->fe[0] = dvb_attach(tda10086_attach,
+                       &tda10086_config, &d->i2c_adap);
+               if (adap->fe[0]) {
+                       info("TUN Found Frontend TDA10086");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 4;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_LG;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
+                               st->dvb_usb_lme2510_firmware = TUNER_LG;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+
+               st->i2c_gate = 4;
+               adap->fe[0] = dvb_attach(stv0299_attach,
+                               &sharp_z0194_config, &d->i2c_adap);
+               if (adap->fe[0]) {
+                       info("FE Found Stv0299");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_S0194;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
+                               st->dvb_usb_lme2510_firmware = TUNER_S0194;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+
+               st->i2c_gate = 5;
+               adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
+                       &d->i2c_adap);
+
+               if (adap->fe[0]) {
+                       info("FE Found Stv0288");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_S7395;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
+                               st->dvb_usb_lme2510_firmware = TUNER_S7395;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+       case 0x22f0:
+               st->i2c_gate = 5;
+               adap->fe[0] = dvb_attach(m88rs2000_attach,
+                       &m88rs2000_config, &d->i2c_adap);
+
+               if (adap->fe[0]) {
+                       info("FE Found M88RS2000");
+                       st->i2c_tuner_gate_w = 5;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_RS2000;
+                       st->fe_set_voltage =
+                               adap->fe[0]->ops.set_voltage;
+
+                       adap->fe[0]->ops.read_signal_strength =
+                               dm04_rs2000_read_signal_strength;
+                       adap->fe[0]->ops.read_snr =
+                               dm04_rs2000_read_snr;
+                       adap->fe[0]->ops.read_ber =
+                               dm04_read_ber;
+                       adap->fe[0]->ops.read_ucblocks =
+                               dm04_read_ucblocks;
+               }
+               break;
+       }
+
+       if (adap->fe[0] == NULL) {
+               info("DM04/QQBOX Not Powered up or not Supported");
+               return -ENODEV;
+       }
+
+       if (ret) {
+               if (adap->fe[0]) {
+                       dvb_frontend_detach(adap->fe[0]);
+                       adap->fe[0] = NULL;
+               }
+               d->rc_map = NULL;
+               return -ENODEV;
+       }
+
+       adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
+       ret = lme_name(adap);
+       return ret;
+}
+
+static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
+       int ret = 0;
+
+       switch (st->tuner_config) {
+       case TUNER_LG:
+               if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
+                       &d->i2c_adap, 1))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_S7395:
+               if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
+                       &d->i2c_adap))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_S0194:
+               if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
+                       &d->i2c_adap, DVB_PLL_OPERA1))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_RS2000:
+               ret = st->tuner_config;
+               break;
+       default:
+               break;
+       }
+
+       if (ret)
+               info("TUN Found %s tuner", tun_msg[ret]);
+       else {
+               info("TUN No tuner found --- resetting device");
+               lme_coldreset(d);
+               return -ENODEV;
+       }
+
+       /* Start the Interrupt*/
+       ret = lme2510_int_read(adap);
+       if (ret < 0) {
+               info("INT Unable to start Interrupt Service");
+               return -ENODEV;
+       }
+
+       return ret;
+}
+
+static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
+{
+       struct lme2510_state *st = d->priv;
+       static u8 lnb_on[] = LNB_ON;
+       static u8 lnb_off[] = LNB_OFF;
+       static u8 rbuf[1];
+       int ret = 0, len = 3, rlen = 1;
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (onoff)
+               ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+       else
+               ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+
+       st->i2c_talk_onoff = 1;
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static int lme2510_get_adapter_count(struct dvb_usb_device *d)
+{
+       return 1;
+}
+
+static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       struct lme2510_state *st = d->priv;
+
+       usb_reset_configuration(d->udev);
+
+       usb_set_interface(d->udev,
+               d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
+
+       st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
+
+       if (lme2510_return_status(d) == 0x44) {
+               *name = lme_firmware_switch(d, 0);
+               return COLD;
+       }
+
+       return 0;
+}
+
+static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+               struct usb_data_stream_properties *stream)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+
+       if (adap == NULL)
+               return 0;
+       /* Turn PID filter on the fly by module option */
+       if (pid_filter == 2) {
+               adap->pid_filtering  = 1;
+               adap->max_feed_count = 15;
+       }
+
+       if (!(le16_to_cpu(d->udev->descriptor.idProduct)
+               == 0x1122))
+               stream->endpoint = 0x8;
+
+       return 0;
+}
+
+static int lme2510_get_rc_config(struct dvb_usb_device *d,
+       struct dvb_usb_rc *rc)
+{
+       rc->allowed_protos = RC_TYPE_NEC;
+       return 0;
+}
+
+static void *lme2510_exit_int(struct dvb_usb_device *d)
+{
+       struct lme2510_state *st = d->priv;
+       struct dvb_usb_adapter *adap = &d->adapter[0];
+       void *buffer = NULL;
+
+       if (adap != NULL) {
+               lme2510_kill_urb(&adap->stream);
+       }
+
+       if (st->usb_buffer != NULL) {
+               st->i2c_talk_onoff = 1;
+               st->signal_lock = 0;
+               st->signal_level = 0;
+               st->signal_sn = 0;
+               buffer = st->usb_buffer;
+       }
+
+       if (st->lme_urb != NULL) {
+               usb_kill_urb(st->lme_urb);
+               usb_free_coherent(d->udev, 128, st->buffer,
+                                 st->lme_urb->transfer_dma);
+               info("Interrupt Service Stopped");
+       }
+
+       return buffer;
+}
+
+static void lme2510_exit(struct dvb_usb_device *d)
+{
+       void *usb_buffer;
+
+       if (d != NULL) {
+               usb_buffer = lme2510_exit_int(d);
+               if (usb_buffer != NULL)
+                       kfree(usb_buffer);
+       }
+}
+
+static struct dvb_usb_device_properties lme2510_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .bInterfaceNumber = 0,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct lme2510_state),
+
+       .download_firmware = lme2510_download_firmware,
+
+       .power_ctrl       = lme2510_powerup,
+       .identify_state   = lme2510_identify_state,
+       .i2c_algo         = &lme2510_i2c_algo,
+
+       .frontend_attach  = dm04_lme2510_frontend_attach,
+       .tuner_attach = dm04_lme2510_tuner,
+       .get_stream_config = lme2510_get_stream_config,
+       .get_adapter_count = lme2510_get_adapter_count,
+       .streaming_ctrl   = lme2510_streaming_ctrl,
+
+       .get_rc_config = lme2510_get_rc_config,
+
+       .exit = lme2510_exit,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 15,
+                       .pid_filter = lme2510_pid_filter,
+                       .pid_filter_ctrl  = lme2510_pid_filter_ctrl,
+                       .stream =
+                       DVB_USB_STREAM_BULK(0x86, 10, 4096),
+               },
+               {
+               }
+       },
+};
+
+static const struct usb_device_id lme2510_id_table[] = {
+       {       DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
+               "DM04_LME2510_DVB-S", RC_MAP_LME2510)   },
+       {       DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
+               "DM04_LME2510C_DVB-S", RC_MAP_LME2510)  },
+       {       DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
+               "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510)   },
+       {}              /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, lme2510_id_table);
+
+static struct usb_driver lme2510_driver = {
+       .name           = KBUILD_MODNAME,
+       .probe          = dvb_usbv2_probe,
+       .disconnect     = dvb_usbv2_disconnect,
+       .id_table       = lme2510_id_table,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(lme2510_driver);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
+MODULE_VERSION("2.06");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(LME2510_C_S7395);
+MODULE_FIRMWARE(LME2510_C_LG);
+MODULE_FIRMWARE(LME2510_C_S0194);
+MODULE_FIRMWARE(LME2510_C_RS2000);
+MODULE_FIRMWARE(LME2510_LG);
+MODULE_FIRMWARE(LME2510_S0194);
+
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.h b/drivers/media/usb/dvb-usb-v2/lmedm04.h
new file mode 100644 (file)
index 0000000..e9c2072
--- /dev/null
@@ -0,0 +1,175 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
+ *                             LME2510C + LG TDQY-P001F
+ *                             LME2510 + LG TDQY-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MVB001F (LME2510+LGTDQT-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * 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,  version 2.
+ * *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_LME2510_H_
+#define _DVB_USB_LME2510_H_
+
+/* Streamer &  PID
+ *
+ * Note:       These commands do not actually stop the streaming
+ *             but form some kind of packet filtering/stream count
+ *             or tuning related functions.
+ *  06 XX
+ *  offset 1 = 00 Enable Streaming
+ *
+ *
+ *  PID
+ *  03 XX XX  ----> reg number ---> setting....20 XX
+ *  offset 1 = length
+ *  offset 2 = start of data
+ *  end byte -1 = 20
+ *  end byte = clear pid always a0, other wise 9c, 9a ??
+ *
+*/
+#define LME_ST_ON_W    {0x06, 0x00}
+#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
+#define LME_ZERO_PID   {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
+#define LME_ALL_PIDS   {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
+
+/*  LNB Voltage
+ *  07 XX XX
+ *  offset 1 = 01
+ *  offset 2 = 00=Voltage low 01=Voltage high
+ *
+ *  LNB Power
+ *  03 01 XX
+ *  offset 2 = 00=ON 01=OFF
+ */
+
+#define LME_VOLTAGE_L  {0x07, 0x01, 0x00}
+#define LME_VOLTAGE_H  {0x07, 0x01, 0x01}
+#define LNB_ON         {0x3a, 0x01, 0x00}
+#define LNB_OFF                {0x3a, 0x01, 0x01}
+
+/* Initial stv0288 settings for 7395 Frontend */
+static u8 s7395_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x20,
+       0x03, 0xa0,
+       0x04, 0xa0,
+       0x05, 0x12,
+       0x06, 0x00,
+       0x09, 0x00,
+       0x0a, 0x04,
+       0x0b, 0x00,
+       0x0c, 0x00,
+       0x0d, 0x00,
+       0x0e, 0xc1,
+       0x0f, 0x54,
+       0x11, 0x7a,
+       0x12, 0x03,
+       0x13, 0x48,
+       0x14, 0x84,
+       0x15, 0xc5,
+       0x16, 0xb8,
+       0x17, 0x9c,
+       0x18, 0x00,
+       0x19, 0xa6,
+       0x1a, 0x88,
+       0x1b, 0x8f,
+       0x1c, 0xf0,
+       0x20, 0x0b,
+       0x21, 0x54,
+       0x22, 0xff,
+       0x23, 0x01,
+       0x28, 0x46,
+       0x29, 0x66,
+       0x2a, 0x90,
+       0x2b, 0xfa,
+       0x2c, 0xd9,
+       0x30, 0x0,
+       0x31, 0x1e,
+       0x32, 0x14,
+       0x33, 0x0f,
+       0x34, 0x09,
+       0x35, 0x0c,
+       0x36, 0x05,
+       0x37, 0x2f,
+       0x38, 0x16,
+       0x39, 0xbd,
+       0x3a, 0x0,
+       0x3b, 0x13,
+       0x3c, 0x11,
+       0x3d, 0x30,
+       0x40, 0x63,
+       0x41, 0x04,
+       0x42, 0x20,
+       0x43, 0x00,
+       0x44, 0x00,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x47, 0x00,
+       0x4a, 0x00,
+       0x50, 0x10,
+       0x51, 0x36,
+       0x52, 0x21,
+       0x53, 0x94,
+       0x54, 0xb2,
+       0x55, 0x29,
+       0x56, 0x64,
+       0x57, 0x2b,
+       0x58, 0x54,
+       0x59, 0x86,
+       0x5a, 0x00,
+       0x5b, 0x9b,
+       0x5c, 0x08,
+       0x5d, 0x7f,
+       0x5e, 0xff,
+       0x5f, 0x8d,
+       0x70, 0x0,
+       0x71, 0x0,
+       0x72, 0x0,
+       0x74, 0x0,
+       0x75, 0x0,
+       0x76, 0x0,
+       0x81, 0x0,
+       0x82, 0x3f,
+       0x83, 0x3f,
+       0x84, 0x0,
+       0x85, 0x0,
+       0x88, 0x0,
+       0x89, 0x0,
+       0x8a, 0x0,
+       0x8b, 0x0,
+       0x8c, 0x0,
+       0x90, 0x0,
+       0x91, 0x0,
+       0x92, 0x0,
+       0x93, 0x0,
+       0x94, 0x1c,
+       0x97, 0x0,
+       0xa0, 0x48,
+       0xa1, 0x0,
+       0xb0, 0xb8,
+       0xb1, 0x3a,
+       0xb2, 0x10,
+       0xb3, 0x82,
+       0xb4, 0x80,
+       0xb5, 0x82,
+       0xb6, 0x82,
+       0xb7, 0x82,
+       0xb8, 0x20,
+       0xb9, 0x0,
+       0xf0, 0x0,
+       0xf1, 0x0,
+       0xf2, 0xc0,
+       0xff, 0xff,
+};
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
new file mode 100644 (file)
index 0000000..d83df4b
--- /dev/null
@@ -0,0 +1,612 @@
+/*
+ *  mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-demod.h"
+#include "mxl111sf-reg.h"
+
+/* debug */
+static int mxl111sf_demod_debug;
+module_param_named(debug, mxl111sf_demod_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define mxl_dbg(fmt, arg...) \
+       if (mxl111sf_demod_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+/* ------------------------------------------------------------------------ */
+
+struct mxl111sf_demod_state {
+       struct mxl111sf_state *mxl_state;
+
+       struct mxl111sf_demod_config *cfg;
+
+       struct dvb_frontend fe;
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
+                                  u8 addr, u8 *data)
+{
+       return (state->cfg->read_reg) ?
+               state->cfg->read_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
+                                   u8 addr, u8 data)
+{
+       return (state->cfg->write_reg) ?
+               state->cfg->write_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static
+int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
+                               struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       return (state->cfg->program_regs) ?
+               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
+               -EINVAL;
+}
+
+/* ------------------------------------------------------------------------ */
+/* TPS */
+
+static
+int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
+                                    fe_code_rate_t *code_rate)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
+       /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (val & V6_CODE_RATE_TPS_MASK) {
+       case 0:
+               *code_rate = FEC_1_2;
+               break;
+       case 1:
+               *code_rate = FEC_2_3;
+               break;
+       case 2:
+               *code_rate = FEC_3_4;
+               break;
+       case 3:
+               *code_rate = FEC_5_6;
+               break;
+       case 4:
+               *code_rate = FEC_7_8;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state,
+                                        fe_modulation_t *modulation)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
+       /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
+       case 0:
+               *modulation = QPSK;
+               break;
+       case 1:
+               *modulation = QAM_16;
+               break;
+       case 2:
+               *modulation = QAM_64;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
+                                         fe_transmit_mode_t *fft_mode)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
+       /* FFT Mode, 00:2K, 01:8K, 10:4K */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
+       case 0:
+               *fft_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               *fft_mode = TRANSMISSION_MODE_8K;
+               break;
+       case 2:
+               *fft_mode = TRANSMISSION_MODE_4K;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
+                                         fe_guard_interval_t *guard)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
+       /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_GI_MASK) >> 4) {
+       case 0:
+               *guard = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               *guard = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               *guard = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               *guard = GUARD_INTERVAL_1_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
+                                    fe_hierarchy_t *hierarchy)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
+       /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
+       case 0:
+               *hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               *hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               *hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               *hierarchy = HIERARCHY_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* LOCKS */
+
+static
+int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
+                                       int *sync_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
+                                     int *rs_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
+                                      int *tps_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
+                                      int *fec_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
+fail:
+       return ret;
+}
+
+#if 0
+static
+int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
+                                     int *cp_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
+fail:
+       return ret;
+}
+#endif
+
+static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
+{
+       return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret = 0;
+
+       struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
+               {0x00, 0xff, 0x01}, /* change page to 1 */
+               {0x40, 0xff, 0x05},
+               {0x40, 0xff, 0x01},
+               {0x41, 0xff, 0xca},
+               {0x41, 0xff, 0xc0},
+               {0x00, 0xff, 0x00}, /* change page to 0 */
+               {0,    0,    0}
+       };
+
+       mxl_dbg("()");
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (mxl_fail(ret))
+                       goto fail;
+               msleep(50);
+       }
+       ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
+       mxl_fail(ret);
+       msleep(50);
+       ret = mxl1x1sf_demod_reset_irq_status(state);
+       mxl_fail(ret);
+       msleep(100);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+/* resets TS Packet error count */
+/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
+static
+int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
+{
+       struct mxl111sf_reg_ctrl_info reset_per_count[] = {
+               {0x20, 0x01, 0x01},
+               {0x20, 0x01, 0x00},
+               {0,    0,    0}
+       };
+       return mxl111sf_demod_program_regs(state, reset_per_count);
+}
+#endif
+
+/* returns TS Packet error count */
+/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
+static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u32 fec_per_count, fec_per_scale;
+       u8 val;
+       int ret;
+
+       *ucblocks = 0;
+
+       /* FEC_PER_COUNT Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       fec_per_count = val;
+
+       /* FEC_PER_SCALE Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       val &= V6_FEC_PER_SCALE_MASK;
+       val *= 4;
+
+       fec_per_scale = 1 << val;
+
+       fec_per_count *= fec_per_scale;
+
+       *ucblocks = fec_per_count;
+fail:
+       return ret;
+}
+
+#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
+/* FIXME: leaving this enabled breaks the build on some architectures,
+ * and we shouldn't have any floating point math in the kernel, anyway.
+ *
+ * These macros need to be re-written, but it's harmless to simply
+ * return zero for now. */
+#define CALCULATE_BER(avg_errors, count) \
+       ((u32)(avg_errors * 4)/(count*64*188*8))
+#define CALCULATE_SNR(data) \
+       ((u32)((10 * (u32)data / 64) - 2.5))
+#else
+#define CALCULATE_BER(avg_errors, count) 0
+#define CALCULATE_SNR(data) 0
+#endif
+
+static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u8 val1, val2, val3;
+       int ret;
+
+       *ber = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
+                                  u16 *snr)
+{
+       u8 val1, val2;
+       int ret;
+
+       *snr = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       int ret = mxl111sf_demod_calc_snr(state, snr);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr /= 10; /* 0.1 dB */
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
+                                     fe_status_t *status)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret, locked, cr_lock, sync_lock, fec_lock;
+
+       *status = 0;
+
+       ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (locked)
+               *status |= FE_HAS_SIGNAL;
+       if (cr_lock)
+               *status |= FE_HAS_CARRIER;
+       if (sync_lock)
+               *status |= FE_HAS_SYNC;
+       if (fec_lock) /* false positives? */
+               *status |= FE_HAS_VITERBI;
+
+       if ((locked) && (cr_lock) && (sync_lock))
+               *status |= FE_HAS_LOCK;
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
+                                              u16 *signal_strength)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       fe_modulation_t modulation;
+       u16 snr;
+
+       mxl111sf_demod_calc_snr(state, &snr);
+       mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+
+       switch (modulation) {
+       case QPSK:
+               *signal_strength = (snr >= 1300) ?
+                       min(65535, snr * 44) : snr * 38;
+               break;
+       case QAM_16:
+               *signal_strength = (snr >= 1500) ?
+                       min(65535, snr * 38) : snr * 33;
+               break;
+       case QAM_64:
+               *signal_strength = (snr >= 2000) ?
+                       min(65535, snr * 29) : snr * 25;
+               break;
+       default:
+               *signal_strength = 0;
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       mxl_dbg("()");
+#if 0
+       p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
+#endif
+       if (fe->ops.tuner_ops.get_bandwidth)
+               fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz);
+       if (fe->ops.tuner_ops.get_frequency)
+               fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP);
+       mxl1x1sf_demod_get_tps_modulation(state, &p->modulation);
+       mxl1x1sf_demod_get_tps_guard_fft_mode(state,
+                                             &p->transmission_mode);
+       mxl1x1sf_demod_get_tps_guard_interval(state,
+                                             &p->guard_interval);
+       mxl1x1sf_demod_get_tps_hierarchy(state,
+                                        &p->hierarchy);
+
+       return 0;
+}
+
+static
+int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void mxl111sf_demod_release(struct dvb_frontend *fe)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       mxl_dbg("()");
+       kfree(state);
+       fe->demodulator_priv = NULL;
+}
+
+static struct dvb_frontend_ops mxl111sf_demod_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name               = "MaxLinear MxL111SF DVB-T demodulator",
+               .frequency_min      = 177000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+       },
+       .release              = mxl111sf_demod_release,
+#if 0
+       .init                 = mxl111sf_init,
+       .i2c_gate_ctrl        = mxl111sf_i2c_gate_ctrl,
+#endif
+       .set_frontend         = mxl111sf_demod_set_frontend,
+       .get_frontend         = mxl111sf_demod_get_frontend,
+       .get_tune_settings    = mxl111sf_demod_get_tune_settings,
+       .read_status          = mxl111sf_demod_read_status,
+       .read_signal_strength = mxl111sf_demod_read_signal_strength,
+       .read_ber             = mxl111sf_demod_read_ber,
+       .read_snr             = mxl111sf_demod_read_snr,
+       .read_ucblocks        = mxl111sf_demod_read_ucblocks,
+};
+
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       struct mxl111sf_demod_state *state = NULL;
+
+       mxl_dbg("()");
+
+       state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->mxl_state = mxl_state;
+       state->cfg = cfg;
+
+       memcpy(&state->fe.ops, &mxl111sf_demod_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->fe.demodulator_priv = state;
+       return &state->fe;
+}
+EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
+
+MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
new file mode 100644 (file)
index 0000000..432706a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 __MXL111SF_DEMOD_H__
+#define __MXL111SF_DEMOD_H__
+
+#include "dvb_frontend.h"
+#include "mxl111sf.h"
+
+struct mxl111sf_demod_config {
+       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
+       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
+       int (*program_regs)(struct mxl111sf_state *state,
+                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+};
+
+#if defined(CONFIG_DVB_USB_MXL111SF) || \
+       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg);
+#else
+static inline
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_USB_MXL111SF */
+
+#endif /* __MXL111SF_DEMOD_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
new file mode 100644 (file)
index 0000000..e4121cb
--- /dev/null
@@ -0,0 +1,763 @@
+/*
+ *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-gpio.h"
+#include "mxl111sf-i2c.h"
+#include "mxl111sf.h"
+
+/* ------------------------------------------------------------------------- */
+
+#define MXL_GPIO_MUX_REG_0 0x84
+#define MXL_GPIO_MUX_REG_1 0x89
+#define MXL_GPIO_MUX_REG_2 0x82
+
+#define MXL_GPIO_DIR_INPUT  0
+#define MXL_GPIO_DIR_OUTPUT 1
+
+
+static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug_adv("(%d, %d)", pin, val);
+
+       if ((pin > 0) && (pin < 8)) {
+               ret = mxl111sf_read_reg(state, 0x19, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (pin - 1));
+               tmp |= (val << (pin - 1));
+               ret = mxl111sf_write_reg(state, 0x19, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+       } else if (pin <= 10) {
+               if (pin == 0)
+                       pin += 7;
+               ret = mxl111sf_read_reg(state, 0x30, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (pin - 3));
+               tmp |= (val << (pin - 3));
+               ret = mxl111sf_write_reg(state, 0x30, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+       } else
+               ret = -EINVAL;
+fail:
+       return ret;
+}
+
+static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug("(0x%02x)", pin);
+
+       *val = 0;
+
+       switch (pin) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+               ret = mxl111sf_read_reg(state, 0x23, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> (pin + 4)) & 0x01;
+               break;
+       case 4:
+       case 5:
+       case 6:
+       case 7:
+               ret = mxl111sf_read_reg(state, 0x2f, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> pin) & 0x01;
+               break;
+       case 8:
+       case 9:
+       case 10:
+               ret = mxl111sf_read_reg(state, 0x22, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> (pin - 3)) & 0x01;
+               break;
+       default:
+               return -EINVAL; /* invalid pin */
+       }
+fail:
+       return ret;
+}
+
+struct mxl_gpio_cfg {
+       u8 pin;
+       u8 dir;
+       u8 val;
+};
+
+static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
+                                    struct mxl_gpio_cfg *gpio_cfg)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
+
+       switch (gpio_cfg->pin) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (gpio_cfg->pin + 4));
+               tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       case 4:
+       case 5:
+       case 6:
+       case 7:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << gpio_cfg->pin);
+               tmp |= (gpio_cfg->dir << gpio_cfg->pin);
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       case 8:
+       case 9:
+       case 10:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (gpio_cfg->pin - 3));
+               tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       default:
+               return -EINVAL; /* invalid pin */
+       }
+
+       ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
+               mxl111sf_set_gpo_state(state,
+                                      gpio_cfg->pin, gpio_cfg->val) :
+               mxl111sf_get_gpi_state(state,
+                                      gpio_cfg->pin, &gpio_cfg->val);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
+                                  int gpio, int direction, int val)
+{
+       struct mxl_gpio_cfg gpio_config = {
+               .pin = gpio,
+               .dir = direction,
+               .val = val,
+       };
+
+       mxl_debug("(%d, %d, %d)", gpio, direction, val);
+
+       return mxl111sf_config_gpio_pins(state, &gpio_config);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
+#define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
+#define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
+#define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
+#define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
+#define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
+#define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
+#define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
+#define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
+#define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
+#define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
+#define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
+#define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
+#define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
+#define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
+#define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
+#define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
+#define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
+#define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
+
+int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
+                                 enum mxl111sf_mux_config pin_mux_config)
+{
+       u8 r12, r15, r17, r18, r3D, r82, r84, r89;
+       int ret;
+
+       mxl_debug("(%d)", pin_mux_config);
+
+       ret = mxl111sf_read_reg(state, 0x17, &r17);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x18, &r18);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x12, &r12);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x15, &r15);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x82, &r82);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x84, &r84);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x89, &r89);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x3D, &r3D);
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (pin_mux_config) {
+       case PIN_MUX_TS_OUT_PARALLEL:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 1 */
+               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 1 */
+               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 1 */
+               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0xF */
+               r84 |= 0xF0;
+               /* mdat_en_ctrl[7:4] = 0xF */
+               r89 |= 0xF0;
+               break;
+       case PIN_MUX_TS_OUT_SERIAL:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 1 */
+               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 1 */
+               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0xF */
+               r84 |= 0xF0;
+               /* mdat_en_ctrl[7:4] = 0xF */
+               r89 |= 0xF0;
+               break;
+       case PIN_MUX_GPIO_MODE:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SERIAL_IN_MODE_0:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SERIAL_IN_MODE_1:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 1 */
+               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SPI_IN_MODE_1:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 1 */
+               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 1 */
+               r3D |= PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SPI_IN_MODE_0:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 1 */
+               r3D |= PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_PARALLEL_IN:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 1 */
+               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_BT656_I2S_MODE:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 1 */
+               r12 |= PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_DEFAULT:
+       default:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       }
+
+       ret = mxl111sf_write_reg(state, 0x17, r17);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x18, r18);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x12, r12);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x15, r15);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x82, r82);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x84, r84);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x89, r89);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x3D, r3D);
+       if (mxl_fail(ret))
+               goto fail;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
+}
+
+static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
+{
+       u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
+       int i, ret;
+
+       mxl_debug("()");
+
+       for (i = 3; i < 8; i++) {
+               ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
+               if (mxl_fail(ret))
+                       break;
+       }
+
+       return ret;
+}
+
+#define PCA9534_I2C_ADDR (0x40 >> 1)
+static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       u8 w[2] = { 1, 0 };
+       u8 r = 0;
+       struct i2c_msg msg[] = {
+               { .addr = PCA9534_I2C_ADDR,
+                 .flags = 0, .buf = w, .len = 1 },
+               { .addr = PCA9534_I2C_ADDR,
+                 .flags = I2C_M_RD, .buf = &r, .len = 1 },
+       };
+
+       mxl_debug("(%d, %d)", gpio, val);
+
+       /* read current GPIO levels from flip-flop */
+       i2c_transfer(&state->d->i2c_adap, msg, 2);
+
+       /* prepare write buffer with current GPIO levels */
+       msg[0].len = 2;
+#if 0
+       w[0] = 1;
+#endif
+       w[1] = r;
+
+       /* clear the desired GPIO */
+       w[1] &= ~(1 << gpio);
+
+       /* set the desired GPIO value */
+       w[1] |= ((val ? 1 : 0) << gpio);
+
+       /* write new GPIO levels to flip-flop */
+       i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
+
+       return 0;
+}
+
+static int pca9534_init_port_expander(struct mxl111sf_state *state)
+{
+       u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
+
+       struct i2c_msg msg = {
+               .addr = PCA9534_I2C_ADDR,
+               .flags = 0, .buf = w, .len = 2
+       };
+
+       mxl_debug("()");
+
+       i2c_transfer(&state->d->i2c_adap, &msg, 1);
+
+       /* configure all pins as outputs */
+       w[0] = 3;
+       w[1] = 0;
+
+       i2c_transfer(&state->d->i2c_adap, &msg, 1);
+
+       return 0;
+}
+
+int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       mxl_debug("(%d, %d)", gpio, val);
+
+       switch (state->gpio_port_expander) {
+       default:
+               mxl_printk(KERN_ERR,
+                          "gpio_port_expander undefined, assuming PCA9534");
+               /* fall-thru */
+       case mxl111sf_PCA9534:
+               return pca9534_set_gpio(state, gpio, val);
+       case mxl111sf_gpio_hw:
+               return mxl111sf_hw_set_gpio(state, gpio, val);
+       }
+}
+
+static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 w = 1;
+       u8 r = 0;
+       struct i2c_msg msg[] = {
+               { .flags = 0,        .buf = &w, .len = 1 },
+               { .flags = I2C_M_RD, .buf = &r, .len = 1 },
+       };
+
+       mxl_debug("()");
+
+       msg[0].addr = 0x70 >> 1;
+       msg[1].addr = 0x70 >> 1;
+
+       /* read current GPIO levels from flip-flop */
+       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
+       if (ret == 2) {
+               state->port_expander_addr = msg[0].addr;
+               state->gpio_port_expander = mxl111sf_PCA9534;
+               mxl_debug("found port expander at 0x%02x",
+                         state->port_expander_addr);
+               return 0;
+       }
+
+       msg[0].addr = 0x40 >> 1;
+       msg[1].addr = 0x40 >> 1;
+
+       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
+       if (ret == 2) {
+               state->port_expander_addr = msg[0].addr;
+               state->gpio_port_expander = mxl111sf_PCA9534;
+               mxl_debug("found port expander at 0x%02x",
+                         state->port_expander_addr);
+               return 0;
+       }
+       state->port_expander_addr = 0xff;
+       state->gpio_port_expander = mxl111sf_gpio_hw;
+       mxl_debug("using hardware gpio");
+       return 0;
+}
+
+int mxl111sf_init_port_expander(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       if (0x00 == state->port_expander_addr)
+               mxl111sf_probe_port_expander(state);
+
+       switch (state->gpio_port_expander) {
+       default:
+               mxl_printk(KERN_ERR,
+                          "gpio_port_expander undefined, assuming PCA9534");
+               /* fall-thru */
+       case mxl111sf_PCA9534:
+               return pca9534_init_port_expander(state);
+       case mxl111sf_gpio_hw:
+               return mxl111sf_hw_gpio_initialize(state);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
+{
+/*     GPO:
+ *     3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
+ *     4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
+ *     5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
+ *     6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
+ *     7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
+ */
+       mxl_debug("(%d)", mode);
+
+       switch (mode) {
+       case MXL111SF_GPIO_MOD_MH:
+               mxl111sf_set_gpio(state, 4, 0);
+               mxl111sf_set_gpio(state, 5, 0);
+               msleep(50);
+               mxl111sf_set_gpio(state, 7, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 6, 1);
+               msleep(50);
+
+               mxl111sf_set_gpio(state, 3, 0);
+               break;
+       case MXL111SF_GPIO_MOD_ATSC:
+               mxl111sf_set_gpio(state, 6, 0);
+               mxl111sf_set_gpio(state, 7, 0);
+               msleep(50);
+               mxl111sf_set_gpio(state, 5, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 4, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 3, 1);
+               break;
+       default: /* DVBT / STANDBY */
+               mxl111sf_init_port_expander(state);
+               break;
+       }
+       return 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
new file mode 100644 (file)
index 0000000..0220f54
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  mxl111sf-gpio.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_GPIO_H_
+#define _DVB_USB_MXL111SF_GPIO_H_
+
+#include "mxl111sf.h"
+
+int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val);
+int mxl111sf_init_port_expander(struct mxl111sf_state *state);
+
+#define MXL111SF_GPIO_MOD_DVBT 0
+#define MXL111SF_GPIO_MOD_MH   1
+#define MXL111SF_GPIO_MOD_ATSC 2
+int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode);
+
+enum mxl111sf_mux_config {
+       PIN_MUX_DEFAULT = 0,
+       PIN_MUX_TS_OUT_PARALLEL,
+       PIN_MUX_TS_OUT_SERIAL,
+       PIN_MUX_GPIO_MODE,
+       PIN_MUX_TS_SERIAL_IN_MODE_0,
+       PIN_MUX_TS_SERIAL_IN_MODE_1,
+       PIN_MUX_TS_SPI_IN_MODE_0,
+       PIN_MUX_TS_SPI_IN_MODE_1,
+       PIN_MUX_TS_PARALLEL_IN,
+       PIN_MUX_BT656_I2S_MODE,
+};
+
+int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
+                                 enum mxl111sf_mux_config pin_mux_config);
+
+#endif /* _DVB_USB_MXL111SF_GPIO_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
new file mode 100644 (file)
index 0000000..3443455
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+ *  mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-i2c.h"
+#include "mxl111sf.h"
+
+/* SW-I2C ----------------------------------------------------------------- */
+
+#define SW_I2C_ADDR            0x1a
+#define SW_I2C_EN              0x02
+#define SW_SCL_OUT             0x04
+#define SW_SDA_OUT             0x08
+#define SW_SDA_IN              0x04
+
+#define SW_I2C_BUSY_ADDR       0x2f
+#define SW_I2C_BUSY            0x02
+
+static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
+                                        u8 byte)
+{
+       int i, ret;
+       u8 data = 0;
+
+       mxl_i2c("(0x%02x)", byte);
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       for (i = 0; i < 8; i++) {
+
+               data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data | SW_SCL_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+
+       /* last bit was 0 so we need to release SDA */
+       if (!(byte & 1)) {
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+
+       /* CLK high for ACK readback */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* drop the CLK after getting ACK, SDA will go high right away */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (data & SW_SDA_IN)
+               ret = -EIO;
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
+                                        u8 *pbyte)
+{
+       int i, ret;
+       u8 byte = 0;
+       u8 data = 0;
+
+       mxl_i2c("()");
+
+       *pbyte = 0;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       for (i = 0; i < 8; i++) {
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN |
+                                        SW_SCL_OUT | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               if (data & SW_SDA_IN)
+                       byte |= (0x80 >> i);
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+       *pbyte = byte;
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_start(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN); /* start */
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN); /* stop */
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_SCL_OUT | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 b = 0;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* pull SDA low */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       /* SDA high to signal last byte read from slave */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
+                                   struct i2c_msg *msg)
+{
+       int i, ret;
+
+       mxl_i2c("()");
+
+       if (msg->flags & I2C_M_RD) {
+
+               ret = mxl111sf_i2c_start(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                   (msg->addr << 1) | 0x01);
+               if (mxl_fail(ret)) {
+                       mxl111sf_i2c_stop(state);
+                       goto fail;
+               }
+
+               for (i = 0; i < msg->len; i++) {
+                       ret = mxl111sf_i2c_bitbang_recvbyte(state,
+                                                           &msg->buf[i]);
+                       if (mxl_fail(ret)) {
+                               mxl111sf_i2c_stop(state);
+                               goto fail;
+                       }
+
+                       if (i < msg->len - 1)
+                               mxl111sf_i2c_ack(state);
+               }
+
+               mxl111sf_i2c_nack(state);
+
+               ret = mxl111sf_i2c_stop(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+       } else {
+
+               ret = mxl111sf_i2c_start(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                   (msg->addr << 1) & 0xfe);
+               if (mxl_fail(ret)) {
+                       mxl111sf_i2c_stop(state);
+                       goto fail;
+               }
+
+               for (i = 0; i < msg->len; i++) {
+                       ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                           msg->buf[i]);
+                       if (mxl_fail(ret)) {
+                               mxl111sf_i2c_stop(state);
+                               goto fail;
+                       }
+               }
+
+               /* FIXME: we only want to do this on the last transaction */
+               mxl111sf_i2c_stop(state);
+       }
+fail:
+       return ret;
+}
+
+/* HW-I2C ----------------------------------------------------------------- */
+
+#define USB_WRITE_I2C_CMD     0x99
+#define USB_READ_I2C_CMD      0xdd
+#define USB_END_I2C_CMD       0xfe
+
+#define USB_WRITE_I2C_CMD_LEN   26
+#define USB_READ_I2C_CMD_LEN    24
+
+#define I2C_MUX_REG           0x30
+#define I2C_CONTROL_REG       0x00
+#define I2C_SLAVE_ADDR_REG    0x08
+#define I2C_DATA_REG          0x0c
+#define I2C_INT_STATUS_REG    0x10
+
+static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
+                                 u8 index, u8 *wdata)
+{
+       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+                                   &wdata[1], 25, NULL, 0);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
+                                u8 index, u8 *wdata, u8 *rdata)
+{
+       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+                                   &wdata[1], 25, rdata, 24);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
+{
+       u8 status = 0;
+       u8 buf[26];
+
+       mxl_i2c_adv("()");
+
+       buf[0] = USB_READ_I2C_CMD;
+       buf[1] = 0x00;
+
+       buf[2] = I2C_INT_STATUS_REG;
+       buf[3] = 0x00;
+       buf[4] = 0x00;
+
+       buf[5] = USB_END_I2C_CMD;
+
+       mxl111sf_i2c_get_data(state, 0, buf, buf);
+
+       if (buf[1] & 0x04)
+               status = 1;
+
+       return status;
+}
+
+static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
+{
+       u8 status = 0;
+       u8 buf[26];
+
+       mxl_i2c("()");
+
+       buf[0] = USB_READ_I2C_CMD;
+       buf[1] = 0x00;
+
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x00;
+       buf[4] = 0x00;
+
+       buf[5] = I2C_INT_STATUS_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+       buf[8] = USB_END_I2C_CMD;
+
+       mxl111sf_i2c_get_data(state, 0, buf, buf);
+
+       if (0x08 == (buf[1] & 0x08))
+               status = 1;
+
+       if ((buf[5] & 0x02) == 0x02)
+               mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
+
+       return status;
+}
+
+static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
+                                 u8 count, u8 *rbuf)
+{
+       u8 i2c_w_data[26];
+       u8 i2c_r_data[24];
+       u8 i = 0;
+       u8 fifo_status = 0;
+       int status = 0;
+
+       mxl_i2c("read %d bytes", count);
+
+       while ((fifo_status == 0) && (i++ < 5))
+               fifo_status = mxl111sf_i2c_check_fifo(state);
+
+       i2c_w_data[0] = 0xDD;
+       i2c_w_data[1] = 0x00;
+
+       for (i = 2; i < 26; i++)
+               i2c_w_data[i] = 0xFE;
+
+       for (i = 0; i < count; i++) {
+               i2c_w_data[2+(i*3)] = 0x0C;
+               i2c_w_data[3+(i*3)] = 0x00;
+               i2c_w_data[4+(i*3)] = 0x00;
+       }
+
+       mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
+
+       /* Check for I2C NACK status */
+       if (mxl111sf_i2c_check_status(state) == 1) {
+               mxl_i2c("error!");
+       } else {
+               for (i = 0; i < count; i++) {
+                       rbuf[i] = i2c_r_data[(i*3)+1];
+                       mxl_i2c("%02x\t %02x",
+                               i2c_r_data[(i*3)+1],
+                               i2c_r_data[(i*3)+2]);
+               }
+
+               status = 1;
+       }
+
+       return status;
+}
+
+#define HWI2C400 1
+static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
+                                   struct i2c_msg *msg)
+{
+       int i, k, ret = 0;
+       u16 index = 0;
+       u8 buf[26];
+       u8 i2c_r_data[24];
+       u16 block_len;
+       u16 left_over_len;
+       u8 rd_status[8];
+       u8 ret_status;
+       u8 readbuff[26];
+
+       mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
+               msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
+               (!(msg->flags & I2C_M_RD)) ? msg->len : 0);
+
+       for (index = 0; index < 26; index++)
+               buf[index] = USB_END_I2C_CMD;
+
+       /* command to indicate data payload is destined for I2C interface */
+       buf[0] = USB_WRITE_I2C_CMD;
+       buf[1] = 0x00;
+
+       /* enable I2C interface */
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x80;
+       buf[4] = 0x00;
+
+       /* enable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x81;
+       buf[7] = 0x00;
+
+       /* set Timeout register on I2C interface */
+       buf[8] = 0x14;
+       buf[9] = 0xff;
+       buf[10] = 0x00;
+#if 0
+       /* enable Interrupts on I2C interface */
+       buf[8] = 0x24;
+       buf[9] = 0xF7;
+       buf[10] = 0x00;
+#endif
+       buf[11] = 0x24;
+       buf[12] = 0xF7;
+       buf[13] = 0x00;
+
+       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* write data on I2C bus */
+       if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
+               mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
+
+               /* control register on I2C interface to initialize I2C bus */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x5E;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               /* I2C Slave device Address */
+               buf[5] = I2C_SLAVE_ADDR_REG;
+               buf[6] = (msg->addr);
+               buf[7] = 0x00;
+               buf[8] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* check for slave device status */
+               if (mxl111sf_i2c_check_status(state) == 1) {
+                       mxl_i2c("NACK writing slave address %02x",
+                               msg->addr);
+                       /* if NACK, stop I2C bus and exit */
+                       buf[2] = I2C_CONTROL_REG;
+                       buf[3] = 0x4E;
+                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                       ret = -EIO;
+                       goto exit;
+               }
+
+               /* I2C interface can do I2C operations in block of 8 bytes of
+                  I2C data. calculation to figure out number of blocks of i2c
+                  data required to program */
+               block_len = (msg->len / 8);
+               left_over_len = (msg->len % 8);
+               index = 0;
+
+               mxl_i2c("block_len %d, left_over_len %d",
+                       block_len, left_over_len);
+
+               for (index = 0; index < block_len; index++) {
+                       for (i = 0; i < 8; i++) {
+                               /* write data on I2C interface */
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = msg->buf[(index*8)+i];
+                               buf[4+(i*3)] = 0x00;
+                       }
+
+                       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK writing slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0x4E;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+               }
+
+               if (left_over_len) {
+                       for (k = 0; k < 26; k++)
+                               buf[k] = USB_END_I2C_CMD;
+
+                       buf[0] = 0x99;
+                       buf[1] = 0x00;
+
+                       for (i = 0; i < left_over_len; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = msg->buf[(index*8)+i];
+                               mxl_i2c("index = %d %d data %d",
+                                       index, i, msg->buf[(index*8)+i]);
+                               buf[4+(i*3)] = 0x00;
+                       }
+                       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK writing slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0x4E;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+               }
+
+               /* issue I2C STOP after write */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x4E;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+       }
+
+       /* read data from I2C bus */
+       if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
+               mxl_i2c("read buf len %d", msg->len);
+
+               /* command to indicate data payload is
+                  destined for I2C interface */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0xDF;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               /* I2C xfer length */
+               buf[5] = 0x14;
+               buf[6] = (msg->len & 0xFF);
+               buf[7] = 0;
+
+               /* I2C slave device Address */
+               buf[8] = I2C_SLAVE_ADDR_REG;
+               buf[9] = msg->addr;
+               buf[10] = 0x00;
+               buf[11] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* check for I2C NACK status */
+               if (mxl111sf_i2c_check_status(state) == 1) {
+                       mxl_i2c("NACK reading slave address %02x",
+                               msg->addr);
+
+                       /* if NACK, stop I2C bus and exit */
+                       buf[2] = I2C_CONTROL_REG;
+                       buf[3] = 0xC7;
+                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                       ret = -EIO;
+                       goto exit;
+               }
+
+               /* I2C interface can do I2C operations in block of 8 bytes of
+                  I2C data. calculation to figure out number of blocks of
+                  i2c data required to program */
+               block_len = ((msg->len) / 8);
+               left_over_len = ((msg->len) % 8);
+               index = 0;
+
+               mxl_i2c("block_len %d, left_over_len %d",
+                       block_len, left_over_len);
+
+               /* command to read data from I2C interface */
+               buf[0] = USB_READ_I2C_CMD;
+               buf[1] = 0x00;
+
+               for (index = 0; index < block_len; index++) {
+                       /* setup I2C read request packet on I2C interface */
+                       for (i = 0; i < 8; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = 0x00;
+                               buf[4+(i*3)] = 0x00;
+                       }
+
+                       ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK reading slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0xC7;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+                       /* copy data from i2c data payload to read buffer */
+                       for (i = 0; i < 8; i++) {
+                               rd_status[i] = i2c_r_data[(i*3)+2];
+
+                               if (rd_status[i] == 0x04) {
+                                       if (i < 7) {
+                                               mxl_i2c("i2c fifo empty!"
+                                                       " @ %d", i);
+                                               msg->buf[(index*8)+i] =
+                                                       i2c_r_data[(i*3)+1];
+                                               /* read again */
+                                               ret_status =
+                                                       mxl111sf_i2c_readagain(
+                                                               state, 8-(i+1),
+                                                               readbuff);
+                                               if (ret_status == 1) {
+                                                       for (k = 0;
+                                                            k < 8-(i+1);
+                                                            k++) {
+
+                                       msg->buf[(index*8)+(k+i+1)] =
+                                               readbuff[k];
+                                       mxl_i2c("read data: %02x\t %02x",
+                                               msg->buf[(index*8)+(k+i)],
+                                               (index*8)+(k+i));
+                                       mxl_i2c("read data: %02x\t %02x",
+                                               msg->buf[(index*8)+(k+i+1)],
+                                               readbuff[k]);
+
+                                                       }
+                                                       goto stop_copy;
+                                               } else {
+                                                       mxl_i2c("readagain "
+                                                               "ERROR!");
+                                               }
+                                       } else {
+                                               msg->buf[(index*8)+i] =
+                                                       i2c_r_data[(i*3)+1];
+                                       }
+                               } else {
+                                       msg->buf[(index*8)+i] =
+                                               i2c_r_data[(i*3)+1];
+                               }
+                       }
+stop_copy:
+                       ;
+
+               }
+
+               if (left_over_len) {
+                       for (k = 0; k < 26; k++)
+                               buf[k] = USB_END_I2C_CMD;
+
+                       buf[0] = 0xDD;
+                       buf[1] = 0x00;
+
+                       for (i = 0; i < left_over_len; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = 0x00;
+                               buf[4+(i*3)] = 0x00;
+                       }
+                       ret = mxl111sf_i2c_get_data(state, 0, buf,
+                                                   i2c_r_data);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK reading slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0xC7;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+                       for (i = 0; i < left_over_len; i++) {
+                               msg->buf[(block_len*8)+i] =
+                                       i2c_r_data[(i*3)+1];
+                               mxl_i2c("read data: %02x\t %02x",
+                                       i2c_r_data[(i*3)+1],
+                                       i2c_r_data[(i*3)+2]);
+                       }
+               }
+
+               /* indicate I2C interface to issue NACK
+                  after next I2C read op */
+               buf[0] = USB_WRITE_I2C_CMD;
+               buf[1] = 0x00;
+
+               /* control register */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x17;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               buf[5] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* control register */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0xC7;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+       }
+exit:
+       /* STOP and disable I2C MUX */
+       buf[0] = USB_WRITE_I2C_CMD;
+       buf[1] = 0x00;
+
+       /* de-initilize I2C BUS */
+       buf[5] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* Control Register */
+       buf[2] = I2C_CONTROL_REG;
+       buf[3] = 0xDF;
+       buf[4] = 0x03;
+
+       /* disable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+
+       /* de-initilize I2C BUS */
+       buf[8] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* disable I2C interface */
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x81;
+       buf[4] = 0x00;
+
+       /* disable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+
+       /* disable I2C interface */
+       buf[8] = I2C_MUX_REG;
+       buf[9] = 0x00;
+       buf[10] = 0x00;
+
+       buf[11] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
+                     struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct mxl111sf_state *state = d->priv;
+       int hwi2c = (state->chip_rev > MXL111SF_V6);
+       int i, ret;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               ret = (hwi2c) ?
+                       mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
+                       mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
+               if (mxl_fail(ret)) {
+                       mxl_debug_adv("failed with error %d on i2c "
+                                     "transaction %d of %d, %sing %d bytes "
+                                     "to/from 0x%02x", ret, i+1, num,
+                                     (msg[i].flags & I2C_M_RD) ?
+                                     "read" : "writ",
+                                     msg[i].len, msg[i].addr);
+
+                       break;
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return i == num ? num : -EREMOTEIO;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
new file mode 100644 (file)
index 0000000..a57a45f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  mxl111sf-i2c.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_I2C_H_
+#define _DVB_USB_MXL111SF_I2C_H_
+
+#include <linux/i2c.h>
+
+int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
+                     struct i2c_msg msg[], int num);
+
+#endif /* _DVB_USB_MXL111SF_I2C_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
new file mode 100644 (file)
index 0000000..b741b3a
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ *  mxl111sf-phy.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-phy.h"
+#include "mxl111sf-reg.h"
+
+int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
+{
+       struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
+               {0x07, 0xff, 0x0c},
+               {0x58, 0xff, 0x9d},
+               {0x09, 0xff, 0x00},
+               {0x06, 0xff, 0x06},
+               {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
+               {0x8d, 0x01, 0x01}, /* NEGATE_Q */
+               {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
+               {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
+               {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
+               {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
+               {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
+               {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
+               {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
+               {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
+               {0x00, 0xff, 0x01}, /* Change to page 1 */
+               {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
+               {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
+               {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
+               {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
+               {0x00, 0xff, 0x00}, /* Change to page 0 */
+               {0,    0,    0}
+       };
+
+       mxl_debug("()");
+
+       return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
+}
+
+int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
+{
+       int ret;
+       mxl_debug("()");
+
+       ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
+{
+       int ret;
+
+       mxl_debug("(%s)", MXL_SOC_MODE == mode ?
+               "MXL_SOC_MODE" : "MXL_TUNER_MODE");
+
+       /* set device mode */
+       ret = mxl111sf_write_reg(state, 0x03,
+                                MXL_SOC_MODE == mode ? 0x01 : 0x00);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg_mask(state,
+                                     0x7d, 0x40, MXL_SOC_MODE == mode ?
+                                     0x00 : /* enable impulse noise filter,
+                                               INF_BYP = 0 */
+                                     0x40); /* disable impulse noise filter,
+                                               INF_BYP = 1 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->device_mode = mode;
+fail:
+       return ret;
+}
+
+/* power up tuner */
+int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
+{
+       mxl_debug("(%d)", onoff);
+
+       return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
+}
+
+int mxl111sf_disable_656_port(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
+}
+
+int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
+}
+
+/* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
+int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
+                           unsigned int parallel_serial,
+                           unsigned int msb_lsb_1st,
+                           unsigned int clock_phase,
+                           unsigned int mpeg_valid_pol,
+                           unsigned int mpeg_sync_pol)
+{
+       int ret;
+       u8 mode, tmp;
+
+       mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
+                 clock_phase, mpeg_valid_pol, mpeg_sync_pol);
+
+       /* Enable PIN MUX */
+       ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
+       mxl_fail(ret);
+
+       /* Configure MPEG Clock phase */
+       mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
+
+       if (clock_phase == TSIF_NORMAL)
+               mode &= ~V6_INVERTED_CLK_PHASE;
+       else
+               mode |= V6_INVERTED_CLK_PHASE;
+
+       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
+       mxl_fail(ret);
+
+       /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
+        * Get current configuration */
+       ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
+       mxl_fail(ret);
+
+       /* Data Input mode */
+       if (parallel_serial == TSIF_INPUT_PARALLEL) {
+               /* Disable serial mode */
+               mode &= ~V6_MPEG_IN_DATA_SERIAL;
+
+               /* Enable Parallel mode */
+               mode |= V6_MPEG_IN_DATA_PARALLEL;
+       } else {
+               /* Disable Parallel mode */
+               mode &= ~V6_MPEG_IN_DATA_PARALLEL;
+
+               /* Enable Serial Mode */
+               mode |= V6_MPEG_IN_DATA_SERIAL;
+
+               /* If serial interface is chosen, configure
+                  MSB or LSB order in transmission */
+               ret = mxl111sf_read_reg(state,
+                                       V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
+                                       &tmp);
+               mxl_fail(ret);
+
+               if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
+                       tmp |= V6_MPEG_SER_MSB_FIRST;
+               else
+                       tmp &= ~V6_MPEG_SER_MSB_FIRST;
+
+               ret = mxl111sf_write_reg(state,
+                                        V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
+                                        tmp);
+               mxl_fail(ret);
+       }
+
+       /* MPEG Sync polarity */
+       if (mpeg_sync_pol == TSIF_NORMAL)
+               mode &= ~V6_INVERTED_MPEG_SYNC;
+       else
+               mode |= V6_INVERTED_MPEG_SYNC;
+
+       /* MPEG Valid polarity */
+       if (mpeg_valid_pol == 0)
+               mode &= ~V6_INVERTED_MPEG_VALID;
+       else
+               mode |= V6_INVERTED_MPEG_VALID;
+
+       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
+{
+       static struct mxl111sf_reg_ctrl_info init_i2s[] = {
+               {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
+               {0x15, 0x60, 0x60}, /* Enable I2S */
+               {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
+                                      Inverted 656 Clock, I2S_SOFT_RESET,
+                                      0 : Normal operation, 1 : Reset State */
+#if 0
+               {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
+#endif
+               {0x00, 0xff, 0x02}, /* Change to Control Page */
+               {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
+               {0x00, 0xff, 0x00},
+               {0,    0,    0}
+       };
+       int ret;
+
+       mxl_debug("(0x%02x)", sample_size);
+
+       ret = mxl111sf_ctrl_program_regs(state, init_i2s);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
+{
+       static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
+               {0x15, 0x40, 0x00},
+               {0,    0,    0}
+       };
+
+       mxl_debug("()");
+
+       return mxl111sf_ctrl_program_regs(state, disable_i2s);
+}
+
+int mxl111sf_config_i2s(struct mxl111sf_state *state,
+                       u8 msb_start_pos, u8 data_width)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
+
+       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       tmp &= 0xe0;
+       tmp |= msb_start_pos;
+       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       tmp &= 0xe0;
+       tmp |= data_width;
+       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
+{
+       u8 val;
+       int ret;
+
+       mxl_debug("(%d)", onoff);
+
+       ret = mxl111sf_write_reg(state, 0x00, 0x02);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (onoff)
+               val |= 0x04;
+       else
+               val &= ~0x04;
+
+       ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, 0x00, 0x00);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_idac_config(struct mxl111sf_state *state,
+                        u8 control_mode, u8 current_setting,
+                        u8 current_value, u8 hysteresis_value)
+{
+       int ret;
+       u8 val;
+       /* current value will be set for both automatic & manual IDAC control */
+       val = current_value;
+
+       if (control_mode == IDAC_MANUAL_CONTROL) {
+               /* enable manual control of IDAC */
+               val |= IDAC_MANUAL_CONTROL_BIT_MASK;
+
+               if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
+                       /* enable current sinking in manual mode */
+                       val |= IDAC_CURRENT_SINKING_BIT_MASK;
+               else
+                       /* disable current sinking in manual mode */
+                       val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
+       } else {
+               /* disable manual control of IDAC */
+               val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
+
+               /* set hysteresis value  reg: 0x0B<5:0> */
+               ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
+                                        (hysteresis_value & 0x3F));
+               mxl_fail(ret);
+       }
+
+       ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
new file mode 100644 (file)
index 0000000..f075607
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  mxl111sf-phy.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_PHY_H_
+#define _DVB_USB_MXL111SF_PHY_H_
+
+#include "mxl111sf.h"
+
+int mxl1x1sf_soft_reset(struct mxl111sf_state *state);
+int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode);
+int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff);
+int mxl111sf_disable_656_port(struct mxl111sf_state *state);
+int mxl111sf_init_tuner_demod(struct mxl111sf_state *state);
+int mxl111sf_enable_usb_output(struct mxl111sf_state *state);
+int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
+                           unsigned int parallel_serial,
+                           unsigned int msb_lsb_1st,
+                           unsigned int clock_phase,
+                           unsigned int mpeg_valid_pol,
+                           unsigned int mpeg_sync_pol);
+int mxl111sf_config_i2s(struct mxl111sf_state *state,
+                       u8 msb_start_pos, u8 data_width);
+int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size);
+int mxl111sf_disable_i2s_port(struct mxl111sf_state *state);
+int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff);
+int mxl111sf_idac_config(struct mxl111sf_state *state,
+                        u8 control_mode, u8 current_setting,
+                        u8 current_value, u8 hysteresis_value);
+
+#endif /* _DVB_USB_MXL111SF_PHY_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
new file mode 100644 (file)
index 0000000..17831b0
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *  mxl111sf-reg.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 _DVB_USB_MXL111SF_REG_H_
+#define _DVB_USB_MXL111SF_REG_H_
+
+#define CHIP_ID_REG                  0xFC
+#define TOP_CHIP_REV_ID_REG          0xFA
+
+#define V6_SNR_RB_LSB_REG            0x27
+#define V6_SNR_RB_MSB_REG            0x28
+
+#define V6_N_ACCUMULATE_REG          0x11
+#define V6_RS_AVG_ERRORS_LSB_REG     0x2C
+#define V6_RS_AVG_ERRORS_MSB_REG     0x2D
+
+#define V6_IRQ_STATUS_REG            0x24
+#define  IRQ_MASK_FEC_LOCK       0x10
+
+#define V6_SYNC_LOCK_REG             0x28
+#define SYNC_LOCK_MASK           0x10
+
+#define V6_RS_LOCK_DET_REG           0x28
+#define  RS_LOCK_DET_MASK        0x08
+
+#define V6_INITACQ_NODETECT_REG    0x20
+#define V6_FORCE_NFFT_CPSIZE_REG   0x20
+
+#define V6_CODE_RATE_TPS_REG       0x29
+#define V6_CODE_RATE_TPS_MASK      0x07
+
+
+#define V6_CP_LOCK_DET_REG        0x28
+#define V6_CP_LOCK_DET_MASK       0x04
+
+#define V6_TPS_HIERACHY_REG        0x29
+#define V6_TPS_HIERARCHY_INFO_MASK  0x40
+
+#define V6_MODORDER_TPS_REG        0x2A
+#define V6_PARAM_CONSTELLATION_MASK   0x30
+
+#define V6_MODE_TPS_REG            0x2A
+#define V6_PARAM_FFT_MODE_MASK        0x0C
+
+
+#define V6_CP_TPS_REG             0x29
+#define V6_PARAM_GI_MASK              0x30
+
+#define V6_TPS_LOCK_REG           0x2A
+#define V6_PARAM_TPS_LOCK_MASK        0x40
+
+#define V6_FEC_PER_COUNT_REG      0x2E
+#define V6_FEC_PER_SCALE_REG      0x2B
+#define V6_FEC_PER_SCALE_MASK        0x03
+#define V6_FEC_PER_CLR_REG        0x20
+#define V6_FEC_PER_CLR_MASK          0x01
+
+#define V6_PIN_MUX_MODE_REG       0x1B
+#define V6_ENABLE_PIN_MUX            0x1E
+
+#define V6_I2S_NUM_SAMPLES_REG    0x16
+
+#define V6_MPEG_IN_CLK_INV_REG    0x17
+#define V6_MPEG_IN_CTRL_REG       0x18
+
+#define V6_INVERTED_CLK_PHASE       0x20
+#define V6_MPEG_IN_DATA_PARALLEL    0x01
+#define V6_MPEG_IN_DATA_SERIAL      0x02
+
+#define V6_INVERTED_MPEG_SYNC       0x04
+#define V6_INVERTED_MPEG_VALID      0x08
+
+#define TSIF_INPUT_PARALLEL         0
+#define TSIF_INPUT_SERIAL           1
+#define TSIF_NORMAL                 0
+
+#define V6_MPEG_INOUT_BIT_ORDER_CTRL_REG  0x19
+#define V6_MPEG_SER_MSB_FIRST                0x80
+#define MPEG_SER_MSB_FIRST_ENABLED        0x01
+
+#define V6_656_I2S_BUFF_STATUS_REG   0x2F
+#define V6_656_OVERFLOW_MASK_BIT         0x08
+#define V6_I2S_OVERFLOW_MASK_BIT         0x01
+
+#define V6_I2S_STREAM_START_BIT_REG  0x14
+#define V6_I2S_STREAM_END_BIT_REG    0x15
+#define I2S_RIGHT_JUSTIFIED     0
+#define I2S_LEFT_JUSTIFIED      1
+#define I2S_DATA_FORMAT         2
+
+#define V6_TUNER_LOOP_THRU_CONTROL_REG  0x09
+#define V6_ENABLE_LOOP_THRU               0x01
+
+#define TOTAL_NUM_IF_OUTPUT_FREQ       16
+
+#define TUNER_NORMAL_IF_SPECTRUM       0x0
+#define TUNER_INVERT_IF_SPECTRUM       0x10
+
+#define V6_TUNER_IF_SEL_REG              0x06
+#define V6_TUNER_IF_FCW_REG              0x3C
+#define V6_TUNER_IF_FCW_BYP_REG          0x3D
+#define V6_RF_LOCK_STATUS_REG            0x23
+
+#define NUM_DIG_TV_CHANNEL     1000
+
+#define V6_DIG_CLK_FREQ_SEL_REG  0x07
+#define V6_REF_SYNTH_INT_REG     0x5C
+#define V6_REF_SYNTH_REMAIN_REG  0x58
+#define V6_DIG_RFREFSELECT_REG   0x32
+#define V6_XTAL_CLK_OUT_GAIN_REG   0x31
+#define V6_TUNER_LOOP_THRU_CTRL_REG      0x09
+#define V6_DIG_XTAL_ENABLE_REG  0x06
+#define V6_DIG_XTAL_BIAS_REG  0x66
+#define V6_XTAL_CAP_REG    0x08
+
+#define V6_GPO_CTRL_REG     0x18
+#define MXL_GPO_0           0x00
+#define MXL_GPO_1           0x01
+#define V6_GPO_0_MASK       0x10
+#define V6_GPO_1_MASK       0x20
+
+#define V6_111SF_GPO_CTRL_REG     0x19
+#define MXL_111SF_GPO_1               0x00
+#define MXL_111SF_GPO_2               0x01
+#define MXL_111SF_GPO_3               0x02
+#define MXL_111SF_GPO_4               0x03
+#define MXL_111SF_GPO_5               0x04
+#define MXL_111SF_GPO_6               0x05
+#define MXL_111SF_GPO_7               0x06
+
+#define MXL_111SF_GPO_0_MASK          0x01
+#define MXL_111SF_GPO_1_MASK          0x02
+#define MXL_111SF_GPO_2_MASK          0x04
+#define MXL_111SF_GPO_3_MASK          0x08
+#define MXL_111SF_GPO_4_MASK          0x10
+#define MXL_111SF_GPO_5_MASK          0x20
+#define MXL_111SF_GPO_6_MASK          0x40
+
+#define V6_ATSC_CONFIG_REG  0x0A
+
+#define MXL_MODE_REG    0x03
+#define START_TUNE_REG  0x1C
+
+#define V6_IDAC_HYSTERESIS_REG    0x0B
+#define V6_IDAC_SETTINGS_REG      0x0C
+#define IDAC_MANUAL_CONTROL             1
+#define IDAC_CURRENT_SINKING_ENABLE     1
+#define IDAC_MANUAL_CONTROL_BIT_MASK      0x80
+#define IDAC_CURRENT_SINKING_BIT_MASK     0x40
+
+#define V8_SPI_MODE_REG  0xE9
+
+#define V6_DIG_RF_PWR_LSB_REG  0x46
+#define V6_DIG_RF_PWR_MSB_REG  0x47
+
+#endif /* _DVB_USB_MXL111SF_REG_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
new file mode 100644 (file)
index 0000000..ef4c65f
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ *  mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 "mxl111sf-tuner.h"
+#include "mxl111sf-phy.h"
+#include "mxl111sf-reg.h"
+
+/* debug */
+static int mxl111sf_tuner_debug;
+module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define mxl_dbg(fmt, arg...) \
+       if (mxl111sf_tuner_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define err pr_err
+
+/* ------------------------------------------------------------------------ */
+
+struct mxl111sf_tuner_state {
+       struct mxl111sf_state *mxl_state;
+
+       struct mxl111sf_tuner_config *cfg;
+
+       enum mxl_if_freq if_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
+                                  u8 addr, u8 *data)
+{
+       return (state->cfg->read_reg) ?
+               state->cfg->read_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
+                                   u8 addr, u8 data)
+{
+       return (state->cfg->write_reg) ?
+               state->cfg->write_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       return (state->cfg->program_regs) ?
+               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
+               -EINVAL;
+}
+
+static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
+                                         int onoff)
+{
+       return (state->cfg->top_master_ctrl) ?
+               state->cfg->top_master_ctrl(state->mxl_state, onoff) :
+               -EINVAL;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
+       {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
+                              DIG_MODEINDEX, _A, _CSF, */
+       {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
+       {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
+       {0,    0,    0}
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
+                                                                 u8 bw)
+{
+       u8 filt_bw;
+
+       /* set channel bandwidth */
+       switch (bw) {
+       case 0: /* ATSC */
+               filt_bw = 25;
+               break;
+       case 1: /* QAM */
+               filt_bw = 69;
+               break;
+       case 6:
+               filt_bw = 21;
+               break;
+       case 7:
+               filt_bw = 42;
+               break;
+       case 8:
+               filt_bw = 63;
+               break;
+       default:
+               err("%s: invalid bandwidth setting!", __func__);
+               return NULL;
+       }
+
+       /* calculate RF channel */
+       freq /= 1000000;
+
+       freq *= 64;
+#if 0
+       /* do round */
+       freq += 0.5;
+#endif
+       /* set bandwidth */
+       mxl_phy_tune_rf[0].data = filt_bw;
+
+       /* set RF */
+       mxl_phy_tune_rf[1].data = (freq & 0xff);
+       mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
+
+       /* start tune */
+       return mxl_phy_tune_rf;
+}
+
+static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
+{
+       int ret;
+       u8 ctrl;
+#if 0
+       u16 iffcw;
+       u32 if_freq;
+#endif
+       mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
+               state->cfg->invert_spectrum, state->cfg->if_freq);
+
+       /* set IF polarity */
+       ctrl = state->cfg->invert_spectrum;
+
+       ctrl |= state->cfg->if_freq;
+
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+#if 0
+       if_freq /= 1000000;
+
+       /* do round */
+       if_freq += 0.5;
+
+       if (MXL_IF_LO == state->cfg->if_freq) {
+               ctrl = 0x08;
+               iffcw = (u16)(if_freq / (108 * 4096));
+       } else if (MXL_IF_HI == state->cfg->if_freq) {
+               ctrl = 0x08;
+               iffcw = (u16)(if_freq / (216 * 4096));
+       } else {
+               ctrl = 0;
+               iffcw = 0;
+       }
+
+       ctrl |= (iffcw >> 8);
+#endif
+       ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ctrl &= 0xf0;
+       ctrl |= 0x90;
+
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+#if 0
+       ctrl = iffcw & 0x00ff;
+#endif
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->if_freq = state->cfg->if_freq;
+fail:
+       return ret;
+}
+
+static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
+       int ret;
+       u8 mxl_mode;
+
+       mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
+
+       /* stop tune */
+       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* check device mode */
+       ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* Fill out registers for channel tune */
+       reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
+       if (!reg_ctrl_array)
+               return -EINVAL;
+
+       ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
+               /* IF tuner mode only */
+               mxl1x1sf_tuner_top_master_ctrl(state, 0);
+               mxl1x1sf_tuner_top_master_ctrl(state, 1);
+               mxl1x1sf_tuner_set_if_output_freq(state);
+       }
+
+       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (state->cfg->ant_hunt)
+               state->cfg->ant_hunt(fe);
+fail:
+       return ret;
+}
+
+static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
+                                         int *rf_synth_lock,
+                                         int *ref_synth_lock)
+{
+       int ret;
+       u8 data;
+
+       *rf_synth_lock = 0;
+       *ref_synth_lock = 0;
+
+       ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
+       *rf_synth_lock  = ((data & 0x0c) == 0x0c) ? 1 : 0;
+fail:
+       return ret;
+}
+
+#if 0
+static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
+                                        int onoff)
+{
+       return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
+                                       onoff ? 1 : 0);
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys  = c->delivery_system;
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+       u8 bw;
+
+       mxl_dbg("()");
+
+       switch (delsys) {
+       case SYS_ATSC:
+       case SYS_ATSCMH:
+               bw = 0; /* ATSC */
+               break;
+       case SYS_DVBC_ANNEX_B:
+               bw = 1; /* US CABLE */
+               break;
+       case SYS_DVBT:
+               switch (c->bandwidth_hz) {
+               case 6000000:
+                       bw = 6;
+                       break;
+               case 7000000:
+                       bw = 7;
+                       break;
+               case 8000000:
+                       bw = 8;
+                       break;
+               default:
+                       err("%s: bandwidth not set!", __func__);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               err("%s: modulation type not supported!", __func__);
+               return -EINVAL;
+       }
+       ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->frequency = c->frequency;
+       state->bandwidth = c->bandwidth_hz;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+static int mxl111sf_tuner_init(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+
+       /* wake from standby handled by usb driver */
+
+       return ret;
+}
+
+static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+
+       /* enter standby mode handled by usb driver */
+
+       return ret;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int rf_locked, ref_locked, ret;
+
+       *status = 0;
+
+       ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
+       if (mxl_fail(ret))
+               goto fail;
+       mxl_info("%s%s", rf_locked ? "rf locked " : "",
+                ref_locked ? "ref locked" : "");
+
+       if ((rf_locked) || (ref_locked))
+               *status |= TUNER_STATUS_LOCKED;
+fail:
+       return ret;
+}
+
+static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       u8 val1, val2;
+       int ret;
+
+       *strength = 0;
+
+       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *strength = val1 | ((val2 & 0x07) << 8);
+fail:
+       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       *frequency = state->frequency;
+       return 0;
+}
+
+static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       *bandwidth = state->bandwidth;
+       return 0;
+}
+
+static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
+                                          u32 *frequency)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+
+       *frequency = 0;
+
+       switch (state->if_freq) {
+       case MXL_IF_4_0:   /* 4.0   MHz */
+               *frequency = 4000000;
+               break;
+       case MXL_IF_4_5:   /* 4.5   MHz */
+               *frequency = 4500000;
+               break;
+       case MXL_IF_4_57:  /* 4.57  MHz */
+               *frequency = 4570000;
+               break;
+       case MXL_IF_5_0:   /* 5.0   MHz */
+               *frequency = 5000000;
+               break;
+       case MXL_IF_5_38:  /* 5.38  MHz */
+               *frequency = 5380000;
+               break;
+       case MXL_IF_6_0:   /* 6.0   MHz */
+               *frequency = 6000000;
+               break;
+       case MXL_IF_6_28:  /* 6.28  MHz */
+               *frequency = 6280000;
+               break;
+       case MXL_IF_7_2:   /* 7.2   MHz */
+               *frequency = 7200000;
+               break;
+       case MXL_IF_35_25: /* 35.25 MHz */
+               *frequency = 35250000;
+               break;
+       case MXL_IF_36:    /* 36    MHz */
+               *frequency = 36000000;
+               break;
+       case MXL_IF_36_15: /* 36.15 MHz */
+               *frequency = 36150000;
+               break;
+       case MXL_IF_44:    /* 44    MHz */
+               *frequency = 44000000;
+               break;
+       }
+       return 0;
+}
+
+static int mxl111sf_tuner_release(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       mxl_dbg("()");
+       kfree(state);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
+       .info = {
+               .name = "MaxLinear MxL111SF",
+#if 0
+               .frequency_min  = ,
+               .frequency_max  = ,
+               .frequency_step = ,
+#endif
+       },
+#if 0
+       .init              = mxl111sf_tuner_init,
+       .sleep             = mxl111sf_tuner_sleep,
+#endif
+       .set_params        = mxl111sf_tuner_set_params,
+       .get_status        = mxl111sf_tuner_get_status,
+       .get_rf_strength   = mxl111sf_get_rf_strength,
+       .get_frequency     = mxl111sf_tuner_get_frequency,
+       .get_bandwidth     = mxl111sf_tuner_get_bandwidth,
+       .get_if_frequency  = mxl111sf_tuner_get_if_frequency,
+       .release           = mxl111sf_tuner_release,
+};
+
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_tuner_config *cfg)
+{
+       struct mxl111sf_tuner_state *state = NULL;
+
+       mxl_dbg("()");
+
+       state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->mxl_state = mxl_state;
+       state->cfg = cfg;
+
+       memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = state;
+       return fe;
+}
+EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
+
+MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
new file mode 100644 (file)
index 0000000..ff33396
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.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 __MXL111SF_TUNER_H__
+#define __MXL111SF_TUNER_H__
+
+#include "dvb_frontend.h"
+
+#include "mxl111sf.h"
+
+enum mxl_if_freq {
+#if 0
+       MXL_IF_LO    = 0x00, /* other IF < 9MHz */
+#endif
+       MXL_IF_4_0   = 0x01, /* 4.0   MHz */
+       MXL_IF_4_5   = 0x02, /* 4.5   MHz */
+       MXL_IF_4_57  = 0x03, /* 4.57  MHz */
+       MXL_IF_5_0   = 0x04, /* 5.0   MHz */
+       MXL_IF_5_38  = 0x05, /* 5.38  MHz */
+       MXL_IF_6_0   = 0x06, /* 6.0   MHz */
+       MXL_IF_6_28  = 0x07, /* 6.28  MHz */
+       MXL_IF_7_2   = 0x08, /* 7.2   MHz */
+       MXL_IF_35_25 = 0x09, /* 35.25 MHz */
+       MXL_IF_36    = 0x0a, /* 36    MHz */
+       MXL_IF_36_15 = 0x0b, /* 36.15 MHz */
+       MXL_IF_44    = 0x0c, /* 44    MHz */
+#if 0
+       MXL_IF_HI    = 0x0f, /* other IF > 35 MHz and < 45 MHz */
+#endif
+};
+
+struct mxl111sf_tuner_config {
+       enum mxl_if_freq if_freq;
+       unsigned int invert_spectrum:1;
+
+       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
+       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
+       int (*program_regs)(struct mxl111sf_state *state,
+                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+       int (*top_master_ctrl)(struct mxl111sf_state *state, int onoff);
+       int (*ant_hunt)(struct dvb_frontend *fe);
+};
+
+/* ------------------------------------------------------------------------ */
+
+#if defined(CONFIG_DVB_USB_MXL111SF) || \
+       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_tuner_config *cfg);
+#else
+static inline
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state
+                                          struct mxl111sf_tuner_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __MXL111SF_TUNER_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
new file mode 100644 (file)
index 0000000..efdcb15
--- /dev/null
@@ -0,0 +1,1431 @@
+/*
+ * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/i2c.h>
+
+#include "mxl111sf.h"
+#include "mxl111sf-reg.h"
+#include "mxl111sf-phy.h"
+#include "mxl111sf-i2c.h"
+#include "mxl111sf-gpio.h"
+
+#include "mxl111sf-demod.h"
+#include "mxl111sf-tuner.h"
+
+#include "lgdt3305.h"
+#include "lg2160.h"
+
+int dvb_usb_mxl111sf_debug;
+module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level "
+                "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
+
+int dvb_usb_mxl111sf_isoc;
+module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
+MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
+
+int dvb_usb_mxl111sf_spi;
+module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
+MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
+
+#define ANT_PATH_AUTO 0
+#define ANT_PATH_EXTERNAL 1
+#define ANT_PATH_INTERNAL 2
+
+int dvb_usb_mxl111sf_rfswitch =
+#if 0
+               ANT_PATH_AUTO;
+#else
+               ANT_PATH_EXTERNAL;
+#endif
+
+module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
+MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_info pr_debug
+#define deb_reg pr_debug
+#define deb_adv pr_debug
+#define err pr_err
+#define info pr_info
+
+int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       int wo = (rbuf == NULL || rlen == 0); /* write-only */
+       int ret;
+       u8 sndbuf[1+wlen];
+
+       deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+
+       memset(sndbuf, 0, 1+wlen);
+
+       sndbuf[0] = cmd;
+       memcpy(&sndbuf[1], wbuf, wlen);
+
+       ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
+               dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#define MXL_CMD_REG_READ       0xaa
+#define MXL_CMD_REG_WRITE      0x55
+
+int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
+{
+       u8 buf[2];
+       int ret;
+
+       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
+       if (mxl_fail(ret)) {
+               mxl_debug("error reading reg: 0x%02x", addr);
+               goto fail;
+       }
+
+       if (buf[0] == addr)
+               *data = buf[1];
+       else {
+               err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+                   addr, buf[0], buf[1]);
+               ret = -EINVAL;
+       }
+
+       deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+fail:
+       return ret;
+}
+
+int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
+{
+       u8 buf[] = { addr, data };
+       int ret;
+
+       deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+
+       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
+       if (mxl_fail(ret))
+               err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
+                                  u8 addr, u8 mask, u8 data)
+{
+       int ret;
+       u8 val;
+
+       if (mask != 0xff) {
+               ret = mxl111sf_read_reg(state, addr, &val);
+#if 1
+               /* dont know why this usually errors out on the first try */
+               if (mxl_fail(ret))
+                       err("error writing addr: 0x%02x, mask: 0x%02x, "
+                           "data: 0x%02x, retrying...", addr, mask, data);
+
+               ret = mxl111sf_read_reg(state, addr, &val);
+#endif
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+       val &= ~mask;
+       val |= data;
+
+       ret = mxl111sf_write_reg(state, addr, val);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       int i, ret = 0;
+
+       for (i = 0;  ctrl_reg_info[i].addr |
+                    ctrl_reg_info[i].mask |
+                    ctrl_reg_info[i].data;  i++) {
+
+               ret = mxl111sf_write_reg_mask(state,
+                                             ctrl_reg_info[i].addr,
+                                             ctrl_reg_info[i].mask,
+                                             ctrl_reg_info[i].data);
+               if (mxl_fail(ret)) {
+                       err("failed on reg #%d (0x%02x)", i,
+                           ctrl_reg_info[i].addr);
+                       break;
+               }
+       }
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 id, ver;
+       char *mxl_chip, *mxl_rev;
+
+       if ((state->chip_id) && (state->chip_ver))
+               return 0;
+
+       ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
+       if (mxl_fail(ret))
+               goto fail;
+       state->chip_id = id;
+
+       ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
+       if (mxl_fail(ret))
+               goto fail;
+       state->chip_ver = ver;
+
+       switch (id) {
+       case 0x61:
+               mxl_chip = "MxL101SF";
+               break;
+       case 0x63:
+               mxl_chip = "MxL111SF";
+               break;
+       default:
+               mxl_chip = "UNKNOWN MxL1X1";
+               break;
+       }
+       switch (ver) {
+       case 0x36:
+               state->chip_rev = MXL111SF_V6;
+               mxl_rev = "v6";
+               break;
+       case 0x08:
+               state->chip_rev = MXL111SF_V8_100;
+               mxl_rev = "v8_100";
+               break;
+       case 0x18:
+               state->chip_rev = MXL111SF_V8_200;
+               mxl_rev = "v8_200";
+               break;
+       default:
+               state->chip_rev = 0;
+               mxl_rev = "UNKNOWN REVISION";
+               break;
+       }
+       info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+fail:
+       return ret;
+}
+
+#define get_chip_info(state)                                           \
+({                                                                     \
+       int ___ret;                                                     \
+       ___ret = mxl1x1sf_get_chip_info(state);                         \
+       if (mxl_fail(___ret)) {                                         \
+               mxl_debug("failed to get chip info"                     \
+                         " on first probe attempt");                   \
+               ___ret = mxl1x1sf_get_chip_info(state);                 \
+               if (mxl_fail(___ret))                                   \
+                       err("failed to get chip info during probe");    \
+               else                                                    \
+                       mxl_debug("probe needed a retry "               \
+                                 "in order to succeed.");              \
+       }                                                               \
+       ___ret;                                                         \
+})
+
+/* ------------------------------------------------------------------------ */
+#if 0
+static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       /* power control depends on which adapter is being woken:
+        * save this for init, instead, via mxl111sf_adap_fe_init */
+       return 0;
+}
+#endif
+
+static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int err;
+
+       /* exit if we didnt initialize the driver yet */
+       if (!state->chip_id) {
+               mxl_debug("driver not yet initialized, exit.");
+               goto fail;
+       }
+
+       deb_info("%s()\n", __func__);
+
+       mutex_lock(&state->fe_lock);
+
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       err = mxl1x1sf_soft_reset(state);
+       mxl_fail(err);
+       err = mxl111sf_init_tuner_demod(state);
+       mxl_fail(err);
+       err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+
+       mxl_fail(err);
+       mxl111sf_enable_usb_output(state);
+       mxl_fail(err);
+       mxl1x1sf_top_master_ctrl(state, 1);
+       mxl_fail(err);
+
+       if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
+           (state->chip_rev > MXL111SF_V6)) {
+               mxl111sf_config_pin_mux_modes(state,
+                                             PIN_MUX_TS_SPI_IN_MODE_1);
+               mxl_fail(err);
+       }
+       err = mxl111sf_init_port_expander(state);
+       if (!mxl_fail(err)) {
+               state->gpio_mode = adap_state->gpio_mode;
+               err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+               mxl_fail(err);
+#if 0
+               err = fe->ops.init(fe);
+#endif
+               msleep(100); /* add short delay after enabling
+                             * the demod before touching it */
+       }
+
+       return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
+fail:
+       return -ENODEV;
+}
+
+static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int err;
+
+       /* exit if we didnt initialize the driver yet */
+       if (!state->chip_id) {
+               mxl_debug("driver not yet initialized, exit.");
+               goto fail;
+       }
+
+       deb_info("%s()\n", __func__);
+
+       err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
+
+       mutex_unlock(&state->fe_lock);
+
+       return err;
+fail:
+       return -ENODEV;
+}
+
+
+static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+               ret = mxl111sf_config_mpeg_in(state, 1, 1,
+                                             adap_state->ep6_clockphase,
+                                             0, 0);
+               mxl_fail(ret);
+#if 0
+       } else {
+               ret = mxl111sf_disable_656_port(state);
+               mxl_fail(ret);
+#endif
+       }
+
+       return ret;
+}
+
+static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+
+               ret = mxl111sf_init_i2s_port(state, 200);
+               mxl_fail(ret);
+               ret = mxl111sf_config_i2s(state, 0, 15);
+               mxl_fail(ret);
+       } else {
+               ret = mxl111sf_disable_i2s_port(state);
+               mxl_fail(ret);
+       }
+       if (state->chip_rev > MXL111SF_V6)
+               ret = mxl111sf_config_spi(state, onoff);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+       }
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct lgdt3305_config hauppauge_lgdt3305_config = {
+       .i2c_addr           = 0xb2 >> 1,
+       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
+       .tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
+       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .qam_if_khz         = 6000,
+       .vsb_if_khz         = 6000,
+};
+
+static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
+                                &hauppauge_lgdt3305_config,
+                                &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2160_config = {
+       .lg_chip            = LG2160,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+};
+
+static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             &hauppauge_lg2160_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_config = {
+       .lg_chip            = LG2161_1019,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 2, /* LG2161_OIF_SPI_MAS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_config = {
+       .lg_chip            = LG2161_1040,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 4, /* LG2161_OIF_SPI_MAS */
+};
+
+static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             (MXL111SF_V8_200 == state->chip_rev) ?
+                             &hauppauge_lg2161_1040_config :
+                             &hauppauge_lg2161_1019_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
+       .lg_chip            = LG2161_1019,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 1, /* LG2161_OIF_SERIAL_TS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
+       .lg_chip            = LG2161_1040,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 7, /* LG2161_OIF_SERIAL_TS */
+};
+
+static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 0;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             (MXL111SF_V8_200 == state->chip_rev) ?
+                             &hauppauge_lg2161_1040_ep6_config :
+                             &hauppauge_lg2161_1019_ep6_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct mxl111sf_demod_config mxl_demod_config = {
+       .read_reg        = mxl111sf_read_reg,
+       .write_reg       = mxl111sf_write_reg,
+       .program_regs    = mxl111sf_ctrl_program_regs,
+};
+
+static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_SOC_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* dont care if this fails */
+       mxl111sf_init_port_expander(state);
+
+       adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
+                             &mxl_demod_config);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
+                                       int antpath)
+{
+       return mxl111sf_idac_config(state, 1, 1,
+                                   (antpath == ANT_PATH_INTERNAL) ?
+                                   0x3f : 0x00, 0);
+}
+
+#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
+       err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+           __func__, __LINE__, \
+           (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
+           pwr0, pwr1, pwr2, pwr3)
+
+#define ANT_HUNT_SLEEP 90
+#define ANT_EXT_TWEAK 0
+
+static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int antctrl = dvb_usb_mxl111sf_rfswitch;
+
+       u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
+
+       /* FIXME: must force EXTERNAL for QAM - done elsewhere */
+       mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
+                             ANT_PATH_EXTERNAL : antctrl);
+
+       if (antctrl == ANT_PATH_AUTO) {
+#if 0
+               msleep(ANT_HUNT_SLEEP);
+#endif
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
+
+               if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
+                       /* return with EXTERNAL enabled */
+                       mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+                       DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
+                                  rxPwr0, rxPwr1, rxPwr2);
+               } else {
+                       /* return with INTERNAL enabled */
+                       DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
+                                  rxPwr0, rxPwr1, rxPwr2);
+               }
+       }
+       return 0;
+}
+
+static struct mxl111sf_tuner_config mxl_tuner_config = {
+       .if_freq         = MXL_IF_6_0, /* applies to external IF output, only */
+       .invert_spectrum = 0,
+       .read_reg        = mxl111sf_read_reg,
+       .write_reg       = mxl111sf_write_reg,
+       .program_regs    = mxl111sf_ctrl_program_regs,
+       .top_master_ctrl = mxl1x1sf_top_master_ctrl,
+       .ant_hunt        = mxl111sf_ant_hunt,
+};
+
+static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
+{
+       struct mxl111sf_state *state = adap_to_priv(adap);
+       int i;
+
+       deb_adv("%s()\n", __func__);
+
+       for (i = 0; i < state->num_frontends; i++) {
+               if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
+                               &mxl_tuner_config) == NULL)
+                       return -EIO;
+               adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;
+       }
+
+       return 0;
+}
+
+static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm mxl111sf_i2c_algo = {
+       .master_xfer   = mxl111sf_i2c_xfer,
+       .functionality = mxl111sf_i2c_func,
+#ifdef NEED_ALGO_CONTROL
+       .algo_control = dummy_algo_control,
+#endif
+};
+
+static int mxl111sf_init(struct dvb_usb_device *d)
+{
+       struct mxl111sf_state *state = d_to_priv(d);
+       int ret;
+       static u8 eeprom[256];
+       struct i2c_client c;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               err("failed to get chip info during probe");
+
+       mutex_init(&state->fe_lock);
+
+       if (state->chip_rev > MXL111SF_V6)
+               mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
+
+       c.adapter = &d->i2c_adap;
+       c.addr = 0xa0 >> 1;
+
+       ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
+       if (mxl_fail(ret))
+               return 0;
+       tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
+                       eeprom + 0xa0 : eeprom + 0x80);
+#if 0
+       switch (state->tv.model) {
+       case 117001:
+       case 126001:
+       case 138001:
+               break;
+       default:
+               printk(KERN_WARNING "%s: warning: "
+                      "unknown hauppauge model #%d\n",
+                      __func__, state->tv.model);
+       }
+#endif
+       return 0;
+}
+
+static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_attach_demod(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_lgdt3305_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_lg2160_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_attach_demod(adap, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_lg2160_frontend_attach(adap, 2);
+       if (ret < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_attach_demod(adap, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
+       if (ret < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_attach_demod(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       if (dvb_usb_mxl111sf_spi)
+               ret = mxl111sf_lg2161_frontend_attach(adap, 1);
+       else
+               ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
+
+       return ret;
+}
+
+static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
+{
+       deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+       stream->type = USB_BULK;
+       stream->count = 5;
+       stream->endpoint = endpoint;
+       stream->u.bulk.buffersize = 8192;
+}
+
+static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
+               u8 endpoint, int framesperurb, int framesize)
+{
+       deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+                       framesperurb * framesize);
+       stream->type = USB_ISOC;
+       stream->count = 5;
+       stream->endpoint = endpoint;
+       stream->u.isoc.framesperurb = framesperurb;
+       stream->u.isoc.framesize = framesize;
+       stream->u.isoc.interval = 1;
+}
+
+/* DVB USB Driver stuff */
+
+/* dvbt       mxl111sf
+ * bulk       EP4/BULK/5/8192
+ * isoc       EP4/ISOC/5/96/564
+ */
+static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_188;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+       else
+               mxl111sf_stream_config_bulk(stream, 4);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_dvbt,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep4_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_dvbt,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* atsc       lgdt3305
+ * bulk       EP6/BULK/5/8192
+ * isoc       EP6/ISOC/5/24/3072
+ */
+static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_188;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+       else
+               mxl111sf_stream_config_bulk(stream, 6);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_atsc,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep6_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_atsc,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mh         lg2160
+ * bulk       EP5/BULK/5/8192/RAW
+ * isoc       EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+       else
+               mxl111sf_stream_config_bulk(stream, 5);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep5_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_mh,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* atsc mh    lgdt3305           mxl111sf          lg2160
+ * bulk       EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * isoc       EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       } else if (fe->id == 1) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 2) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_atsc_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_atsc_mh,
+       .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mercury    lgdt3305           mxl111sf          lg2161
+ * tp bulk    EP6/BULK/5/8192    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
+ * tp isoc    EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk   EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * spi isoc   EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       } else if (fe->id == 1) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mercury,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury,
+       .get_stream_config = mxl111sf_get_stream_config_mercury,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mercury mh mxl111sf          lg2161
+ * tp bulk    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
+ * tp isoc    EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk   EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * spi isoc   EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1  && dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mercury_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury_mh,
+       .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+static const struct usb_device_id mxl111sf_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
+
+static struct usb_driver mxl111sf_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = mxl111sf_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(mxl111sf_usb_driver);
+
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
new file mode 100644 (file)
index 0000000..9816de8
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+
+#ifndef _DVB_USB_MXL111SF_H_
+#define _DVB_USB_MXL111SF_H_
+
+#ifdef DVB_USB_LOG_PREFIX
+#undef DVB_USB_LOG_PREFIX
+#endif
+#define DVB_USB_LOG_PREFIX "mxl111sf"
+#include "dvb_usb.h"
+#include <media/tveeprom.h>
+
+#define MXL_EP1_REG_READ     1
+#define MXL_EP2_REG_WRITE    2
+#define MXL_EP3_INTERRUPT    3
+#define MXL_EP4_MPEG2        4
+#define MXL_EP5_I2S          5
+#define MXL_EP6_656          6
+#define MXL_EP6_MPEG2        6
+
+#ifdef USING_ENUM_mxl111sf_current_mode
+enum mxl111sf_current_mode {
+       mxl_mode_dvbt = MXL_EP4_MPEG2,
+       mxl_mode_mh   = MXL_EP5_I2S,
+       mxl_mode_atsc = MXL_EP6_MPEG2,
+};
+#endif
+
+enum mxl111sf_gpio_port_expander {
+       mxl111sf_gpio_hw,
+       mxl111sf_PCA9534,
+};
+
+struct mxl111sf_adap_state {
+       int alt_mode;
+       int gpio_mode;
+       int device_mode;
+       int ep6_clockphase;
+       int (*fe_init)(struct dvb_frontend *);
+       int (*fe_sleep)(struct dvb_frontend *);
+};
+
+struct mxl111sf_state {
+       struct dvb_usb_device *d;
+
+       enum mxl111sf_gpio_port_expander gpio_port_expander;
+       u8 port_expander_addr;
+
+       u8 chip_id;
+       u8 chip_ver;
+#define MXL111SF_V6     1
+#define MXL111SF_V8_100 2
+#define MXL111SF_V8_200 3
+       u8 chip_rev;
+
+#ifdef USING_ENUM_mxl111sf_current_mode
+       enum mxl111sf_current_mode current_mode;
+#endif
+
+#define MXL_TUNER_MODE         0
+#define MXL_SOC_MODE           1
+#define MXL_DEV_MODE_MASK      0x01
+#if 1
+       int device_mode;
+#endif
+       /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t),
+                                    EP5 BULK transfer (atsc-mh),
+                                    EP6 BULK transfer (atsc/qam),
+          use usb alt setting 2 for EP4 BULK transfer (dvb-t),
+                                    EP5 ISOC transfer (atsc-mh),
+                                    EP6 ISOC transfer (atsc/qam),
+        */
+       int alt_mode;
+       int gpio_mode;
+       struct tveeprom tv;
+
+       struct mutex fe_lock;
+       u8 num_frontends;
+       struct mxl111sf_adap_state adap_state[3];
+};
+
+int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
+int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data);
+
+struct mxl111sf_reg_ctrl_info {
+       u8 addr;
+       u8 mask;
+       u8 data;
+};
+
+int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
+                           u8 addr, u8 mask, u8 data);
+int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+
+/* needed for hardware i2c functions in mxl111sf-i2c.c:
+ * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
+int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
+
+#define mxl_printk(kern, fmt, arg...) \
+       printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define mxl_info(fmt, arg...) \
+       mxl_printk(KERN_INFO, fmt, ##arg)
+
+extern int dvb_usb_mxl111sf_debug;
+#define mxl_debug(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define MXL_I2C_DBG 0x04
+#define MXL_ADV_DBG 0x10
+#define mxl_debug_adv(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug & MXL_ADV_DBG) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define mxl_i2c(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug & MXL_I2C_DBG) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define mxl_i2c_adv(fmt, arg...) \
+       if ((dvb_usb_mxl111sf_debug & (MXL_I2C_DBG | MXL_ADV_DBG)) == \
+               (MXL_I2C_DBG | MXL_ADV_DBG)) \
+                       mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+/* The following allows the mxl_fail() macro defined below to work
+ * in externel modules, such as mxl111sf-tuner.ko, even though
+ * dvb_usb_mxl111sf_debug is not defined within those modules */
+#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
+#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
+#else
+#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
+#endif
+
+#define mxl_fail(ret)                                                  \
+({                                                                     \
+       int __ret;                                                      \
+       __ret = (ret < 0);                                              \
+       if ((__ret) && (MXL_ADV_DEBUG_ENABLED & MXL_ADV_DBG))           \
+               mxl_printk(KERN_ERR, "error %d on line %d",             \
+                          ret, __LINE__);                              \
+       __ret;                                                          \
+})
+
+#endif /* _DVB_USB_MXL111SF_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
new file mode 100644 (file)
index 0000000..a2d1e5b
--- /dev/null
@@ -0,0 +1,1259 @@
+/*
+ * Realtek RTL28xxU DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Thomas Mair <thomas.mair86@googlemail.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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "rtl28xxu.h"
+
+#include "rtl2830.h"
+#include "rtl2832.h"
+
+#include "qt1010.h"
+#include "mt2060.h"
+#include "mxl5005s.h"
+#include "fc0012.h"
+#include "fc0013.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
+{
+       int ret;
+       unsigned int pipe;
+       u8 requesttype;
+       u8 *buf;
+
+       buf = kmalloc(req->size, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       if (req->index & CMD_WR_FLAG) {
+               /* write */
+               memcpy(buf, req->data, req->size);
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {
+               /* read */
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
+                       req->index, buf, req->size, 1000);
+       if (ret > 0)
+               ret = 0;
+
+       deb_dump(0, requesttype, req->value, req->index, buf, req->size);
+
+       /* read request, copy returned data to return buf */
+       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+               memcpy(req->data, buf, req->size);
+
+       kfree(buf);
+
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
+{
+       struct rtl28xxu_req req;
+
+       if (reg < 0x3000)
+               req.index = CMD_USB_WR;
+       else if (reg < 0x4000)
+               req.index = CMD_SYS_WR;
+       else
+               req.index = CMD_IR_WR;
+
+       req.value = reg;
+       req.size = len;
+       req.data = val;
+
+       return rtl28xxu_ctrl_msg(d, &req);
+}
+
+static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
+{
+       struct rtl28xxu_req req;
+
+       if (reg < 0x3000)
+               req.index = CMD_USB_RD;
+       else if (reg < 0x4000)
+               req.index = CMD_SYS_RD;
+       else
+               req.index = CMD_IR_RD;
+
+       req.value = reg;
+       req.size = len;
+       req.data = val;
+
+       return rtl28xxu_ctrl_msg(d, &req);
+}
+
+static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
+{
+       return rtl28xx_wr_regs(d, reg, &val, 1);
+}
+
+static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
+{
+       return rtl2831_rd_regs(d, reg, val, 1);
+}
+
+/* I2C */
+static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+       int num)
+{
+       int ret;
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct rtl28xxu_priv *priv = d->priv;
+       struct rtl28xxu_req req;
+
+       /*
+        * It is not known which are real I2C bus xfer limits, but testing
+        * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes.
+        * TODO: find out RTL2832U lens
+        */
+
+       /*
+        * I2C adapter logic looks rather complicated due to fact it handles
+        * three different access methods. Those methods are;
+        * 1) integrated demod access
+        * 2) old I2C access
+        * 3) new I2C access
+        *
+        * Used method is selected in order 1, 2, 3. Method 3 can handle all
+        * requests but there is two reasons why not use it always;
+        * 1) It is most expensive, usually two USB messages are needed
+        * 2) At least RTL2831U does not support it
+        *
+        * Method 3 is needed in case of I2C write+read (typical register read)
+        * where write is more than one byte.
+        */
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
+               (msg[1].flags & I2C_M_RD)) {
+               if (msg[0].len > 24 || msg[1].len > 24) {
+                       /* TODO: check msg[0].len max */
+                       ret = -EOPNOTSUPP;
+                       goto err_mutex_unlock;
+               } else if (msg[0].addr == 0x10) {
+                       /* method 1 - integrated demod */
+                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
+                       req.index = CMD_DEMOD_RD | priv->page;
+                       req.size = msg[1].len;
+                       req.data = &msg[1].buf[0];
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+               } else if (msg[0].len < 2) {
+                       /* method 2 - old I2C */
+                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
+                       req.index = CMD_I2C_RD;
+                       req.size = msg[1].len;
+                       req.data = &msg[1].buf[0];
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+               } else {
+                       /* method 3 - new I2C */
+                       req.value = (msg[0].addr << 1);
+                       req.index = CMD_I2C_DA_WR;
+                       req.size = msg[0].len;
+                       req.data = msg[0].buf;
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+                       if (ret)
+                               goto err_mutex_unlock;
+
+                       req.value = (msg[0].addr << 1);
+                       req.index = CMD_I2C_DA_RD;
+                       req.size = msg[1].len;
+                       req.data = msg[1].buf;
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+               }
+       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
+               if (msg[0].len > 22) {
+                       /* TODO: check msg[0].len max */
+                       ret = -EOPNOTSUPP;
+                       goto err_mutex_unlock;
+               } else if (msg[0].addr == 0x10) {
+                       /* method 1 - integrated demod */
+                       if (msg[0].buf[0] == 0x00) {
+                               /* save demod page for later demod access */
+                               priv->page = msg[0].buf[1];
+                               ret = 0;
+                       } else {
+                               req.value = (msg[0].buf[0] << 8) |
+                                       (msg[0].addr << 1);
+                               req.index = CMD_DEMOD_WR | priv->page;
+                               req.size = msg[0].len-1;
+                               req.data = &msg[0].buf[1];
+                               ret = rtl28xxu_ctrl_msg(d, &req);
+                       }
+               } else if (msg[0].len < 23) {
+                       /* method 2 - old I2C */
+                       req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
+                       req.index = CMD_I2C_WR;
+                       req.size = msg[0].len-1;
+                       req.data = &msg[0].buf[1];
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+               } else {
+                       /* method 3 - new I2C */
+                       req.value = (msg[0].addr << 1);
+                       req.index = CMD_I2C_DA_WR;
+                       req.size = msg[0].len;
+                       req.data = msg[0].buf;
+                       ret = rtl28xxu_ctrl_msg(d, &req);
+               }
+       } else {
+               ret = -EINVAL;
+       }
+
+err_mutex_unlock:
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret ? ret : num;
+}
+
+static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm rtl28xxu_i2c_algo = {
+       .master_xfer   = rtl28xxu_i2c_xfer,
+       .functionality = rtl28xxu_i2c_func,
+};
+
+static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
+       .i2c_addr = 0x10, /* 0x20 */
+       .xtal = 28800000,
+       .ts_mode = 0,
+       .spec_inv = 1,
+       .if_dvbt = 36150000,
+       .vtop = 0x20,
+       .krf = 0x04,
+       .agc_targ_val = 0x2d,
+
+};
+
+static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
+       .i2c_addr = 0x10, /* 0x20 */
+       .xtal = 28800000,
+       .ts_mode = 0,
+       .spec_inv = 1,
+       .if_dvbt = 36125000,
+       .vtop = 0x20,
+       .krf = 0x04,
+       .agc_targ_val = 0x2d,
+};
+
+static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
+       .i2c_addr = 0x10, /* 0x20 */
+       .xtal = 28800000,
+       .ts_mode = 0,
+       .spec_inv = 0,
+       .if_dvbt = 4570000,
+       .vtop = 0x3f,
+       .krf = 0x04,
+       .agc_targ_val = 0x3e,
+};
+
+static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct rtl28xxu_priv *priv = d_to_priv(d);
+       u8 buf[1];
+       struct rtl2830_config *rtl2830_config;
+       /* open RTL2831U/RTL2830 I2C gate */
+       struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
+       /* for MT2060 tuner probe */
+       struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
+       /* for QT1010 tuner probe */
+       struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /*
+        * RTL2831U GPIOs
+        * =========================================================
+        * GPIO0 | tuner#0 | 0 off | 1 on  | MXL5005S (?)
+        * GPIO2 | LED     | 0 off | 1 on  |
+        * GPIO4 | tuner#1 | 0 on  | 1 off | MT2060
+        */
+
+       /* GPIO direction */
+       ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, 0x0a);
+       if (ret)
+               goto err;
+
+       /* enable as output GPIO0, GPIO2, GPIO4 */
+       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, 0x15);
+       if (ret)
+               goto err;
+
+       /*
+        * Probe used tuner. We need to know used tuner before demod attach
+        * since there is some demod params needed to set according to tuner.
+        */
+
+       /* demod needs some time to wake up */
+       msleep(20);
+
+       /* open demod I2C gate */
+       ret = rtl28xxu_ctrl_msg(d, &req_gate);
+       if (ret)
+               goto err;
+
+       /* check QT1010 ID(?) register; reg=0f val=2c */
+       ret = rtl28xxu_ctrl_msg(d, &req_qt1010);
+       if (ret == 0 && buf[0] == 0x2c) {
+               priv->tuner = TUNER_RTL2830_QT1010;
+               rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
+               dev_dbg(&d->udev->dev, "%s: QT1010\n", __func__);
+               goto found;
+       } else {
+               dev_dbg(&d->udev->dev, "%s: QT1010 probe failed=%d - %02x\n",
+                               __func__, ret, buf[0]);
+       }
+
+       /* open demod I2C gate */
+       ret = rtl28xxu_ctrl_msg(d, &req_gate);
+       if (ret)
+               goto err;
+
+       /* check MT2060 ID register; reg=00 val=63 */
+       ret = rtl28xxu_ctrl_msg(d, &req_mt2060);
+       if (ret == 0 && buf[0] == 0x63) {
+               priv->tuner = TUNER_RTL2830_MT2060;
+               rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
+               dev_dbg(&d->udev->dev, "%s: MT2060\n", __func__);
+               goto found;
+       } else {
+               dev_dbg(&d->udev->dev, "%s: MT2060 probe failed=%d - %02x\n",
+                               __func__, ret, buf[0]);
+       }
+
+       /* assume MXL5005S */
+       ret = 0;
+       priv->tuner = TUNER_RTL2830_MXL5005S;
+       rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
+       dev_dbg(&d->udev->dev, "%s: MXL5005S\n", __func__);
+       goto found;
+
+found:
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(rtl2830_attach, rtl2830_config,
+               &d->i2c_adap);
+       if (adap->fe[0] == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
+       .i2c_addr = 0x10, /* 0x20 */
+       .xtal = 28800000,
+       .if_dvbt = 0,
+       .tuner = TUNER_RTL2832_FC0012
+};
+
+static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
+       .i2c_addr = 0x10, /* 0x20 */
+       .xtal = 28800000,
+       .if_dvbt = 0,
+       .tuner = TUNER_RTL2832_FC0013
+};
+
+static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
+               int cmd, int arg)
+{
+       int ret;
+       u8 val;
+
+       dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
+
+       switch (cmd) {
+       case FC_FE_CALLBACK_VHF_ENABLE:
+               /* set output values */
+               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+               if (ret)
+                       goto err;
+
+               if (arg)
+                       val &= 0xbf; /* set GPIO6 low */
+               else
+                       val |= 0x40; /* set GPIO6 high */
+
+
+               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+               if (ret)
+                       goto err;
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+       return 0;
+
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+
+static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d,
+               int cmd, int arg)
+{
+       /* TODO implement*/
+       return 0;
+}
+
+static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
+{
+       struct rtl28xxu_priv *priv = d->priv;
+
+       switch (priv->tuner) {
+       case TUNER_RTL2832_FC0012:
+               return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
+
+       case TUNER_RTL2832_FC0013:
+               return rtl2832u_fc0013_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -ENODEV;
+}
+
+static int rtl2832u_frontend_callback(void *adapter_priv, int component,
+                                   int cmd, int arg)
+{
+       struct i2c_adapter *adap = adapter_priv;
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+       switch (component) {
+       case DVB_FRONTEND_COMPONENT_TUNER:
+               return rtl2832u_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct rtl28xxu_priv *priv = d_to_priv(d);
+       struct rtl2832_config *rtl2832_config;
+       u8 buf[2], val;
+       /* open RTL2832U/RTL2832 I2C gate */
+       struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
+       /* close RTL2832U/RTL2832 I2C gate */
+       struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
+       /* for FC0012 tuner probe */
+       struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf};
+       /* for FC0013 tuner probe */
+       struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf};
+       /* for MT2266 tuner probe */
+       struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf};
+       /* for FC2580 tuner probe */
+       struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
+       /* for MT2063 tuner probe */
+       struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf};
+       /* for MAX3543 tuner probe */
+       struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf};
+       /* for TUA9001 tuner probe */
+       struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf};
+       /* for MXL5007T tuner probe */
+       struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
+       /* for E4000 tuner probe */
+       struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
+       /* for TDA18272 tuner probe */
+       struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val);
+       if (ret)
+               goto err;
+
+       val &= 0xbf;
+
+       ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val);
+       if (ret)
+               goto err;
+
+       /* enable as output GPIO3 and GPIO6*/
+       ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val);
+       if (ret)
+               goto err;
+
+       val |= 0x48;
+
+       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val);
+       if (ret)
+               goto err;
+
+       /*
+        * Probe used tuner. We need to know used tuner before demod attach
+        * since there is some demod params needed to set according to tuner.
+        */
+
+       /* open demod I2C gate */
+       ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
+       if (ret)
+               goto err;
+
+       priv->tuner = TUNER_NONE;
+
+       /* check FC0012 ID register; reg=00 val=a1 */
+       ret = rtl28xxu_ctrl_msg(d, &req_fc0012);
+       if (ret == 0 && buf[0] == 0xa1) {
+               priv->tuner = TUNER_RTL2832_FC0012;
+               rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
+               dev_info(&d->udev->dev, "%s: FC0012 tuner found",
+                               KBUILD_MODNAME);
+               goto found;
+       }
+
+       /* check FC0013 ID register; reg=00 val=a3 */
+       ret = rtl28xxu_ctrl_msg(d, &req_fc0013);
+       if (ret == 0 && buf[0] == 0xa3) {
+               priv->tuner = TUNER_RTL2832_FC0013;
+               rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
+               dev_info(&d->udev->dev, "%s: FC0013 tuner found",
+                               KBUILD_MODNAME);
+               goto found;
+       }
+
+       /* check MT2266 ID register; reg=00 val=85 */
+       ret = rtl28xxu_ctrl_msg(d, &req_mt2266);
+       if (ret == 0 && buf[0] == 0x85) {
+               priv->tuner = TUNER_RTL2832_MT2266;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: MT2266 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check FC2580 ID register; reg=01 val=56 */
+       ret = rtl28xxu_ctrl_msg(d, &req_fc2580);
+       if (ret == 0 && buf[0] == 0x56) {
+               priv->tuner = TUNER_RTL2832_FC2580;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: FC2580 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check MT2063 ID register; reg=00 val=9e || 9c */
+       ret = rtl28xxu_ctrl_msg(d, &req_mt2063);
+       if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
+               priv->tuner = TUNER_RTL2832_MT2063;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: MT2063 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check MAX3543 ID register; reg=00 val=38 */
+       ret = rtl28xxu_ctrl_msg(d, &req_max3543);
+       if (ret == 0 && buf[0] == 0x38) {
+               priv->tuner = TUNER_RTL2832_MAX3543;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: MAX3534 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check TUA9001 ID register; reg=7e val=2328 */
+       ret = rtl28xxu_ctrl_msg(d, &req_tua9001);
+       if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
+               priv->tuner = TUNER_RTL2832_TUA9001;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: TUA9001 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check MXL5007R ID register; reg=d9 val=14 */
+       ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t);
+       if (ret == 0 && buf[0] == 0x14) {
+               priv->tuner = TUNER_RTL2832_MXL5007T;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: MXL5007T tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check E4000 ID register; reg=02 val=40 */
+       ret = rtl28xxu_ctrl_msg(d, &req_e4000);
+       if (ret == 0 && buf[0] == 0x40) {
+               priv->tuner = TUNER_RTL2832_E4000;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: E4000 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+       /* check TDA18272 ID register; reg=00 val=c760  */
+       ret = rtl28xxu_ctrl_msg(d, &req_tda18272);
+       if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
+               priv->tuner = TUNER_RTL2832_TDA18272;
+               /* TODO implement tuner */
+               dev_info(&d->udev->dev, "%s: TDA18272 tuner found",
+                               KBUILD_MODNAME);
+               goto unsupported;
+       }
+
+unsupported:
+       /* close demod I2C gate */
+       ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
+       if (ret)
+               goto err;
+
+       /* tuner not found */
+       dev_dbg(&d->udev->dev, "%s: No compatible tuner found\n", __func__);
+       ret = -ENODEV;
+       return ret;
+
+found:
+       /* close demod I2C gate */
+       ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
+       if (ret)
+               goto err;
+
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config,
+               &d->i2c_adap);
+               if (adap->fe[0] == NULL) {
+                       ret = -ENODEV;
+                       goto err;
+               }
+
+       /* set fe callbacks */
+       adap->fe[0]->callback = rtl2832u_frontend_callback;
+
+       return ret;
+
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static struct qt1010_config rtl28xxu_qt1010_config = {
+       .i2c_address = 0x62, /* 0xc4 */
+};
+
+static struct mt2060_config rtl28xxu_mt2060_config = {
+       .i2c_address = 0x60, /* 0xc0 */
+       .clock_out = 0,
+};
+
+static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
+       .i2c_address     = 0x63, /* 0xc6 */
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_C_H,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct rtl28xxu_priv *priv = d_to_priv(d);
+       struct i2c_adapter *rtl2830_tuner_i2c;
+       struct dvb_frontend *fe;
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
+       rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe[0]);
+
+       switch (priv->tuner) {
+       case TUNER_RTL2830_QT1010:
+               fe = dvb_attach(qt1010_attach, adap->fe[0],
+                               rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
+               break;
+       case TUNER_RTL2830_MT2060:
+               fe = dvb_attach(mt2060_attach, adap->fe[0],
+                               rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
+                               1220);
+               break;
+       case TUNER_RTL2830_MXL5005S:
+               fe = dvb_attach(mxl5005s_attach, adap->fe[0],
+                               rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
+               break;
+       default:
+               fe = NULL;
+               dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
+                               priv->tuner);
+       }
+
+       if (fe == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct rtl28xxu_priv *priv = d_to_priv(d);
+       struct dvb_frontend *fe;
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       switch (priv->tuner) {
+       case TUNER_RTL2832_FC0012:
+               fe = dvb_attach(fc0012_attach, adap->fe[0],
+                       &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
+
+               /* since fc0012 includs reading the signal strength delegate
+                * that to the tuner driver */
+               adap->fe[0]->ops.read_signal_strength =
+                               adap->fe[0]->ops.tuner_ops.get_rf_strength;
+               return 0;
+               break;
+       case TUNER_RTL2832_FC0013:
+               fe = dvb_attach(fc0013_attach, adap->fe[0],
+                       &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
+
+               /* fc0013 also supports signal strength reading */
+               adap->fe[0]->ops.read_signal_strength =
+                               adap->fe[0]->ops.tuner_ops.get_rf_strength;
+               return 0;
+       default:
+               fe = NULL;
+               dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
+                               priv->tuner);
+       }
+
+       if (fe == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl28xxu_init(struct dvb_usb_device *d)
+{
+       int ret;
+       u8 val;
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* init USB endpoints */
+       ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
+       if (ret)
+               goto err;
+
+       /* enable DMA and Full Packet Mode*/
+       val |= 0x09;
+       ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
+       if (ret)
+               goto err;
+
+       /* set EPA maximum packet size to 0x0200 */
+       ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
+       if (ret)
+               goto err;
+
+       /* change EPA FIFO length */
+       ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl28xxu_streaming_ctrl(struct dvb_frontend *fe , int onoff)
+{
+       int ret;
+       u8 buf[2];
+       struct dvb_usb_device *d = fe_to_d(fe);
+
+       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
+
+       if (onoff) {
+               buf[0] = 0x00;
+               buf[1] = 0x00;
+       } else {
+               buf[0] = 0x10; /* stall EPA */
+               buf[1] = 0x02; /* reset EPA */
+       }
+
+       ret = rtl28xx_wr_regs(d, USB_EPA_CTL, buf, 2);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+       u8 gpio, sys0;
+
+       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
+
+       /* demod adc */
+       ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0);
+       if (ret)
+               goto err;
+
+       /* tuner power, read GPIOs */
+       ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
+       if (ret)
+               goto err;
+
+       dev_dbg(&d->udev->dev, "%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
+                       sys0, gpio);
+
+       if (onoff) {
+               gpio |= 0x01; /* GPIO0 = 1 */
+               gpio &= (~0x10); /* GPIO4 = 0 */
+               gpio |= 0x04; /* GPIO2 = 1, LED on */
+               sys0 = sys0 & 0x0f;
+               sys0 |= 0xe0;
+       } else {
+               gpio &= (~0x01); /* GPIO0 = 0 */
+               gpio |= 0x10; /* GPIO4 = 1 */
+               gpio &= (~0x04); /* GPIO2 = 1, LED off */
+               sys0 = sys0 & (~0xc0);
+       }
+
+       dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
+                       sys0, gpio);
+
+       /* demod adc */
+       ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0);
+       if (ret)
+               goto err;
+
+       /* tuner power, write GPIOs */
+       ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+       u8 val;
+
+       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
+
+       if (onoff) {
+               /* set output values */
+               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+               if (ret)
+                       goto err;
+
+               val |= 0x08;
+               val &= 0xef;
+
+               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+               if (ret)
+                       goto err;
+
+               /* demod_ctl_1 */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+               if (ret)
+                       goto err;
+
+               val &= 0xef;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
+               if (ret)
+                       goto err;
+
+               /* demod control */
+               /* PLL enable */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+               if (ret)
+                       goto err;
+
+               /* bit 7 to 1 */
+               val |= 0x80;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+               if (ret)
+                       goto err;
+
+               /* demod HW reset */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+               if (ret)
+                       goto err;
+               /* bit 5 to 0 */
+               val &= 0xdf;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+               if (ret)
+                       goto err;
+
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+               if (ret)
+                       goto err;
+
+               val |= 0x20;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+               if (ret)
+                       goto err;
+
+               mdelay(5);
+
+               /*enable ADC_Q and ADC_I */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+               if (ret)
+                       goto err;
+
+               val |= 0x48;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+               if (ret)
+                       goto err;
+
+
+       } else {
+               /* demod_ctl_1 */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+               if (ret)
+                       goto err;
+
+               val |= 0x0c;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
+               if (ret)
+                       goto err;
+
+               /* set output values */
+               ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+               if (ret)
+                               goto err;
+
+               val |= 0x10;
+
+               ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+               if (ret)
+                       goto err;
+
+               /* demod control */
+               ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+               if (ret)
+                       goto err;
+
+               val &= 0x37;
+
+               ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+               if (ret)
+                       goto err;
+
+       }
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+
+static int rtl2831u_rc_query(struct dvb_usb_device *d)
+{
+       int ret, i;
+       struct rtl28xxu_priv *priv = d->priv;
+       u8 buf[5];
+       u32 rc_code;
+       struct rtl28xxu_reg_val rc_nec_tab[] = {
+               { 0x3033, 0x80 },
+               { 0x3020, 0x43 },
+               { 0x3021, 0x16 },
+               { 0x3022, 0x16 },
+               { 0x3023, 0x5a },
+               { 0x3024, 0x2d },
+               { 0x3025, 0x16 },
+               { 0x3026, 0x01 },
+               { 0x3028, 0xb0 },
+               { 0x3029, 0x04 },
+               { 0x302c, 0x88 },
+               { 0x302e, 0x13 },
+               { 0x3030, 0xdf },
+               { 0x3031, 0x05 },
+       };
+
+       /* init remote controller */
+       if (!priv->rc_active) {
+               for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
+                       ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
+                                       rc_nec_tab[i].val);
+                       if (ret)
+                               goto err;
+               }
+               priv->rc_active = true;
+       }
+
+       ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5);
+       if (ret)
+               goto err;
+
+       if (buf[4] & 0x01) {
+               if (buf[2] == (u8) ~buf[3]) {
+                       if (buf[0] == (u8) ~buf[1]) {
+                               /* NEC standard (16 bit) */
+                               rc_code = buf[0] << 8 | buf[2];
+                       } else {
+                               /* NEC extended (24 bit) */
+                               rc_code = buf[0] << 16 |
+                                               buf[1] << 8 | buf[2];
+                       }
+               } else {
+                       /* NEC full (32 bit) */
+                       rc_code = buf[0] << 24 | buf[1] << 16 |
+                                       buf[2] << 8 | buf[3];
+               }
+
+               rc_keydown(d->rc_dev, rc_code, 0);
+
+               ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
+               if (ret)
+                       goto err;
+
+               /* repeated intentionally to avoid extra keypress */
+               ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
+               if (ret)
+                       goto err;
+       }
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
+               struct dvb_usb_rc *rc)
+{
+       rc->map_name = RC_MAP_EMPTY;
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query = rtl2831u_rc_query;
+       rc->interval = 400;
+
+       return 0;
+}
+
+static int rtl2832u_rc_query(struct dvb_usb_device *d)
+{
+       int ret, i;
+       struct rtl28xxu_priv *priv = d->priv;
+       u8 buf[128];
+       int len;
+       struct rtl28xxu_reg_val rc_nec_tab[] = {
+               { IR_RX_CTRL,             0x20 },
+               { IR_RX_BUF_CTRL,         0x80 },
+               { IR_RX_IF,               0xff },
+               { IR_RX_IE,               0xff },
+               { IR_MAX_DURATION0,       0xd0 },
+               { IR_MAX_DURATION1,       0x07 },
+               { IR_IDLE_LEN0,           0xc0 },
+               { IR_IDLE_LEN1,           0x00 },
+               { IR_GLITCH_LEN,          0x03 },
+               { IR_RX_CLK,              0x09 },
+               { IR_RX_CFG,              0x1c },
+               { IR_MAX_H_TOL_LEN,       0x1e },
+               { IR_MAX_L_TOL_LEN,       0x1e },
+               { IR_RX_CTRL,             0x80 },
+       };
+
+       /* init remote controller */
+       if (!priv->rc_active) {
+               for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
+                       ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
+                                       rc_nec_tab[i].val);
+                       if (ret)
+                               goto err;
+               }
+               priv->rc_active = true;
+       }
+
+       ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]);
+       if (ret)
+               goto err;
+
+       if (buf[0] != 0x83)
+               goto exit;
+
+       ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
+       if (ret)
+               goto err;
+
+       len = buf[0];
+       ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
+
+       /* TODO: pass raw IR to Kernel IR decoder */
+
+       ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
+       ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
+       ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
+
+exit:
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
+               struct dvb_usb_rc *rc)
+{
+       rc->map_name = RC_MAP_EMPTY;
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query = rtl2832u_rc_query;
+       rc->interval = 400;
+
+       return 0;
+}
+
+static const struct dvb_usb_device_properties rtl2831u_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct rtl28xxu_priv),
+
+       .power_ctrl = rtl2831u_power_ctrl,
+       .i2c_algo = &rtl28xxu_i2c_algo,
+       .frontend_attach = rtl2831u_frontend_attach,
+       .tuner_attach = rtl2831u_tuner_attach,
+       .init = rtl28xxu_init,
+       .get_rc_config = rtl2831u_get_rc_config,
+       .streaming_ctrl = rtl28xxu_streaming_ctrl,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
+               },
+       },
+};
+
+static const struct dvb_usb_device_properties rtl2832u_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct rtl28xxu_priv),
+
+       .power_ctrl = rtl2832u_power_ctrl,
+       .i2c_algo = &rtl28xxu_i2c_algo,
+       .frontend_attach = rtl2832u_frontend_attach,
+       .tuner_attach = rtl2832u_tuner_attach,
+       .init = rtl28xxu_init,
+       .get_rc_config = rtl2832u_get_rc_config,
+       .streaming_ctrl = rtl28xxu_streaming_ctrl,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
+               },
+       },
+};
+
+static const struct usb_device_id rtl28xxu_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U,
+               &rtl2831u_props, "Realtek RTL2831U reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT,
+               &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
+       { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2,
+               &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
+
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
+               &rtl2832u_props, "Terratec Cinergy T Stick Black", NULL) },
+       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
+               &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
+               &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
+
+static struct usb_driver rtl28xxu_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = rtl28xxu_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(rtl28xxu_usb_driver);
+
+MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_AUTHOR("Thomas Mair <thomas.mair86@googlemail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
new file mode 100644 (file)
index 0000000..575edbf
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Realtek RTL28xxU DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef RTL28XXU_H
+#define RTL28XXU_H
+
+#include "dvb_usb.h"
+
+#define deb_dump(r, t, v, i, b, l) { \
+       char *direction; \
+       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+               direction = ">>>"; \
+       else \
+               direction = "<<<"; \
+       dev_dbg(&d->udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
+                       "%s [%d bytes]\n",  __func__, t, r, v & 0xff, v >> 8, \
+                       i & 0xff, i >> 8, l & 0xff, l >> 8, direction, l); \
+}
+
+/*
+ * USB commands
+ * (usb_control_msg() index parameter)
+ */
+
+#define DEMOD            0x0000
+#define USB              0x0100
+#define SYS              0x0200
+#define I2C              0x0300
+#define I2C_DA           0x0600
+
+#define CMD_WR_FLAG      0x0010
+#define CMD_DEMOD_RD     0x0000
+#define CMD_DEMOD_WR     0x0010
+#define CMD_USB_RD       0x0100
+#define CMD_USB_WR       0x0110
+#define CMD_SYS_RD       0x0200
+#define CMD_IR_RD        0x0201
+#define CMD_IR_WR        0x0211
+#define CMD_SYS_WR       0x0210
+#define CMD_I2C_RD       0x0300
+#define CMD_I2C_WR       0x0310
+#define CMD_I2C_DA_RD    0x0600
+#define CMD_I2C_DA_WR    0x0610
+
+
+struct rtl28xxu_priv {
+       u8 chip_id;
+       u8 tuner;
+       u8 page; /* integrated demod active register page */
+       bool rc_active;
+};
+
+enum rtl28xxu_chip_id {
+       CHIP_ID_NONE,
+       CHIP_ID_RTL2831U,
+       CHIP_ID_RTL2832U,
+};
+
+enum rtl28xxu_tuner {
+       TUNER_NONE,
+
+       TUNER_RTL2830_QT1010,
+       TUNER_RTL2830_MT2060,
+       TUNER_RTL2830_MXL5005S,
+
+       TUNER_RTL2832_MT2266,
+       TUNER_RTL2832_FC2580,
+       TUNER_RTL2832_MT2063,
+       TUNER_RTL2832_MAX3543,
+       TUNER_RTL2832_TUA9001,
+       TUNER_RTL2832_MXL5007T,
+       TUNER_RTL2832_FC0012,
+       TUNER_RTL2832_E4000,
+       TUNER_RTL2832_TDA18272,
+       TUNER_RTL2832_FC0013,
+};
+
+struct rtl28xxu_req {
+       u16 value;
+       u16 index;
+       u16 size;
+       u8 *data;
+};
+
+struct rtl28xxu_reg_val {
+       u16 reg;
+       u8 val;
+};
+
+/*
+ * memory map
+ *
+ * 0x0000 DEMOD : demodulator
+ * 0x2000 USB   : SIE, USB endpoint, debug, DMA
+ * 0x3000 SYS   : system
+ * 0xfc00 RC    : remote controller (not RTL2831U)
+ */
+
+/*
+ * USB registers
+ */
+/* SIE Control Registers */
+#define USB_SYSCTL         0x2000 /* USB system control */
+#define USB_SYSCTL_0       0x2000 /* USB system control */
+#define USB_SYSCTL_1       0x2001 /* USB system control */
+#define USB_SYSCTL_2       0x2002 /* USB system control */
+#define USB_SYSCTL_3       0x2003 /* USB system control */
+#define USB_IRQSTAT        0x2008 /* SIE interrupt status */
+#define USB_IRQEN          0x200C /* SIE interrupt enable */
+#define USB_CTRL           0x2010 /* USB control */
+#define USB_STAT           0x2014 /* USB status */
+#define USB_DEVADDR        0x2018 /* USB device address */
+#define USB_TEST           0x201C /* USB test mode */
+#define USB_FRAME_NUMBER   0x2020 /* frame number */
+#define USB_FIFO_ADDR      0x2028 /* address of SIE FIFO RAM */
+#define USB_FIFO_CMD       0x202A /* SIE FIFO RAM access command */
+#define USB_FIFO_DATA      0x2030 /* SIE FIFO RAM data */
+/* Endpoint Registers */
+#define EP0_SETUPA         0x20F8 /* EP 0 setup packet lower byte */
+#define EP0_SETUPB         0x20FC /* EP 0 setup packet higher byte */
+#define USB_EP0_CFG        0x2104 /* EP 0 configure */
+#define USB_EP0_CTL        0x2108 /* EP 0 control */
+#define USB_EP0_STAT       0x210C /* EP 0 status */
+#define USB_EP0_IRQSTAT    0x2110 /* EP 0 interrupt status */
+#define USB_EP0_IRQEN      0x2114 /* EP 0 interrupt enable */
+#define USB_EP0_MAXPKT     0x2118 /* EP 0 max packet size */
+#define USB_EP0_BC         0x2120 /* EP 0 FIFO byte counter */
+#define USB_EPA_CFG        0x2144 /* EP A configure */
+#define USB_EPA_CFG_0      0x2144 /* EP A configure */
+#define USB_EPA_CFG_1      0x2145 /* EP A configure */
+#define USB_EPA_CFG_2      0x2146 /* EP A configure */
+#define USB_EPA_CFG_3      0x2147 /* EP A configure */
+#define USB_EPA_CTL        0x2148 /* EP A control */
+#define USB_EPA_CTL_0      0x2148 /* EP A control */
+#define USB_EPA_CTL_1      0x2149 /* EP A control */
+#define USB_EPA_CTL_2      0x214A /* EP A control */
+#define USB_EPA_CTL_3      0x214B /* EP A control */
+#define USB_EPA_STAT       0x214C /* EP A status */
+#define USB_EPA_IRQSTAT    0x2150 /* EP A interrupt status */
+#define USB_EPA_IRQEN      0x2154 /* EP A interrupt enable */
+#define USB_EPA_MAXPKT     0x2158 /* EP A max packet size */
+#define USB_EPA_MAXPKT_0   0x2158 /* EP A max packet size */
+#define USB_EPA_MAXPKT_1   0x2159 /* EP A max packet size */
+#define USB_EPA_MAXPKT_2   0x215A /* EP A max packet size */
+#define USB_EPA_MAXPKT_3   0x215B /* EP A max packet size */
+#define USB_EPA_FIFO_CFG   0x2160 /* EP A FIFO configure */
+#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */
+#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */
+#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */
+#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */
+/* Debug Registers */
+#define USB_PHYTSTDIS      0x2F04 /* PHY test disable */
+#define USB_TOUT_VAL       0x2F08 /* USB time-out time */
+#define USB_VDRCTRL        0x2F10 /* UTMI vendor signal control */
+#define USB_VSTAIN         0x2F14 /* UTMI vendor signal status in */
+#define USB_VLOADM         0x2F18 /* UTMI load vendor signal status in */
+#define USB_VSTAOUT        0x2F1C /* UTMI vendor signal status out */
+#define USB_UTMI_TST       0x2F80 /* UTMI test */
+#define USB_UTMI_STATUS    0x2F84 /* UTMI status */
+#define USB_TSTCTL         0x2F88 /* test control */
+#define USB_TSTCTL2        0x2F8C /* test control 2 */
+#define USB_PID_FORCE      0x2F90 /* force PID */
+#define USB_PKTERR_CNT     0x2F94 /* packet error counter */
+#define USB_RXERR_CNT      0x2F98 /* RX error counter */
+#define USB_MEM_BIST       0x2F9C /* MEM BIST test */
+#define USB_SLBBIST        0x2FA0 /* self-loop-back BIST */
+#define USB_CNTTEST        0x2FA4 /* counter test */
+#define USB_PHYTST         0x2FC0 /* USB PHY test */
+#define USB_DBGIDX         0x2FF0 /* select individual block debug signal */
+#define USB_DBGMUX         0x2FF4 /* debug signal module mux */
+
+/*
+ * SYS registers
+ */
+/* demod control registers */
+#define SYS_SYS0           0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */
+#define SYS_DEMOD_CTL      0x3000 /* control register for DVB-T demodulator */
+/* GPIO registers */
+#define SYS_GPIO_OUT_VAL   0x3001 /* output value of GPIO */
+#define SYS_GPIO_IN_VAL    0x3002 /* input value of GPIO */
+#define SYS_GPIO_OUT_EN    0x3003 /* output enable of GPIO */
+#define SYS_SYS1           0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */
+#define SYS_GPIO_DIR       0x3004 /* direction control for GPIO */
+#define SYS_SYSINTE        0x3005 /* system interrupt enable */
+#define SYS_SYSINTS        0x3006 /* system interrupt status */
+#define SYS_GPIO_CFG0      0x3007 /* PAD configuration for GPIO0-GPIO3 */
+#define SYS_SYS2           0x3008 /* include GP_CFG1 and 3 reserved bytes */
+#define SYS_GPIO_CFG1      0x3008 /* PAD configuration for GPIO4 */
+#define SYS_DEMOD_CTL1     0x300B
+
+/* IrDA registers */
+#define SYS_IRRC_PSR       0x3020 /* IR protocol selection */
+#define SYS_IRRC_PER       0x3024 /* IR protocol extension */
+#define SYS_IRRC_SF        0x3028 /* IR sampling frequency */
+#define SYS_IRRC_DPIR      0x302C /* IR data package interval */
+#define SYS_IRRC_CR        0x3030 /* IR control */
+#define SYS_IRRC_RP        0x3034 /* IR read port */
+#define SYS_IRRC_SR        0x3038 /* IR status */
+/* I2C master registers */
+#define SYS_I2CCR          0x3040 /* I2C clock */
+#define SYS_I2CMCR         0x3044 /* I2C master control */
+#define SYS_I2CMSTR        0x3048 /* I2C master SCL timing */
+#define SYS_I2CMSR         0x304C /* I2C master status */
+#define SYS_I2CMFR         0x3050 /* I2C master FIFO */
+
+/*
+ * IR registers
+ */
+#define IR_RX_BUF          0xFC00
+#define IR_RX_IE           0xFD00
+#define IR_RX_IF           0xFD01
+#define IR_RX_CTRL         0xFD02
+#define IR_RX_CFG          0xFD03
+#define IR_MAX_DURATION0   0xFD04
+#define IR_MAX_DURATION1   0xFD05
+#define IR_IDLE_LEN0       0xFD06
+#define IR_IDLE_LEN1       0xFD07
+#define IR_GLITCH_LEN      0xFD08
+#define IR_RX_BUF_CTRL     0xFD09
+#define IR_RX_BUF_DATA     0xFD0A
+#define IR_RX_BC           0xFD0B
+#define IR_RX_CLK          0xFD0C
+#define IR_RX_C_COUNT_L    0xFD0D
+#define IR_RX_C_COUNT_H    0xFD0E
+#define IR_SUSPEND_CTRL    0xFD10
+#define IR_ERR_TOL_CTRL    0xFD11
+#define IR_UNIT_LEN        0xFD12
+#define IR_ERR_TOL_LEN     0xFD13
+#define IR_MAX_H_TOL_LEN   0xFD14
+#define IR_MAX_L_TOL_LEN   0xFD15
+#define IR_MASK_CTRL       0xFD16
+#define IR_MASK_DATA       0xFD17
+#define IR_RES_MASK_ADDR   0xFD18
+#define IR_RES_MASK_T_LEN  0xFD19
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/usb_urb.c b/drivers/media/usb/dvb-usb-v2/usb_urb.c
new file mode 100644 (file)
index 0000000..eaf673a
--- /dev/null
@@ -0,0 +1,357 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb_usb_common.h"
+
+/* URB stuff for streaming */
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props);
+
+static void usb_urb_complete(struct urb *urb)
+{
+       struct usb_data_stream *stream = urb->context;
+       int ptype = usb_pipetype(urb->pipe);
+       int i;
+       u8 *b;
+
+       dev_dbg(&stream->udev->dev, "%s: %s urb completed status=%d " \
+                       "length=%d/%d pack_num=%d errors=%d\n", __func__,
+                       ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+                       urb->status, urb->actual_length,
+                       urb->transfer_buffer_length,
+                       urb->number_of_packets, urb->error_count);
+
+       switch (urb->status) {
+       case 0:         /* success */
+       case -ETIMEDOUT:    /* NAK */
+               break;
+       case -ECONNRESET:   /* kill */
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:        /* error */
+               dev_dbg(&stream->udev->dev, "%s: urb completition failed=%d\n",
+                               __func__, urb->status);
+               break;
+       }
+
+       b = (u8 *) urb->transfer_buffer;
+       switch (ptype) {
+       case PIPE_ISOCHRONOUS:
+               for (i = 0; i < urb->number_of_packets; i++) {
+                       if (urb->iso_frame_desc[i].status != 0)
+                               dev_dbg(&stream->udev->dev, "%s: iso frame " \
+                                               "descriptor has an error=%d\n",
+                                               __func__,
+                                               urb->iso_frame_desc[i].status);
+                       else if (urb->iso_frame_desc[i].actual_length > 0)
+                               stream->complete(stream,
+                                       b + 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;
+               }
+               break;
+       case PIPE_BULK:
+               if (urb->actual_length > 0)
+                       stream->complete(stream, b, urb->actual_length);
+               break;
+       default:
+               dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
+                               "completition handler\n", KBUILD_MODNAME);
+               return;
+       }
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+int usb_urb_killv2(struct usb_data_stream *stream)
+{
+       int i;
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+       return 0;
+}
+
+int usb_urb_submitv2(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props)
+{
+       int i, ret;
+
+       if (props) {
+               ret = usb_urb_reconfig(stream, props);
+               if (ret < 0)
+                       return ret;
+       }
+
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
+               ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
+               if (ret) {
+                       dev_err(&stream->udev->dev, "%s: could not submit " \
+                                       "urb no. %d - get them all back\n",
+                                       KBUILD_MODNAME, i);
+                       usb_urb_killv2(stream);
+                       return ret;
+               }
+               stream->urbs_submitted++;
+       }
+       return 0;
+}
+
+int usb_urb_free_urbs(struct usb_data_stream *stream)
+{
+       int i;
+
+       usb_urb_killv2(stream);
+
+       for (i = stream->urbs_initialized - 1; i >= 0; i--) {
+               if (stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
+                                       __func__, i);
+                       /* free the URBs */
+                       usb_free_urb(stream->urb_list[i]);
+               }
+       }
+       stream->urbs_initialized = 0;
+
+       return 0;
+}
+
+static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
+{
+       int i, j;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+               usb_fill_bulk_urb(stream->urb_list[i],
+                               stream->udev,
+                               usb_rcvbulkpipe(stream->udev,
+                                               stream->props.endpoint),
+                               stream->buf_list[i],
+                               stream->props.u.bulk.buffersize,
+                               usb_urb_complete, stream);
+
+               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
+{
+       int i, j;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               struct urb *urb;
+               int frame_offset = 0;
+               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+               stream->urb_list[i] = usb_alloc_urb(
+                               stream->props.u.isoc.framesperurb, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+
+               urb = stream->urb_list[i];
+
+               urb->dev = stream->udev;
+               urb->context = stream;
+               urb->complete = usb_urb_complete;
+               urb->pipe = usb_rcvisocpipe(stream->udev,
+                               stream->props.endpoint);
+               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+               urb->interval = stream->props.u.isoc.interval;
+               urb->number_of_packets = stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer_length = stream->props.u.isoc.framesize *
+                               stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer = stream->buf_list[i];
+               urb->transfer_dma = stream->dma_addr[i];
+
+               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length =
+                                       stream->props.u.isoc.framesize;
+                       frame_offset += stream->props.u.isoc.framesize;
+               }
+
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+       if (stream->state & USB_STATE_URB_BUF) {
+               while (stream->buf_num) {
+                       stream->buf_num--;
+                       dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
+                               __func__, stream->buf_num);
+                       usb_free_coherent(stream->udev, stream->buf_size,
+                                         stream->buf_list[stream->buf_num],
+                                         stream->dma_addr[stream->buf_num]);
+               }
+       }
+
+       stream->state &= ~USB_STATE_URB_BUF;
+
+       return 0;
+}
+
+int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
+               unsigned long size)
+{
+       stream->buf_num = 0;
+       stream->buf_size = size;
+
+       dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
+                       "streaming\n", __func__,  num * size);
+
+       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+               stream->buf_list[stream->buf_num] = usb_alloc_coherent(
+                               stream->udev, size, GFP_ATOMIC,
+                               &stream->dma_addr[stream->buf_num]);
+               if (!stream->buf_list[stream->buf_num]) {
+                       dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
+                                       __func__, stream->buf_num);
+                       usb_free_stream_buffers(stream);
+                       return -ENOMEM;
+               }
+
+               dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+                               __func__, stream->buf_num,
+                               stream->buf_list[stream->buf_num],
+                               (long long)stream->dma_addr[stream->buf_num]);
+               memset(stream->buf_list[stream->buf_num], 0, size);
+               stream->state |= USB_STATE_URB_BUF;
+       }
+
+       return 0;
+}
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props)
+{
+       int buf_size;
+
+       if (!props)
+               return 0;
+
+       /* check allocated buffers are large enough for the request */
+       if (props->type == USB_BULK) {
+               buf_size = stream->props.u.bulk.buffersize;
+       } else if (props->type == USB_ISOC) {
+               buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
+       } else {
+               dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
+                               KBUILD_MODNAME, props->type);
+               return -EINVAL;
+       }
+
+       if (stream->buf_num < props->count || stream->buf_size < buf_size) {
+               dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
+                               "allocated buffers are too small\n",
+                               KBUILD_MODNAME);
+               return -EINVAL;
+       }
+
+       /* check if all fields are same */
+       if (stream->props.type == props->type &&
+                       stream->props.count == props->count &&
+                       stream->props.endpoint == props->endpoint) {
+               if (props->type == USB_BULK &&
+                               props->u.bulk.buffersize ==
+                               stream->props.u.bulk.buffersize)
+                       return 0;
+               else if (props->type == USB_ISOC &&
+                               props->u.isoc.framesperurb ==
+                               stream->props.u.isoc.framesperurb &&
+                               props->u.isoc.framesize ==
+                               stream->props.u.isoc.framesize &&
+                               props->u.isoc.interval ==
+                               stream->props.u.isoc.interval)
+                       return 0;
+       }
+
+       dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
+
+       usb_urb_free_urbs(stream);
+       memcpy(&stream->props, props, sizeof(*props));
+       if (props->type == USB_BULK)
+               return usb_urb_alloc_bulk_urbs(stream);
+       else if (props->type == USB_ISOC)
+               return usb_urb_alloc_isoc_urbs(stream);
+
+       return 0;
+}
+
+int usb_urb_initv2(struct usb_data_stream *stream,
+               const struct usb_data_stream_properties *props)
+{
+       int ret;
+
+       if (!stream || !props)
+               return -EINVAL;
+
+       memcpy(&stream->props, props, sizeof(*props));
+
+       if (!stream->complete) {
+               dev_err(&stream->udev->dev, "%s: there is no data callback - " \
+                               "this doesn't make sense\n", KBUILD_MODNAME);
+               return -EINVAL;
+       }
+
+       switch (stream->props.type) {
+       case USB_BULK:
+               ret = usb_alloc_stream_buffers(stream, stream->props.count,
+                               stream->props.u.bulk.buffersize);
+               if (ret < 0)
+                       return ret;
+
+               return usb_urb_alloc_bulk_urbs(stream);
+       case USB_ISOC:
+               ret = usb_alloc_stream_buffers(stream, stream->props.count,
+                               stream->props.u.isoc.framesize *
+                               stream->props.u.isoc.framesperurb);
+               if (ret < 0)
+                       return ret;
+
+               return usb_urb_alloc_isoc_urbs(stream);
+       default:
+               dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
+                               "transfer\n", KBUILD_MODNAME);
+               return -EINVAL;
+       }
+}
+
+int usb_urb_exitv2(struct usb_data_stream *stream)
+{
+       usb_urb_free_urbs(stream);
+       usb_free_stream_buffers(stream);
+
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
new file mode 100644 (file)
index 0000000..00173ee
--- /dev/null
@@ -0,0 +1,313 @@
+config DVB_USB
+       tristate "Support for various USB DVB devices"
+       depends on DVB_CORE && USB && I2C && RC_CORE
+       help
+         By enabling this you will be able to choose the various supported
+         USB1.1 and USB2.0 DVB devices.
+
+         Almost every USB device needs a firmware, please look into
+         <file:Documentation/dvb/README.dvb-usb>.
+
+         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+         Say Y if you own a USB DVB device.
+
+config DVB_USB_DEBUG
+       bool "Enable extended debug support for all DVB-USB devices"
+       depends on DVB_USB
+       help
+         Say Y if you want to enable debugging. See modinfo dvb-usb (and the
+         appropriate drivers) for debug levels.
+
+config DVB_USB_A800
+       tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
+       depends on DVB_USB
+       select DVB_DIB3000MC
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
+
+config DVB_USB_DIBUSB_MB
+       tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
+       depends on DVB_USB
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_DIB3000MB
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
+         DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
+
+         For an up-to-date list of devices supported by this driver, have a look
+         on the Linux-DVB Wiki at www.linuxtv.org.
+
+         Say Y if you own such a device and want to use it. You should build it as
+         a module.
+
+config DVB_USB_DIBUSB_MB_FAULTY
+       bool "Support faulty USB IDs"
+       depends on DVB_USB_DIBUSB_MB
+       help
+         Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
+
+config DVB_USB_DIBUSB_MC
+       tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
+       depends on DVB_USB
+       select DVB_DIB3000MC
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Support for USB2.0 DVB-T receivers based on reference designs made by
+         DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
+
+         For an up-to-date list of devices supported by this driver, have a look
+         on the Linux-DVB Wiki at www.linuxtv.org.
+
+         Say Y if you own such a device and want to use it. You should build it as
+         a module.
+
+config DVB_USB_DIB0700
+       tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
+       depends on DVB_USB
+       select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+       select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+       select DVB_DIB8000 if !DVB_FE_CUSTOMISE
+       select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
+       select DVB_S5H1411 if !DVB_FE_CUSTOMISE
+       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+       help
+         Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
+         USB bridge is also present in devices having the DiB7700 DVB-T-USB
+         silicon. This chip can be found in devices offered by Hauppauge,
+         Avermedia and other big and small companies.
+
+         For an up-to-date list of devices supported by this driver, have a look
+         on the LinuxTV Wiki at www.linuxtv.org.
+
+         Say Y if you own such a device and want to use it. You should build it as
+         a module.
+
+config DVB_USB_UMT_010
+       tristate "HanfTek UMT-010 DVB-T USB2.0 support"
+       depends on DVB_USB
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_DIB3000MC
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
+
+config DVB_USB_CXUSB
+       tristate "Conexant USB2.0 hybrid reference design support"
+       depends on DVB_USB
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_CX22702 if !DVB_FE_CUSTOMISE
+       select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+       select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
+       select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Conexant USB2.0 hybrid reference design.
+         Currently, only DVB and ATSC modes are supported, analog mode
+         shall be added in the future. Devices that require this module:
+
+         Medion MD95700 hybrid USB2.0 device.
+         DViCO FusionHDTV (Bluebird) USB2.0 devices
+
+config DVB_USB_M920X
+       tristate "Uli m920x DVB-T USB2.0 support"
+       depends on DVB_USB
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
+         Currently, only devices with a product id of
+         "DTV USB MINI" (in cold state) are supported.
+         Firmware required.
+
+config DVB_USB_DIGITV
+       tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
+       depends on DVB_USB
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_NXT6000 if !DVB_FE_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
+
+config DVB_USB_VP7045
+       tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
+       depends on DVB_USB
+       help
+         Say Y here to support the
+
+           TwinhanDTV Alpha (stick) (VP-7045),
+               TwinhanDTV MagicBox II (VP-7046),
+               DigitalNow TinyUSB 2 DVB-t,
+               DigitalRise USB 2.0 Ter (Beetle) and
+               TYPHOON DVB-T USB DRIVE
+
+         DVB-T USB2.0 receivers.
+
+config DVB_USB_VP702X
+       tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
+       depends on DVB_USB
+       help
+         Say Y here to support the
+
+           TwinhanDTV StarBox,
+               DigitalRise USB Starbox and
+               TYPHOON DVB-S USB 2.0 BOX
+
+         DVB-S USB2.0 receivers.
+
+config DVB_USB_GP8PSK
+       tristate "GENPIX 8PSK->USB module support"
+       depends on DVB_USB
+       help
+         Say Y here to support the
+           GENPIX 8psk module
+
+         DVB-S USB2.0 receivers.
+
+config DVB_USB_NOVA_T_USB2
+       tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
+       depends on DVB_USB
+       select DVB_DIB3000MC
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
+
+config DVB_USB_TTUSB2
+       tristate "Pinnacle 400e DVB-S USB2.0 support"
+       depends on DVB_USB
+       select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select DVB_TDA826X if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
+         firmware protocol used by this module is similar to the one used by the
+         old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
+
+config DVB_USB_DTT200U
+       tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
+       depends on DVB_USB
+       help
+         Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
+
+         The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
+
+         The WT-220U and its clones are pen-sized.
+
+config DVB_USB_OPERA1
+       tristate "Opera1 DVB-S USB2.0 receiver"
+       depends on DVB_USB
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Opera DVB-S USB2.0 receiver.
+
+config DVB_USB_AF9005
+       tristate "Afatech AF9005 DVB-T USB1.1 support"
+       depends on DVB_USB && EXPERIMENTAL
+       select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
+         and the TerraTec Cinergy T USB XE (Rev.1)
+
+config DVB_USB_AF9005_REMOTE
+       tristate "Afatech AF9005 default remote control support"
+       depends on DVB_USB_AF9005
+       help
+         Say Y here to support the default remote control decoding for the
+         Afatech AF9005 based receiver.
+
+config DVB_USB_PCTV452E
+       tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
+       depends on DVB_USB
+       select TTPCI_EEPROM
+       select DVB_LNBP22 if !DVB_FE_CUSTOMISE
+       select DVB_STB0899 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       help
+         Support for external USB adapter designed by Pinnacle,
+         shipped under the brand name 'PCTV HDTV Pro USB'.
+         Also supports TT Connect S2-3600/3650 cards.
+         Say Y if you own such a device and want to use it.
+
+config DVB_USB_DW2102
+       tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
+       depends on DVB_USB
+       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_TDA10023 if !DVB_FE_CUSTOMISE
+       select DVB_MT312 if !DVB_FE_CUSTOMISE
+       select DVB_ZL10039 if !DVB_FE_CUSTOMISE
+       select DVB_DS3000 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110 if !DVB_FE_CUSTOMISE
+       select DVB_STV0900 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
+         receivers.
+
+config DVB_USB_CINERGY_T2
+       tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
+       depends on DVB_USB
+       help
+         Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
+
+         Say Y if you own such a device and want to use it.
+
+config DVB_USB_DTV5100
+       tristate "AME DTV-5100 USB2.0 DVB-T support"
+       depends on DVB_USB
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
+
+config DVB_USB_FRIIO
+       tristate "Friio ISDB-T USB2.0 Receiver support"
+       depends on DVB_USB
+       help
+         Say Y here to support the Japanese DTV receiver Friio.
+
+config DVB_USB_AZ6027
+       tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
+       depends on DVB_USB
+       select DVB_STB0899 if !DVB_FE_CUSTOMISE
+       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the AZ6027 device
+
+config DVB_USB_TECHNISAT_USB2
+       tristate "Technisat DVB-S/S2 USB2.0 support"
+       depends on DVB_USB
+       select DVB_STV090x if !DVB_FE_CUSTOMISE
+       select DVB_STV6110x if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
new file mode 100644 (file)
index 0000000..a5630e3
--- /dev/null
@@ -0,0 +1,82 @@
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
+obj-$(CONFIG_DVB_USB) += dvb-usb.o
+
+dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
+obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+
+dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
+obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
+
+dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
+obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
+
+dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
+obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
+
+dvb-usb-dibusb-common-objs = dibusb-common.o
+
+dvb-usb-a800-objs = a800.o
+obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
+
+dvb-usb-dibusb-mb-objs = dibusb-mb.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
+
+dvb-usb-dibusb-mc-objs = dibusb-mc.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
+
+dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
+obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
+
+dvb-usb-umt-010-objs = umt-010.o
+obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
+
+dvb-usb-m920x-objs = m920x.o
+obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
+
+dvb-usb-digitv-objs = digitv.o
+obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
+
+dvb-usb-cxusb-objs = cxusb.o
+obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
+
+dvb-usb-ttusb2-objs = ttusb2.o
+obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
+
+dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
+obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+
+dvb-usb-opera-objs = opera1.o
+obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
+
+dvb-usb-af9005-objs = af9005.o af9005-fe.o
+obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
+
+dvb-usb-af9005-remote-objs = af9005-remote.o
+obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
+
+dvb-usb-pctv452e-objs = pctv452e.o
+obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
+
+dvb-usb-dw2102-objs = dw2102.o
+obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
+
+dvb-usb-dtv5100-objs = dtv5100.o
+obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
+
+dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
+obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
+
+dvb-usb-friio-objs = friio.o friio-fe.o
+obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
+
+dvb-usb-az6027-objs = az6027.o
+obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
+
+dvb-usb-technisat-usb2-objs = technisat-usb2.o
+obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
+
+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
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
new file mode 100644 (file)
index 0000000..8d7fef8
--- /dev/null
@@ -0,0 +1,191 @@
+/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
+ * USB2.0 (A800) DVB-T receiver.
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to
+ *   - AVerMedia who kindly provided information and
+ *   - Glen Harris who suffered from my mistakes during development.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_rc(args...)   dprintk(debug,0x01,args)
+
+static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       /* do nothing for the AVerMedia */
+       return 0;
+}
+
+/* assure to put cold to 0 for iManufacturer == 1 */
+static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+       struct dvb_usb_device_description **desc, int *cold)
+{
+       *cold = udev->descriptor.iManufacturer != 1;
+       return 0;
+}
+
+static struct rc_map_table rc_map_a800_table[] = {
+       { 0x0201, KEY_MODE },      /* SOURCE */
+       { 0x0200, KEY_POWER2 },      /* POWER */
+       { 0x0205, KEY_1 },           /* 1 */
+       { 0x0206, KEY_2 },           /* 2 */
+       { 0x0207, KEY_3 },           /* 3 */
+       { 0x0209, KEY_4 },           /* 4 */
+       { 0x020a, KEY_5 },           /* 5 */
+       { 0x020b, KEY_6 },           /* 6 */
+       { 0x020d, KEY_7 },           /* 7 */
+       { 0x020e, KEY_8 },           /* 8 */
+       { 0x020f, KEY_9 },           /* 9 */
+       { 0x0212, KEY_LEFT },        /* L / DISPLAY */
+       { 0x0211, KEY_0 },           /* 0 */
+       { 0x0213, KEY_RIGHT },       /* R / CH RTN */
+       { 0x0217, KEY_CAMERA },      /* SNAP SHOT */
+       { 0x0210, KEY_LAST },        /* 16-CH PREV */
+       { 0x021e, KEY_VOLUMEDOWN },  /* VOL DOWN */
+       { 0x020c, KEY_ZOOM },        /* FULL SCREEN */
+       { 0x021f, KEY_VOLUMEUP },    /* VOL UP */
+       { 0x0214, KEY_MUTE },        /* MUTE */
+       { 0x0208, KEY_AUDIO },       /* AUDIO */
+       { 0x0219, KEY_RECORD },      /* RECORD */
+       { 0x0218, KEY_PLAY },        /* PLAY */
+       { 0x021b, KEY_STOP },        /* STOP */
+       { 0x021a, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
+       { 0x021d, KEY_BACK },        /* << / RED */
+       { 0x021c, KEY_FORWARD },     /* >> / YELLOW */
+       { 0x0203, KEY_TEXT },        /* TELETEXT */
+       { 0x0204, KEY_EPG },         /* EPG */
+       { 0x0215, KEY_MENU },        /* MENU */
+
+       { 0x0303, KEY_CHANNELUP },   /* CH UP */
+       { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
+       { 0x0301, KEY_FIRST },       /* |<< / GREEN */
+       { 0x0300, KEY_LAST },        /* >>| / BLUE */
+
+};
+
+static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       int ret;
+       u8 *key = kmalloc(5, GFP_KERNEL);
+       if (!key)
+               return -ENOMEM;
+
+       if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
+                               0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
+                               2000) != 5) {
+               ret = -ENODEV;
+               goto out;
+       }
+
+       /* call the universal NEC remote processor, to find out the key's state and event */
+       dvb_usb_nec_rc_key_to_event(d,key,event,state);
+       if (key[0] != 0)
+               deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+       ret = 0;
+out:
+       kfree(key);
+       return ret;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_device_properties a800_properties;
+
+static int a800_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &a800_properties,
+                                  THIS_MODULE, NULL, adapter_nr);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id a800_table [] = {
+/* 00 */       { USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
+/* 01 */       { USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
+                       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, a800_table);
+
+static struct dvb_usb_device_properties a800_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-avertv-a800-02.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+
+                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
+                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                                       .stream = {
+                                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               },
+       },
+
+       .power_ctrl       = a800_power_ctrl,
+       .identify_state   = a800_identify_state,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_a800_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_a800_table),
+               .rc_query         = a800_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+       .num_device_descs = 1,
+       .devices = {
+               {   "AVerMedia AverTV DVB-T USB 2.0 (A800)",
+                       { &a800_table[0], NULL },
+                       { &a800_table[1], NULL },
+               },
+       }
+};
+
+static struct usb_driver a800_driver = {
+       .name           = "dvb_usb_a800",
+       .probe          = a800_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = a800_table,
+};
+
+module_usb_driver(a800_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
new file mode 100644 (file)
index 0000000..740f3f4
--- /dev/null
@@ -0,0 +1,1487 @@
+/* Frontend part of the Linux driver for the Afatech 9005
+ * USB1.1 DVB-T receiver.
+ *
+ * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ * 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "af9005.h"
+#include "af9005-script.h"
+#include "mt2060.h"
+#include "qt1010.h"
+#include <asm/div64.h>
+
+struct af9005_fe_state {
+       struct dvb_usb_device *d;
+       fe_status_t stat;
+
+       /* retraining parameters */
+       u32 original_fcw;
+       u16 original_rf_top;
+       u16 original_if_top;
+       u16 original_if_min;
+       u16 original_aci0_if_top;
+       u16 original_aci1_if_top;
+       u16 original_aci0_if_min;
+       u8 original_if_unplug_th;
+       u8 original_rf_unplug_th;
+       u8 original_dtop_if_unplug_th;
+       u8 original_dtop_rf_unplug_th;
+
+       /* statistics */
+       u32 pre_vit_error_count;
+       u32 pre_vit_bit_count;
+       u32 ber;
+       u32 post_vit_error_count;
+       u32 post_vit_bit_count;
+       u32 unc;
+       u16 abort_count;
+
+       int opened;
+       int strong;
+       unsigned long next_status_check;
+       struct dvb_frontend frontend;
+};
+
+static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi,
+                                u16 reglo, u8 pos, u8 len, u16 value)
+{
+       int ret;
+
+       if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))
+               return ret;
+       return af9005_write_register_bits(d, reghi, pos, len,
+                                         (u8) ((value & 0x300) >> 8));
+}
+
+static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,
+                               u16 reglo, u8 pos, u8 len, u16 * value)
+{
+       int ret;
+       u8 temp0, temp1;
+
+       if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))
+               return ret;
+       if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))
+               return ret;
+       switch (pos) {
+       case 0:
+               *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;
+               break;
+       case 2:
+               *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;
+               break;
+       case 4:
+               *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;
+               break;
+       case 6:
+               *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;
+               break;
+       default:
+               err("invalid pos in read word agc");
+               return -EINVAL;
+       }
+       return 0;
+
+}
+
+static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 temp;
+
+       *available = false;
+
+       ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
+                                       fec_vtb_rsd_mon_en_pos,
+                                       fec_vtb_rsd_mon_en_len, &temp);
+       if (ret)
+               return ret;
+       if (temp & 1) {
+               ret =
+                   af9005_read_register_bits(state->d,
+                                             xd_p_reg_ofsm_read_rbc_en,
+                                             reg_ofsm_read_rbc_en_pos,
+                                             reg_ofsm_read_rbc_en_len, &temp);
+               if (ret)
+                       return ret;
+               if ((temp & 1) == 0)
+                       *available = true;
+
+       }
+       return 0;
+}
+
+static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,
+                                           u32 * post_err_count,
+                                           u32 * post_cw_count,
+                                           u16 * abort_count)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u32 err_count;
+       u32 cw_count;
+       u8 temp, temp0, temp1, temp2;
+       u16 loc_abort_count;
+
+       *post_err_count = 0;
+       *post_cw_count = 0;
+
+       /* check if error bit count is ready */
+       ret =
+           af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,
+                                     fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       if (!temp) {
+               deb_info("rsd counter not ready\n");
+               return 100;
+       }
+       /* get abort count */
+       ret =
+           af9005_read_ofdm_register(state->d,
+                                     xd_r_fec_rsd_abort_packet_cnt_7_0,
+                                     &temp0);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d,
+                                     xd_r_fec_rsd_abort_packet_cnt_15_8,
+                                     &temp1);
+       if (ret)
+               return ret;
+       loc_abort_count = ((u16) temp1 << 8) + temp0;
+
+       /* get error count */
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,
+                                     &temp0);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,
+                                     &temp1);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,
+                                     &temp2);
+       if (ret)
+               return ret;
+       err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
+       *post_err_count = err_count - (u32) loc_abort_count *8 * 8;
+
+       /* get RSD packet number */
+       ret =
+           af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
+                                     &temp0);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
+                                     &temp1);
+       if (ret)
+               return ret;
+       cw_count = ((u32) temp1 << 8) + temp0;
+       if (cw_count == 0) {
+               err("wrong RSD packet count");
+               return -EIO;
+       }
+       deb_info("POST abort count %d err count %d rsd packets %d\n",
+                loc_abort_count, err_count, cw_count);
+       *post_cw_count = cw_count - (u32) loc_abort_count;
+       *abort_count = loc_abort_count;
+       return 0;
+
+}
+
+static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
+                                  u32 * post_err_count, u32 * post_cw_count,
+                                  u16 * abort_count)
+{
+       u32 loc_cw_count = 0, loc_err_count;
+       u16 loc_abort_count = 0;
+       int ret;
+
+       ret =
+           af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,
+                                            &loc_abort_count);
+       if (ret)
+               return ret;
+       *post_err_count = loc_err_count;
+       *post_cw_count = loc_cw_count * 204 * 8;
+       *abort_count = loc_abort_count;
+
+       return 0;
+}
+
+static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,
+                                           u32 * pre_err_count,
+                                           u32 * pre_bit_count)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       u8 temp, temp0, temp1, temp2;
+       u32 super_frame_count, x, bits;
+       int ret;
+
+       ret =
+           af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,
+                                     fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       if (!temp) {
+               deb_info("viterbi counter not ready\n");
+               return 101;     /* ERR_APO_VTB_COUNTER_NOT_READY; */
+       }
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,
+                                     &temp0);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,
+                                     &temp1);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,
+                                     &temp2);
+       if (ret)
+               return ret;
+       *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
+
+       ret =
+           af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
+                                     &temp0);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
+                                     &temp1);
+       if (ret)
+               return ret;
+       super_frame_count = ((u32) temp1 << 8) + temp0;
+       if (super_frame_count == 0) {
+               deb_info("super frame count 0\n");
+               return 102;
+       }
+
+       /* read fft mode */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
+                                     reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       if (temp == 0) {
+               /* 2K */
+               x = 1512;
+       } else if (temp == 1) {
+               /* 8k */
+               x = 6048;
+       } else {
+               err("Invalid fft mode");
+               return -EINVAL;
+       }
+
+       /* read modulation mode */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
+                                     reg_tpsd_const_pos, reg_tpsd_const_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       switch (temp) {
+       case 0:         /* QPSK */
+               bits = 2;
+               break;
+       case 1:         /* QAM_16 */
+               bits = 4;
+               break;
+       case 2:         /* QAM_64 */
+               bits = 6;
+               break;
+       default:
+               err("invalid modulation mode");
+               return -EINVAL;
+       }
+       *pre_bit_count = super_frame_count * 68 * 4 * x * bits;
+       deb_info("PRE err count %d frame count %d bit count %d\n",
+                *pre_err_count, super_frame_count, *pre_bit_count);
+       return 0;
+}
+
+static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+
+       /* set super frame count to 1 */
+       ret =
+           af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
+                                      1 & 0xff);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
+                                        1 >> 8);
+       if (ret)
+               return ret;
+       /* reset pre viterbi error count */
+       ret =
+           af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,
+                                      fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,
+                                      1);
+
+       return ret;
+}
+
+static int af9005_reset_post_viterbi(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+
+       /* set packet unit */
+       ret =
+           af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
+                                      10000 & 0xff);
+       if (ret)
+               return ret;
+       ret =
+           af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
+                                      10000 >> 8);
+       if (ret)
+               return ret;
+       /* reset post viterbi error count */
+       ret =
+           af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,
+                                      fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,
+                                      1);
+
+       return ret;
+}
+
+static int af9005_get_statistic(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret, fecavailable;
+       u64 numerator, denominator;
+
+       deb_info("GET STATISTIC\n");
+       ret = af9005_is_fecmon_available(fe, &fecavailable);
+       if (ret)
+               return ret;
+       if (!fecavailable) {
+               deb_info("fecmon not available\n");
+               return 0;
+       }
+
+       ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,
+                                              &state->pre_vit_bit_count);
+       if (ret == 0) {
+               af9005_reset_pre_viterbi(fe);
+               if (state->pre_vit_bit_count > 0) {
+                       /* according to v 0.0.4 of the dvb api ber should be a multiple
+                          of 10E-9 so we have to multiply the error count by
+                          10E9=1000000000 */
+                       numerator =
+                           (u64) state->pre_vit_error_count * (u64) 1000000000;
+                       denominator = (u64) state->pre_vit_bit_count;
+                       state->ber = do_div(numerator, denominator);
+               } else {
+                       state->ber = 0xffffffff;
+               }
+       }
+
+       ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,
+                                     &state->post_vit_bit_count,
+                                     &state->abort_count);
+       if (ret == 0) {
+               ret = af9005_reset_post_viterbi(fe);
+               state->unc += state->abort_count;
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
+static int af9005_fe_refresh_state(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       if (time_after(jiffies, state->next_status_check)) {
+               deb_info("REFRESH STATE\n");
+
+               /* statistics */
+               if (af9005_get_statistic(fe))
+                       err("get_statistic_failed");
+               state->next_status_check = jiffies + 250 * HZ / 1000;
+       }
+       return 0;
+}
+
+static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       u8 temp;
+       int ret;
+
+       if (fe->ops.tuner_ops.release == NULL)
+               return -ENODEV;
+
+       *stat = 0;
+       ret = af9005_read_register_bits(state->d, xd_p_agc_lock,
+                                       agc_lock_pos, agc_lock_len, &temp);
+       if (ret)
+               return ret;
+       if (temp)
+               *stat |= FE_HAS_SIGNAL;
+
+       ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,
+                                       fd_tpsd_lock_pos, fd_tpsd_lock_len,
+                                       &temp);
+       if (ret)
+               return ret;
+       if (temp)
+               *stat |= FE_HAS_CARRIER;
+
+       ret = af9005_read_register_bits(state->d,
+                                       xd_r_mp2if_sync_byte_locked,
+                                       mp2if_sync_byte_locked_pos,
+                                       mp2if_sync_byte_locked_pos, &temp);
+       if (ret)
+               return ret;
+       if (temp)
+               *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
+       if (state->opened)
+               af9005_led_control(state->d, *stat & FE_HAS_LOCK);
+
+       ret =
+           af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,
+                                     reg_strong_sginal_detected_pos,
+                                     reg_strong_sginal_detected_len, &temp);
+       if (ret)
+               return ret;
+       if (temp != state->strong) {
+               deb_info("adjust for strong signal %d\n", temp);
+                       state->strong = temp;
+       }
+       return 0;
+}
+
+static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       if (fe->ops.tuner_ops.release  == NULL)
+               return -ENODEV;
+       af9005_fe_refresh_state(fe);
+       *ber = state->ber;
+       return 0;
+}
+
+static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       if (fe->ops.tuner_ops.release == NULL)
+               return -ENODEV;
+       af9005_fe_refresh_state(fe);
+       *unc = state->unc;
+       return 0;
+}
+
+static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
+                                         u16 * strength)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 if_gain, rf_gain;
+
+       if (fe->ops.tuner_ops.release == NULL)
+               return -ENODEV;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
+                                     &rf_gain);
+       if (ret)
+               return ret;
+       ret =
+           af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,
+                                     &if_gain);
+       if (ret)
+               return ret;
+       /* this value has no real meaning, but i don't have the tables that relate
+          the rf and if gain with the dbm, so I just scale the value */
+       *strength = (512 - rf_gain - if_gain) << 7;
+       return 0;
+}
+
+static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       /* the snr can be derived from the ber and the modulation
+          but I don't think this kind of complex calculations belong
+          in the driver. I may be wrong.... */
+       return -ENOSYS;
+}
+
+static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw)
+{
+       u8 temp0, temp1, temp2, temp3, buf[4];
+       int ret;
+       u32 NS_coeff1_2048Nu;
+       u32 NS_coeff1_8191Nu;
+       u32 NS_coeff1_8192Nu;
+       u32 NS_coeff1_8193Nu;
+       u32 NS_coeff2_2k;
+       u32 NS_coeff2_8k;
+
+       switch (bw) {
+       case 6000000:
+               NS_coeff1_2048Nu = 0x2ADB6DC;
+               NS_coeff1_8191Nu = 0xAB7313;
+               NS_coeff1_8192Nu = 0xAB6DB7;
+               NS_coeff1_8193Nu = 0xAB685C;
+               NS_coeff2_2k = 0x156DB6E;
+               NS_coeff2_8k = 0x55B6DC;
+               break;
+
+       case 7000000:
+               NS_coeff1_2048Nu = 0x3200001;
+               NS_coeff1_8191Nu = 0xC80640;
+               NS_coeff1_8192Nu = 0xC80000;
+               NS_coeff1_8193Nu = 0xC7F9C0;
+               NS_coeff2_2k = 0x1900000;
+               NS_coeff2_8k = 0x640000;
+               break;
+
+       case 8000000:
+               NS_coeff1_2048Nu = 0x3924926;
+               NS_coeff1_8191Nu = 0xE4996E;
+               NS_coeff1_8192Nu = 0xE49249;
+               NS_coeff1_8193Nu = 0xE48B25;
+               NS_coeff2_2k = 0x1C92493;
+               NS_coeff2_8k = 0x724925;
+               break;
+       default:
+               err("Invalid bandwidth %d.", bw);
+               return -EINVAL;
+       }
+
+       /*
+        *  write NS_coeff1_2048Nu
+        */
+
+       temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);
+       temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);
+       temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);
+       temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       /*  cfoe_NS_2k_coeff1_25_24 */
+       ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);
+       if (ret)
+               return ret;
+
+       /*  cfoe_NS_2k_coeff1_23_16 */
+       ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);
+       if (ret)
+               return ret;
+
+       /*  cfoe_NS_2k_coeff1_15_8 */
+       ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);
+       if (ret)
+               return ret;
+
+       /*  cfoe_NS_2k_coeff1_7_0 */
+       ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);
+       if (ret)
+               return ret;
+
+       /*
+        *  write NS_coeff2_2k
+        */
+
+       temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));
+       temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);
+       temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);
+       temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);
+       if (ret)
+               return ret;
+
+       /*
+        *  write NS_coeff1_8191Nu
+        */
+
+       temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));
+       temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);
+       temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);
+       temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);
+       if (ret)
+               return ret;
+
+       /*
+        *  write NS_coeff1_8192Nu
+        */
+
+       temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);
+       temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);
+       temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);
+       temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);
+       if (ret)
+               return ret;
+
+       /*
+        *  write NS_coeff1_8193Nu
+        */
+
+       temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));
+       temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);
+       temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);
+       temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);
+       if (ret)
+               return ret;
+
+       /*
+        *  write NS_coeff2_8k
+        */
+
+       temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));
+       temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);
+       temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);
+       temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);
+
+       /*  big endian to make 8051 happy */
+       buf[0] = temp3;
+       buf[1] = temp2;
+       buf[2] = temp1;
+       buf[3] = temp0;
+
+       ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);
+       if (ret)
+               return ret;
+
+       ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);
+       return ret;
+
+}
+
+static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw)
+{
+       u8 temp;
+       switch (bw) {
+       case 6000000:
+               temp = 0;
+               break;
+       case 7000000:
+               temp = 1;
+               break;
+       case 8000000:
+               temp = 2;
+               break;
+       default:
+               err("Invalid bandwidth %d.", bw);
+               return -EINVAL;
+       }
+       return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,
+                                         reg_bw_len, temp);
+}
+
+static int af9005_fe_power(struct dvb_frontend *fe, int on)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       u8 temp = on;
+       int ret;
+       deb_info("power %s tuner\n", on ? "on" : "off");
+       ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
+       return ret;
+}
+
+static struct mt2060_config af9005_mt2060_config = {
+       0xC0
+};
+
+static struct qt1010_config af9005_qt1010_config = {
+       0xC4
+};
+
+static int af9005_fe_init(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       int ret, i, scriptlen;
+       u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
+       u8 buf[2];
+       u16 if1;
+
+       deb_info("in af9005_fe_init\n");
+
+       /* reset */
+       deb_info("reset\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,
+                                       4, 1, 0x01)))
+               return ret;
+       if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))
+               return ret;
+       /* clear ofdm reset */
+       deb_info("clear ofdm reset\n");
+       for (i = 0; i < 150; i++) {
+               if ((ret =
+                    af9005_read_ofdm_register(state->d,
+                                              xd_I2C_reg_ofdm_rst, &temp)))
+                       return ret;
+               if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))
+                       break;
+               msleep(10);
+       }
+       if (i == 150)
+               return -ETIMEDOUT;
+
+       /*FIXME in the dump
+          write B200 A9
+          write xd_g_reg_ofsm_clk 7
+          read eepr c6 (2)
+          read eepr c7 (2)
+          misc ctrl 3 -> 1
+          read eepr ca (6)
+          write xd_g_reg_ofsm_clk 0
+          write B200 a1
+        */
+       ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);
+       if (ret)
+               return ret;
+       temp = 0x01;
+       ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);
+       if (ret)
+               return ret;
+
+       temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
+                                       reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
+               return ret;
+       ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
+                                        reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
+
+       if (ret)
+               return ret;
+       /* don't know what register aefc is, but this is what the windows driver does */
+       ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);
+       if (ret)
+               return ret;
+
+       /* set stand alone chip */
+       deb_info("set stand alone chip\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,
+                                       reg_dca_stand_alone_pos,
+                                       reg_dca_stand_alone_len, 1)))
+               return ret;
+
+       /* set dca upper & lower chip */
+       deb_info("set dca upper & lower chip\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,
+                                       reg_dca_upper_chip_pos,
+                                       reg_dca_upper_chip_len, 0)))
+               return ret;
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,
+                                       reg_dca_lower_chip_pos,
+                                       reg_dca_lower_chip_len, 0)))
+               return ret;
+
+       /* set 2wire master clock to 0x14 (for 60KHz) */
+       deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");
+       if ((ret =
+            af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))
+               return ret;
+
+       /* clear dca enable chip */
+       deb_info("clear dca enable chip\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_dca_en,
+                                       reg_dca_en_pos, reg_dca_en_len, 0)))
+               return ret;
+       /* FIXME these are register bits, but I don't know which ones */
+       ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);
+       if (ret)
+               return ret;
+
+       /* init other parameters: program cfoe and select bandwidth */
+       deb_info("program cfoe\n");
+       ret = af9005_fe_program_cfoe(state->d, 6000000);
+       if (ret)
+               return ret;
+       /* set read-update bit for modulation */
+       deb_info("set read-update bit for modulation\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,
+                                       reg_feq_read_update_pos,
+                                       reg_feq_read_update_len, 1)))
+               return ret;
+
+       /* sample code has a set MPEG TS code here
+          but sniffing reveals that it doesn't do it */
+
+       /* set read-update bit to 1 for DCA modulation */
+       deb_info("set read-update bit 1 for DCA modulation\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,
+                                       reg_dca_read_update_pos,
+                                       reg_dca_read_update_len, 1)))
+               return ret;
+
+       /* enable fec monitor */
+       deb_info("enable fec monitor\n");
+       if ((ret =
+            af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
+                                       fec_vtb_rsd_mon_en_pos,
+                                       fec_vtb_rsd_mon_en_len, 1)))
+               return ret;
+
+       /* FIXME should be register bits, I don't know which ones */
+       ret = af9005_write_ofdm_register(state->d, 0xa601, 0);
+
+       /* set api_retrain_never_freeze */
+       deb_info("set api_retrain_never_freeze\n");
+       if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
+               return ret;
+
+       /* load init script */
+       deb_info("load init script\n");
+       scriptlen = sizeof(script) / sizeof(RegDesc);
+       for (i = 0; i < scriptlen; i++) {
+               if ((ret =
+                    af9005_write_register_bits(state->d, script[i].reg,
+                                               script[i].pos,
+                                               script[i].len, script[i].val)))
+                       return ret;
+               /* save 3 bytes of original fcw */
+               if (script[i].reg == 0xae18)
+                       temp2 = script[i].val;
+               if (script[i].reg == 0xae19)
+                       temp1 = script[i].val;
+               if (script[i].reg == 0xae1a)
+                       temp0 = script[i].val;
+
+               /* save original unplug threshold */
+               if (script[i].reg == xd_p_reg_unplug_th)
+                       state->original_if_unplug_th = script[i].val;
+               if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
+                       state->original_rf_unplug_th = script[i].val;
+               if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
+                       state->original_dtop_if_unplug_th = script[i].val;
+               if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
+                       state->original_dtop_rf_unplug_th = script[i].val;
+
+       }
+       state->original_fcw =
+           ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
+
+
+       /* save original TOPs */
+       deb_info("save original TOPs\n");
+
+       /*  RF TOP */
+       ret =
+           af9005_read_word_agc(state->d,
+                                xd_p_reg_aagc_rf_top_numerator_9_8,
+                                xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
+                                &state->original_rf_top);
+       if (ret)
+               return ret;
+
+       /*  IF TOP */
+       ret =
+           af9005_read_word_agc(state->d,
+                                xd_p_reg_aagc_if_top_numerator_9_8,
+                                xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
+                                &state->original_if_top);
+       if (ret)
+               return ret;
+
+       /*  ACI 0 IF TOP */
+       ret =
+           af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
+                                &state->original_aci0_if_top);
+       if (ret)
+               return ret;
+
+       /*  ACI 1 IF TOP */
+       ret =
+           af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
+                                &state->original_aci1_if_top);
+       if (ret)
+               return ret;
+
+       /* attach tuner and init */
+       if (fe->ops.tuner_ops.release == NULL) {
+               /* read tuner and board id from eeprom */
+               ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
+               if (ret) {
+                       err("Impossible to read EEPROM\n");
+                       return ret;
+               }
+               deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);
+               switch (buf[0]) {
+               case 2: /* MT2060 */
+                       /* read if1 from eeprom */
+                       ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);
+                       if (ret) {
+                               err("Impossible to read EEPROM\n");
+                               return ret;
+                       }
+                       if1 = (u16) (buf[0] << 8) + buf[1];
+                       if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
+                                        &af9005_mt2060_config, if1) == NULL) {
+                               deb_info("MT2060 attach failed\n");
+                               return -ENODEV;
+                       }
+                       break;
+               case 3: /* QT1010 */
+               case 9: /* QT1010B */
+                       if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
+                                       &af9005_qt1010_config) ==NULL) {
+                               deb_info("QT1010 attach failed\n");
+                               return -ENODEV;
+                       }
+                       break;
+               default:
+                       err("Unsupported tuner type %d", buf[0]);
+                       return -ENODEV;
+               }
+               ret = fe->ops.tuner_ops.init(fe);
+               if (ret)
+                       return ret;
+       }
+
+       deb_info("profit!\n");
+       return 0;
+}
+
+static int af9005_fe_sleep(struct dvb_frontend *fe)
+{
+       return af9005_fe_power(fe, 0);
+}
+
+static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+       struct af9005_fe_state *state = fe->demodulator_priv;
+
+       if (acquire) {
+               state->opened++;
+       } else {
+
+               state->opened--;
+               if (!state->opened)
+                       af9005_led_control(state->d, 0);
+       }
+       return 0;
+}
+
+static int af9005_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 temp, temp0, temp1, temp2;
+
+       deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
+                fep->bandwidth_hz);
+       if (fe->ops.tuner_ops.release == NULL) {
+               err("Tuner not attached");
+               return -ENODEV;
+       }
+
+       deb_info("turn off led\n");
+       /* not in the log */
+       ret = af9005_led_control(state->d, 0);
+       if (ret)
+               return ret;
+       /* not sure about the bits */
+       ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);
+       if (ret)
+               return ret;
+
+       /* set FCW to default value */
+       deb_info("set FCW to default value\n");
+       temp0 = (u8) (state->original_fcw & 0x000000ff);
+       temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);
+       temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);
+       ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);
+       if (ret)
+               return ret;
+       ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);
+       if (ret)
+               return ret;
+
+       /* restore original TOPs */
+       deb_info("restore original TOPs\n");
+       ret =
+           af9005_write_word_agc(state->d,
+                                 xd_p_reg_aagc_rf_top_numerator_9_8,
+                                 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
+                                 state->original_rf_top);
+       if (ret)
+               return ret;
+       ret =
+           af9005_write_word_agc(state->d,
+                                 xd_p_reg_aagc_if_top_numerator_9_8,
+                                 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
+                                 state->original_if_top);
+       if (ret)
+               return ret;
+       ret =
+           af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
+                                 state->original_aci0_if_top);
+       if (ret)
+               return ret;
+       ret =
+           af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
+                                 state->original_aci1_if_top);
+       if (ret)
+               return ret;
+
+       /* select bandwidth */
+       deb_info("select bandwidth");
+       ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz);
+       if (ret)
+               return ret;
+       ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz);
+       if (ret)
+               return ret;
+
+       /* clear easy mode flag */
+       deb_info("clear easy mode flag\n");
+       ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);
+       if (ret)
+               return ret;
+
+       /* set unplug threshold to original value */
+       deb_info("set unplug threshold to original value\n");
+       ret =
+           af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,
+                                      state->original_if_unplug_th);
+       if (ret)
+               return ret;
+       /* set tuner */
+       deb_info("set tuner\n");
+       ret = fe->ops.tuner_ops.set_params(fe);
+       if (ret)
+               return ret;
+
+       /* trigger ofsm */
+       deb_info("trigger ofsm\n");
+       temp = 0;
+       ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);
+       if (ret)
+               return ret;
+
+       /* clear retrain and freeze flag */
+       deb_info("clear retrain and freeze flag\n");
+       ret =
+           af9005_write_register_bits(state->d,
+                                      xd_p_reg_api_retrain_request,
+                                      reg_api_retrain_request_pos, 2, 0);
+       if (ret)
+               return ret;
+
+       /* reset pre viterbi and post viterbi registers and statistics */
+       af9005_reset_pre_viterbi(fe);
+       af9005_reset_post_viterbi(fe);
+       state->pre_vit_error_count = 0;
+       state->pre_vit_bit_count = 0;
+       state->ber = 0;
+       state->post_vit_error_count = 0;
+       /* state->unc = 0; commented out since it should be ever increasing */
+       state->abort_count = 0;
+
+       state->next_status_check = jiffies;
+       state->strong = -1;
+
+       return 0;
+}
+
+static int af9005_fe_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct af9005_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 temp;
+
+       /* mode */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
+                                     reg_tpsd_const_pos, reg_tpsd_const_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       deb_info("===== fe_get_frontend_legacy = =============\n");
+       deb_info("CONSTELLATION ");
+       switch (temp) {
+       case 0:
+               fep->modulation = QPSK;
+               deb_info("QPSK\n");
+               break;
+       case 1:
+               fep->modulation = QAM_16;
+               deb_info("QAM_16\n");
+               break;
+       case 2:
+               fep->modulation = QAM_64;
+               deb_info("QAM_64\n");
+               break;
+       }
+
+       /* tps hierarchy and alpha value */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,
+                                     reg_tpsd_hier_pos, reg_tpsd_hier_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       deb_info("HIERARCHY ");
+       switch (temp) {
+       case 0:
+               fep->hierarchy = HIERARCHY_NONE;
+               deb_info("NONE\n");
+               break;
+       case 1:
+               fep->hierarchy = HIERARCHY_1;
+               deb_info("1\n");
+               break;
+       case 2:
+               fep->hierarchy = HIERARCHY_2;
+               deb_info("2\n");
+               break;
+       case 3:
+               fep->hierarchy = HIERARCHY_4;
+               deb_info("4\n");
+               break;
+       }
+
+       /*  high/low priority     */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_dec_pri,
+                                     reg_dec_pri_pos, reg_dec_pri_len, &temp);
+       if (ret)
+               return ret;
+       /* if temp is set = high priority */
+       deb_info("PRIORITY %s\n", temp ? "high" : "low");
+
+       /* high coderate */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,
+                                     reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       deb_info("CODERATE HP ");
+       switch (temp) {
+       case 0:
+               fep->code_rate_HP = FEC_1_2;
+               deb_info("FEC_1_2\n");
+               break;
+       case 1:
+               fep->code_rate_HP = FEC_2_3;
+               deb_info("FEC_2_3\n");
+               break;
+       case 2:
+               fep->code_rate_HP = FEC_3_4;
+               deb_info("FEC_3_4\n");
+               break;
+       case 3:
+               fep->code_rate_HP = FEC_5_6;
+               deb_info("FEC_5_6\n");
+               break;
+       case 4:
+               fep->code_rate_HP = FEC_7_8;
+               deb_info("FEC_7_8\n");
+               break;
+       }
+
+       /* low coderate */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,
+                                     reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       deb_info("CODERATE LP ");
+       switch (temp) {
+       case 0:
+               fep->code_rate_LP = FEC_1_2;
+               deb_info("FEC_1_2\n");
+               break;
+       case 1:
+               fep->code_rate_LP = FEC_2_3;
+               deb_info("FEC_2_3\n");
+               break;
+       case 2:
+               fep->code_rate_LP = FEC_3_4;
+               deb_info("FEC_3_4\n");
+               break;
+       case 3:
+               fep->code_rate_LP = FEC_5_6;
+               deb_info("FEC_5_6\n");
+               break;
+       case 4:
+               fep->code_rate_LP = FEC_7_8;
+               deb_info("FEC_7_8\n");
+               break;
+       }
+
+       /* guard interval */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,
+                                     reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
+       if (ret)
+               return ret;
+       deb_info("GUARD INTERVAL ");
+       switch (temp) {
+       case 0:
+               fep->guard_interval = GUARD_INTERVAL_1_32;
+               deb_info("1_32\n");
+               break;
+       case 1:
+               fep->guard_interval = GUARD_INTERVAL_1_16;
+               deb_info("1_16\n");
+               break;
+       case 2:
+               fep->guard_interval = GUARD_INTERVAL_1_8;
+               deb_info("1_8\n");
+               break;
+       case 3:
+               fep->guard_interval = GUARD_INTERVAL_1_4;
+               deb_info("1_4\n");
+               break;
+       }
+
+       /* fft */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
+                                     reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
+                                     &temp);
+       if (ret)
+               return ret;
+       deb_info("TRANSMISSION MODE ");
+       switch (temp) {
+       case 0:
+               fep->transmission_mode = TRANSMISSION_MODE_2K;
+               deb_info("2K\n");
+               break;
+       case 1:
+               fep->transmission_mode = TRANSMISSION_MODE_8K;
+               deb_info("8K\n");
+               break;
+       }
+
+       /* bandwidth      */
+       ret =
+           af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,
+                                     reg_bw_len, &temp);
+       deb_info("BANDWIDTH ");
+       switch (temp) {
+       case 0:
+               fep->bandwidth_hz = 6000000;
+               deb_info("6\n");
+               break;
+       case 1:
+               fep->bandwidth_hz = 7000000;
+               deb_info("7\n");
+               break;
+       case 2:
+               fep->bandwidth_hz = 8000000;
+               deb_info("8\n");
+               break;
+       }
+       return 0;
+}
+
+static void af9005_fe_release(struct dvb_frontend *fe)
+{
+       struct af9005_fe_state *state =
+           (struct af9005_fe_state *)fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops af9005_fe_ops;
+
+struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
+{
+       struct af9005_fe_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       deb_info("attaching frontend af9005\n");
+
+       state->d = d;
+       state->opened = 0;
+
+       memcpy(&state->frontend.ops, &af9005_fe_ops,
+              sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+      error:
+       return NULL;
+}
+
+static struct dvb_frontend_ops af9005_fe_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+                .name = "AF9005 USB DVB-T",
+                .frequency_min = 44250000,
+                .frequency_max = 867250000,
+                .frequency_stepsize = 250000,
+                .caps = FE_CAN_INVERSION_AUTO |
+                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
+                FE_CAN_HIERARCHY_AUTO,
+                },
+
+       .release = af9005_fe_release,
+
+       .init = af9005_fe_init,
+       .sleep = af9005_fe_sleep,
+       .ts_bus_ctrl = af9005_ts_bus_ctrl,
+
+       .set_frontend = af9005_fe_set_frontend,
+       .get_frontend = af9005_fe_get_frontend,
+
+       .read_status = af9005_fe_read_status,
+       .read_ber = af9005_fe_read_ber,
+       .read_signal_strength = af9005_fe_read_signal_strength,
+       .read_snr = af9005_fe_read_snr,
+       .read_ucblocks = af9005_fe_read_unc_blocks,
+};
diff --git a/drivers/media/usb/dvb-usb/af9005-remote.c b/drivers/media/usb/dvb-usb/af9005-remote.c
new file mode 100644 (file)
index 0000000..7e3961d
--- /dev/null
@@ -0,0 +1,157 @@
+/* DVB USB compliant Linux driver for the Afatech 9005
+ * USB1.1 DVB-T receiver.
+ *
+ * Standard remote decode function
+ *
+ * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ * 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "af9005.h"
+/* debug */
+static int dvb_usb_af9005_remote_debug;
+module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+                "enable (1) or disable (0) debug messages."
+                DVB_USB_DEBUG_STATUS);
+
+#define deb_decode(args...)   dprintk(dvb_usb_af9005_remote_debug,0x01,args)
+
+struct rc_map_table rc_map_af9005_table[] = {
+
+       {0x01b7, KEY_POWER},
+       {0x01a7, KEY_VOLUMEUP},
+       {0x0187, KEY_CHANNELUP},
+       {0x017f, KEY_MUTE},
+       {0x01bf, KEY_VOLUMEDOWN},
+       {0x013f, KEY_CHANNELDOWN},
+       {0x01df, KEY_1},
+       {0x015f, KEY_2},
+       {0x019f, KEY_3},
+       {0x011f, KEY_4},
+       {0x01ef, KEY_5},
+       {0x016f, KEY_6},
+       {0x01af, KEY_7},
+       {0x0127, KEY_8},
+       {0x0107, KEY_9},
+       {0x01cf, KEY_ZOOM},
+       {0x014f, KEY_0},
+       {0x018f, KEY_GOTO},     /* marked jump on the remote */
+
+       {0x00bd, KEY_POWER},
+       {0x007d, KEY_VOLUMEUP},
+       {0x00fd, KEY_CHANNELUP},
+       {0x009d, KEY_MUTE},
+       {0x005d, KEY_VOLUMEDOWN},
+       {0x00dd, KEY_CHANNELDOWN},
+       {0x00ad, KEY_1},
+       {0x006d, KEY_2},
+       {0x00ed, KEY_3},
+       {0x008d, KEY_4},
+       {0x004d, KEY_5},
+       {0x00cd, KEY_6},
+       {0x00b5, KEY_7},
+       {0x0075, KEY_8},
+       {0x00f5, KEY_9},
+       {0x0095, KEY_ZOOM},
+       {0x0055, KEY_0},
+       {0x00d5, KEY_GOTO},     /* marked jump on the remote */
+};
+
+int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
+
+static int repeatable_keys[] = {
+       KEY_VOLUMEUP,
+       KEY_VOLUMEDOWN,
+       KEY_CHANNELUP,
+       KEY_CHANNELDOWN
+};
+
+int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
+                    int *state)
+{
+       u16 mark, space;
+       u32 result;
+       u8 cust, dat, invdat;
+       int i;
+
+       if (len >= 6) {
+               mark = (u16) (data[0] << 8) + data[1];
+               space = (u16) (data[2] << 8) + data[3];
+               if (space * 3 < mark) {
+                       for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
+                               if (d->last_event == repeatable_keys[i]) {
+                                       *state = REMOTE_KEY_REPEAT;
+                                       *event = d->last_event;
+                                       deb_decode("repeat key, event %x\n",
+                                                  *event);
+                                       return 0;
+                               }
+                       }
+                       deb_decode("repeated key ignored (non repeatable)\n");
+                       return 0;
+               } else if (len >= 33 * 4) {     /*32 bits + start code */
+                       result = 0;
+                       for (i = 4; i < 4 + 32 * 4; i += 4) {
+                               result <<= 1;
+                               mark = (u16) (data[i] << 8) + data[i + 1];
+                               mark >>= 1;
+                               space = (u16) (data[i + 2] << 8) + data[i + 3];
+                               space >>= 1;
+                               if (mark * 2 > space)
+                                       result += 1;
+                       }
+                       deb_decode("key pressed, raw value %x\n", result);
+                       if ((result & 0xff000000) != 0xfe000000) {
+                               deb_decode
+                                   ("doesn't start with 0xfe, ignored\n");
+                               return 0;
+                       }
+                       cust = (result >> 16) & 0xff;
+                       dat = (result >> 8) & 0xff;
+                       invdat = (~result) & 0xff;
+                       if (dat != invdat) {
+                               deb_decode("code != inverted code\n");
+                               return 0;
+                       }
+                       for (i = 0; i < rc_map_af9005_table_size; i++) {
+                               if (rc5_custom(&rc_map_af9005_table[i]) == cust
+                                   && rc5_data(&rc_map_af9005_table[i]) == dat) {
+                                       *event = rc_map_af9005_table[i].keycode;
+                                       *state = REMOTE_KEY_PRESSED;
+                                       deb_decode
+                                           ("key pressed, event %x\n", *event);
+                                       return 0;
+                               }
+                       }
+                       deb_decode("not found in table\n");
+               }
+       }
+       return 0;
+}
+
+EXPORT_SYMBOL(rc_map_af9005_table);
+EXPORT_SYMBOL(rc_map_af9005_table_size);
+EXPORT_SYMBOL(af9005_rc_decode);
+
+MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
+MODULE_DESCRIPTION
+    ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005-script.h b/drivers/media/usb/dvb-usb/af9005-script.h
new file mode 100644 (file)
index 0000000..4d69045
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+File automatically generated by createinit.py using data
+extracted from AF05BDA.sys (windows driver):
+
+dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110
+python createinit.py > af9005-script.h
+
+*/
+
+typedef struct {
+       u16 reg;
+       u8 pos;
+       u8 len;
+       u8 val;
+} RegDesc;
+
+static RegDesc script[] = {
+       {0xa180, 0x0, 0x8, 0xa},
+       {0xa181, 0x0, 0x8, 0xd7},
+       {0xa182, 0x0, 0x8, 0xa3},
+       {0xa0a0, 0x0, 0x8, 0x0},
+       {0xa0a1, 0x0, 0x5, 0x0},
+       {0xa0a1, 0x5, 0x1, 0x1},
+       {0xa0c0, 0x0, 0x4, 0x1},
+       {0xa20e, 0x4, 0x4, 0xa},
+       {0xa20f, 0x0, 0x8, 0x40},
+       {0xa210, 0x0, 0x8, 0x8},
+       {0xa32a, 0x0, 0x4, 0xa},
+       {0xa32c, 0x0, 0x8, 0x20},
+       {0xa32b, 0x0, 0x8, 0x15},
+       {0xa1a0, 0x1, 0x1, 0x1},
+       {0xa000, 0x0, 0x1, 0x1},
+       {0xa000, 0x1, 0x1, 0x0},
+       {0xa001, 0x1, 0x1, 0x1},
+       {0xa001, 0x0, 0x1, 0x0},
+       {0xa001, 0x5, 0x1, 0x0},
+       {0xa00e, 0x0, 0x5, 0x10},
+       {0xa00f, 0x0, 0x3, 0x4},
+       {0xa00f, 0x3, 0x3, 0x5},
+       {0xa010, 0x0, 0x3, 0x4},
+       {0xa010, 0x3, 0x3, 0x5},
+       {0xa016, 0x4, 0x4, 0x3},
+       {0xa01f, 0x0, 0x6, 0xa},
+       {0xa020, 0x0, 0x6, 0xa},
+       {0xa2bc, 0x0, 0x1, 0x1},
+       {0xa2bc, 0x5, 0x1, 0x1},
+       {0xa015, 0x0, 0x8, 0x50},
+       {0xa016, 0x0, 0x1, 0x0},
+       {0xa02a, 0x0, 0x8, 0x50},
+       {0xa029, 0x0, 0x8, 0x4b},
+       {0xa614, 0x0, 0x8, 0x46},
+       {0xa002, 0x0, 0x5, 0x19},
+       {0xa003, 0x0, 0x5, 0x1a},
+       {0xa004, 0x0, 0x5, 0x19},
+       {0xa005, 0x0, 0x5, 0x1a},
+       {0xa008, 0x0, 0x8, 0x69},
+       {0xa009, 0x0, 0x2, 0x2},
+       {0xae1b, 0x0, 0x8, 0x69},
+       {0xae1c, 0x0, 0x8, 0x2},
+       {0xae1d, 0x0, 0x8, 0x2a},
+       {0xa022, 0x0, 0x8, 0xaa},
+       {0xa006, 0x0, 0x8, 0xc8},
+       {0xa007, 0x0, 0x2, 0x0},
+       {0xa00c, 0x0, 0x8, 0xba},
+       {0xa00d, 0x0, 0x2, 0x2},
+       {0xa608, 0x0, 0x8, 0xba},
+       {0xa60e, 0x0, 0x2, 0x2},
+       {0xa609, 0x0, 0x8, 0x80},
+       {0xa60e, 0x2, 0x2, 0x3},
+       {0xa00a, 0x0, 0x8, 0xb6},
+       {0xa00b, 0x0, 0x2, 0x0},
+       {0xa011, 0x0, 0x8, 0xb9},
+       {0xa012, 0x0, 0x2, 0x0},
+       {0xa013, 0x0, 0x8, 0xbd},
+       {0xa014, 0x0, 0x2, 0x2},
+       {0xa366, 0x0, 0x1, 0x1},
+       {0xa2bc, 0x3, 0x1, 0x0},
+       {0xa2bd, 0x0, 0x8, 0xa},
+       {0xa2be, 0x0, 0x8, 0x14},
+       {0xa2bf, 0x0, 0x8, 0x8},
+       {0xa60a, 0x0, 0x8, 0xbd},
+       {0xa60e, 0x4, 0x2, 0x2},
+       {0xa60b, 0x0, 0x8, 0x86},
+       {0xa60e, 0x6, 0x2, 0x3},
+       {0xa001, 0x2, 0x2, 0x1},
+       {0xa1c7, 0x0, 0x8, 0xf5},
+       {0xa03d, 0x0, 0x8, 0xb1},
+       {0xa616, 0x0, 0x8, 0xff},
+       {0xa617, 0x0, 0x8, 0xad},
+       {0xa618, 0x0, 0x8, 0xad},
+       {0xa61e, 0x3, 0x1, 0x1},
+       {0xae1a, 0x0, 0x8, 0x0},
+       {0xae19, 0x0, 0x8, 0xc8},
+       {0xae18, 0x0, 0x8, 0x61},
+       {0xa140, 0x0, 0x8, 0x0},
+       {0xa141, 0x0, 0x8, 0xc8},
+       {0xa142, 0x0, 0x7, 0x61},
+       {0xa023, 0x0, 0x8, 0xff},
+       {0xa021, 0x0, 0x8, 0xad},
+       {0xa026, 0x0, 0x1, 0x0},
+       {0xa024, 0x0, 0x8, 0xff},
+       {0xa025, 0x0, 0x8, 0xff},
+       {0xa1c8, 0x0, 0x8, 0xf},
+       {0xa2bc, 0x1, 0x1, 0x0},
+       {0xa60c, 0x0, 0x4, 0x5},
+       {0xa60c, 0x4, 0x4, 0x6},
+       {0xa60d, 0x0, 0x8, 0xa},
+       {0xa371, 0x0, 0x1, 0x1},
+       {0xa366, 0x1, 0x3, 0x7},
+       {0xa338, 0x0, 0x8, 0x10},
+       {0xa339, 0x0, 0x6, 0x7},
+       {0xa33a, 0x0, 0x6, 0x1f},
+       {0xa33b, 0x0, 0x8, 0xf6},
+       {0xa33c, 0x3, 0x5, 0x4},
+       {0xa33d, 0x4, 0x4, 0x0},
+       {0xa33d, 0x1, 0x1, 0x1},
+       {0xa33d, 0x2, 0x1, 0x1},
+       {0xa33d, 0x3, 0x1, 0x1},
+       {0xa16d, 0x0, 0x4, 0xf},
+       {0xa161, 0x0, 0x5, 0x5},
+       {0xa162, 0x0, 0x4, 0x5},
+       {0xa165, 0x0, 0x8, 0xff},
+       {0xa166, 0x0, 0x8, 0x9c},
+       {0xa2c3, 0x0, 0x4, 0x5},
+       {0xa61a, 0x0, 0x6, 0xf},
+       {0xb200, 0x0, 0x8, 0xa1},
+       {0xb201, 0x0, 0x8, 0x7},
+       {0xa093, 0x0, 0x1, 0x0},
+       {0xa093, 0x1, 0x5, 0xf},
+       {0xa094, 0x0, 0x8, 0xff},
+       {0xa095, 0x0, 0x8, 0xf},
+       {0xa080, 0x2, 0x5, 0x3},
+       {0xa081, 0x0, 0x4, 0x0},
+       {0xa081, 0x4, 0x4, 0x9},
+       {0xa082, 0x0, 0x5, 0x1f},
+       {0xa08d, 0x0, 0x8, 0x1},
+       {0xa083, 0x0, 0x8, 0x32},
+       {0xa084, 0x0, 0x1, 0x0},
+       {0xa08e, 0x0, 0x8, 0x3},
+       {0xa085, 0x0, 0x8, 0x32},
+       {0xa086, 0x0, 0x3, 0x0},
+       {0xa087, 0x0, 0x8, 0x6e},
+       {0xa088, 0x0, 0x5, 0x15},
+       {0xa089, 0x0, 0x8, 0x0},
+       {0xa08a, 0x0, 0x5, 0x19},
+       {0xa08b, 0x0, 0x8, 0x92},
+       {0xa08c, 0x0, 0x5, 0x1c},
+       {0xa120, 0x0, 0x8, 0x0},
+       {0xa121, 0x0, 0x5, 0x10},
+       {0xa122, 0x0, 0x8, 0x0},
+       {0xa123, 0x0, 0x7, 0x40},
+       {0xa123, 0x7, 0x1, 0x0},
+       {0xa124, 0x0, 0x8, 0x13},
+       {0xa125, 0x0, 0x7, 0x10},
+       {0xa1c0, 0x0, 0x8, 0x0},
+       {0xa1c1, 0x0, 0x5, 0x4},
+       {0xa1c2, 0x0, 0x8, 0x0},
+       {0xa1c3, 0x0, 0x5, 0x10},
+       {0xa1c3, 0x5, 0x3, 0x0},
+       {0xa1c4, 0x0, 0x6, 0x0},
+       {0xa1c5, 0x0, 0x7, 0x10},
+       {0xa100, 0x0, 0x8, 0x0},
+       {0xa101, 0x0, 0x5, 0x10},
+       {0xa102, 0x0, 0x8, 0x0},
+       {0xa103, 0x0, 0x7, 0x40},
+       {0xa103, 0x7, 0x1, 0x0},
+       {0xa104, 0x0, 0x8, 0x18},
+       {0xa105, 0x0, 0x7, 0xa},
+       {0xa106, 0x0, 0x8, 0x20},
+       {0xa107, 0x0, 0x8, 0x40},
+       {0xa108, 0x0, 0x4, 0x0},
+       {0xa38c, 0x0, 0x8, 0xfc},
+       {0xa38d, 0x0, 0x8, 0x0},
+       {0xa38e, 0x0, 0x8, 0x7e},
+       {0xa38f, 0x0, 0x8, 0x0},
+       {0xa390, 0x0, 0x8, 0x2f},
+       {0xa60f, 0x5, 0x1, 0x1},
+       {0xa170, 0x0, 0x8, 0xdc},
+       {0xa171, 0x0, 0x2, 0x0},
+       {0xa2ae, 0x0, 0x1, 0x1},
+       {0xa2ae, 0x1, 0x1, 0x1},
+       {0xa392, 0x0, 0x1, 0x1},
+       {0xa391, 0x2, 0x1, 0x0},
+       {0xabc1, 0x0, 0x8, 0xff},
+       {0xabc2, 0x0, 0x8, 0x0},
+       {0xabc8, 0x0, 0x8, 0x8},
+       {0xabca, 0x0, 0x8, 0x10},
+       {0xabcb, 0x0, 0x1, 0x0},
+       {0xabc3, 0x5, 0x3, 0x7},
+       {0xabc0, 0x6, 0x1, 0x0},
+       {0xabc0, 0x4, 0x2, 0x0},
+       {0xa344, 0x4, 0x4, 0x1},
+       {0xabc0, 0x7, 0x1, 0x1},
+       {0xabc0, 0x2, 0x1, 0x1},
+       {0xa345, 0x0, 0x8, 0x66},
+       {0xa346, 0x0, 0x8, 0x66},
+       {0xa347, 0x0, 0x4, 0x0},
+       {0xa343, 0x0, 0x4, 0xa},
+       {0xa347, 0x4, 0x4, 0x2},
+       {0xa348, 0x0, 0x4, 0xc},
+       {0xa348, 0x4, 0x4, 0x7},
+       {0xa349, 0x0, 0x6, 0x2},
+};
diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
new file mode 100644 (file)
index 0000000..af176b6
--- /dev/null
@@ -0,0 +1,1117 @@
+/* DVB USB compliant Linux driver for the Afatech 9005
+ * USB1.1 DVB-T receiver.
+ *
+ * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ * 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "af9005.h"
+
+/* debug */
+int dvb_usb_af9005_debug;
+module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+                "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
+                DVB_USB_DEBUG_STATUS);
+/* enable obnoxious led */
+bool dvb_usb_af9005_led = 1;
+module_param_named(led, dvb_usb_af9005_led, bool, 0644);
+MODULE_PARM_DESC(led, "enable led (default: 1).");
+
+/* eeprom dump */
+static int dvb_usb_af9005_dump_eeprom;
+module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
+MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* remote control decoder */
+static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
+               u32 *event, int *state);
+static void *rc_keys;
+static int *rc_keys_size;
+
+u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
+
+struct af9005_device_state {
+       u8 sequence;
+       int led_state;
+};
+
+static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
+                             int readwrite, int type, u8 * values, int len)
+{
+       struct af9005_device_state *st = d->priv;
+       u8 obuf[16] = { 0 };
+       u8 ibuf[17] = { 0 };
+       u8 command;
+       int i;
+       int ret;
+
+       if (len < 1) {
+               err("generic read/write, less than 1 byte. Makes no sense.");
+               return -EINVAL;
+       }
+       if (len > 8) {
+               err("generic read/write, more than 8 bytes. Not supported.");
+               return -EINVAL;
+       }
+
+       obuf[0] = 14;           /* rest of buffer length low */
+       obuf[1] = 0;            /* rest of buffer length high */
+
+       obuf[2] = AF9005_REGISTER_RW;   /* register operation */
+       obuf[3] = 12;           /* rest of buffer length */
+
+       obuf[4] = st->sequence++;       /* sequence number */
+
+       obuf[5] = (u8) (reg >> 8);      /* register address */
+       obuf[6] = (u8) (reg & 0xff);
+
+       if (type == AF9005_OFDM_REG) {
+               command = AF9005_CMD_OFDM_REG;
+       } else {
+               command = AF9005_CMD_TUNER;
+       }
+
+       if (len > 1)
+               command |=
+                   AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
+       command |= readwrite;
+       if (readwrite == AF9005_CMD_WRITE)
+               for (i = 0; i < len; i++)
+                       obuf[8 + i] = values[i];
+       else if (type == AF9005_TUNER_REG)
+               /* read command for tuner, the first byte contains the i2c address */
+               obuf[8] = values[0];
+       obuf[7] = command;
+
+       ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
+       if (ret)
+               return ret;
+
+       /* sanity check */
+       if (ibuf[2] != AF9005_REGISTER_RW_ACK) {
+               err("generic read/write, wrong reply code.");
+               return -EIO;
+       }
+       if (ibuf[3] != 0x0d) {
+               err("generic read/write, wrong length in reply.");
+               return -EIO;
+       }
+       if (ibuf[4] != obuf[4]) {
+               err("generic read/write, wrong sequence in reply.");
+               return -EIO;
+       }
+       /*
+          Windows driver doesn't check these fields, in fact sometimes
+          the register in the reply is different that what has been sent
+
+          if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {
+          err("generic read/write, wrong register in reply.");
+          return -EIO;
+          }
+          if (ibuf[7] != command) {
+          err("generic read/write wrong command in reply.");
+          return -EIO;
+          }
+        */
+       if (ibuf[16] != 0x01) {
+               err("generic read/write wrong status code in reply.");
+               return -EIO;
+       }
+       if (readwrite == AF9005_CMD_READ)
+               for (i = 0; i < len; i++)
+                       values[i] = ibuf[8 + i];
+
+       return 0;
+
+}
+
+int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
+{
+       int ret;
+       deb_reg("read register %x ", reg);
+       ret = af9005_generic_read_write(d, reg,
+                                       AF9005_CMD_READ, AF9005_OFDM_REG,
+                                       value, 1);
+       if (ret)
+               deb_reg("failed\n");
+       else
+               deb_reg("value %x\n", *value);
+       return ret;
+}
+
+int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
+                              u8 * values, int len)
+{
+       int ret;
+       deb_reg("read %d registers %x ", len, reg);
+       ret = af9005_generic_read_write(d, reg,
+                                       AF9005_CMD_READ, AF9005_OFDM_REG,
+                                       values, len);
+       if (ret)
+               deb_reg("failed\n");
+       else
+               debug_dump(values, len, deb_reg);
+       return ret;
+}
+
+int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
+{
+       int ret;
+       u8 temp = value;
+       deb_reg("write register %x value %x ", reg, value);
+       ret = af9005_generic_read_write(d, reg,
+                                       AF9005_CMD_WRITE, AF9005_OFDM_REG,
+                                       &temp, 1);
+       if (ret)
+               deb_reg("failed\n");
+       else
+               deb_reg("ok\n");
+       return ret;
+}
+
+int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
+                               u8 * values, int len)
+{
+       int ret;
+       deb_reg("write %d registers %x values ", len, reg);
+       debug_dump(values, len, deb_reg);
+
+       ret = af9005_generic_read_write(d, reg,
+                                       AF9005_CMD_WRITE, AF9005_OFDM_REG,
+                                       values, len);
+       if (ret)
+               deb_reg("failed\n");
+       else
+               deb_reg("ok\n");
+       return ret;
+}
+
+int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
+                             u8 len, u8 * value)
+{
+       u8 temp;
+       int ret;
+       deb_reg("read bits %x %x %x", reg, pos, len);
+       ret = af9005_read_ofdm_register(d, reg, &temp);
+       if (ret) {
+               deb_reg(" failed\n");
+               return ret;
+       }
+       *value = (temp >> pos) & regmask[len - 1];
+       deb_reg(" value %x\n", *value);
+       return 0;
+
+}
+
+int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
+                              u8 len, u8 value)
+{
+       u8 temp, mask;
+       int ret;
+       deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
+       if (pos == 0 && len == 8)
+               return af9005_write_ofdm_register(d, reg, value);
+       ret = af9005_read_ofdm_register(d, reg, &temp);
+       if (ret)
+               return ret;
+       mask = regmask[len - 1] << pos;
+       temp = (temp & ~mask) | ((value << pos) & mask);
+       return af9005_write_ofdm_register(d, reg, temp);
+
+}
+
+static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
+                                          u16 reg, u8 * values, int len)
+{
+       return af9005_generic_read_write(d, reg,
+                                        AF9005_CMD_READ, AF9005_TUNER_REG,
+                                        values, len);
+}
+
+static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
+                                           u16 reg, u8 * values, int len)
+{
+       return af9005_generic_read_write(d, reg,
+                                        AF9005_CMD_WRITE,
+                                        AF9005_TUNER_REG, values, len);
+}
+
+int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
+                                u8 * values, int len)
+{
+       /* don't let the name of this function mislead you: it's just used
+          as an interface from the firmware to the i2c bus. The actual
+          i2c addresses are contained in the data */
+       int ret, i, done = 0, fail = 0;
+       u8 temp;
+       ret = af9005_usb_write_tuner_registers(d, reg, values, len);
+       if (ret)
+               return ret;
+       if (reg != 0xffff) {
+               /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
+               for (i = 0; i < 200; i++) {
+                       ret =
+                           af9005_read_ofdm_register(d,
+                                                     xd_I2C_i2c_m_status_wdat_done,
+                                                     &temp);
+                       if (ret)
+                               return ret;
+                       done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
+                                      << i2c_m_status_wdat_done_pos);
+                       if (done)
+                               break;
+                       fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
+                                      << i2c_m_status_wdat_fail_pos);
+                       if (fail)
+                               break;
+                       msleep(50);
+               }
+               if (i == 200)
+                       return -ETIMEDOUT;
+               if (fail) {
+                       /* clear write fail bit */
+                       af9005_write_register_bits(d,
+                                                  xd_I2C_i2c_m_status_wdat_fail,
+                                                  i2c_m_status_wdat_fail_pos,
+                                                  i2c_m_status_wdat_fail_len,
+                                                  1);
+                       return -EIO;
+               }
+               /* clear write done bit */
+               ret =
+                   af9005_write_register_bits(d,
+                                              xd_I2C_i2c_m_status_wdat_fail,
+                                              i2c_m_status_wdat_done_pos,
+                                              i2c_m_status_wdat_done_len, 1);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
+int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
+                               u8 * values, int len)
+{
+       /* don't let the name of this function mislead you: it's just used
+          as an interface from the firmware to the i2c bus. The actual
+          i2c addresses are contained in the data */
+       int ret, i;
+       u8 temp, buf[2];
+
+       buf[0] = addr;          /* tuner i2c address */
+       buf[1] = values[0];     /* tuner register */
+
+       values[0] = addr + 0x01;        /* i2c read address */
+
+       if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
+               /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
+               ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
+               if (ret)
+                       return ret;
+       }
+
+       /* send read command to ofsm */
+       ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
+       if (ret)
+               return ret;
+
+       /* check if read done */
+       for (i = 0; i < 200; i++) {
+               ret = af9005_read_ofdm_register(d, 0xa408, &temp);
+               if (ret)
+                       return ret;
+               if (temp & 0x01)
+                       break;
+               msleep(50);
+       }
+       if (i == 200)
+               return -ETIMEDOUT;
+
+       /* clear read done bit (by writing 1) */
+       ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
+       if (ret)
+               return ret;
+
+       /* get read data (available from 0xa400) */
+       for (i = 0; i < len; i++) {
+               ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
+               if (ret)
+                       return ret;
+               values[i] = temp;
+       }
+       return 0;
+}
+
+static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
+                           u8 * data, int len)
+{
+       int ret, i;
+       u8 buf[3];
+       deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
+               reg, len);
+       debug_dump(data, len, deb_i2c);
+
+       for (i = 0; i < len; i++) {
+               buf[0] = i2caddr;
+               buf[1] = reg + (u8) i;
+               buf[2] = data[i];
+               ret =
+                   af9005_write_tuner_registers(d,
+                                                APO_REG_I2C_RW_SILICON_TUNER,
+                                                buf, 3);
+               if (ret) {
+                       deb_i2c("i2c_write failed\n");
+                       return ret;
+               }
+       }
+       deb_i2c("i2c_write ok\n");
+       return 0;
+}
+
+static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
+                          u8 * data, int len)
+{
+       int ret, i;
+       u8 temp;
+       deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
+       for (i = 0; i < len; i++) {
+               temp = reg + i;
+               ret =
+                   af9005_read_tuner_registers(d,
+                                               APO_REG_I2C_RW_SILICON_TUNER,
+                                               i2caddr, &temp, 1);
+               if (ret) {
+                       deb_i2c("i2c_read failed\n");
+                       return ret;
+               }
+               data[i] = temp;
+       }
+       deb_i2c("i2c data read: ");
+       debug_dump(data, len, deb_i2c);
+       return 0;
+}
+
+static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                          int num)
+{
+       /* only implements what the mt2060 module does, don't know how
+          to make it really generic */
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int ret;
+       u8 reg, addr;
+       u8 *value;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       if (num > 2)
+               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+       if (num == 2) {
+               /* reads a single register */
+               reg = *msg[0].buf;
+               addr = msg[0].addr;
+               value = msg[1].buf;
+               ret = af9005_i2c_read(d, addr, reg, value, 1);
+               if (ret == 0)
+                       ret = 2;
+       } else {
+               /* write one or more registers */
+               reg = msg[0].buf[0];
+               addr = msg[0].addr;
+               value = &msg[0].buf[1];
+               ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
+               if (ret == 0)
+                       ret = 1;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return ret;
+}
+
+static u32 af9005_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9005_i2c_algo = {
+       .master_xfer = af9005_i2c_xfer,
+       .functionality = af9005_i2c_func,
+};
+
+int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
+                       int wlen, u8 * rbuf, int rlen)
+{
+       struct af9005_device_state *st = d->priv;
+
+       int ret, i, packet_len;
+       u8 buf[64];
+       u8 ibuf[64];
+
+       if (wlen < 0) {
+               err("send command, wlen less than 0 bytes. Makes no sense.");
+               return -EINVAL;
+       }
+       if (wlen > 54) {
+               err("send command, wlen more than 54 bytes. Not supported.");
+               return -EINVAL;
+       }
+       if (rlen > 54) {
+               err("send command, rlen more than 54 bytes. Not supported.");
+               return -EINVAL;
+       }
+       packet_len = wlen + 5;
+       buf[0] = (u8) (packet_len & 0xff);
+       buf[1] = (u8) ((packet_len & 0xff00) >> 8);
+
+       buf[2] = 0x26;          /* packet type */
+       buf[3] = wlen + 3;
+       buf[4] = st->sequence++;
+       buf[5] = command;
+       buf[6] = wlen;
+       for (i = 0; i < wlen; i++)
+               buf[7 + i] = wbuf[i];
+       ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);
+       if (ret)
+               return ret;
+       if (ibuf[2] != 0x27) {
+               err("send command, wrong reply code.");
+               return -EIO;
+       }
+       if (ibuf[4] != buf[4]) {
+               err("send command, wrong sequence in reply.");
+               return -EIO;
+       }
+       if (ibuf[5] != 0x01) {
+               err("send command, wrong status code in reply.");
+               return -EIO;
+       }
+       if (ibuf[6] != rlen) {
+               err("send command, invalid data length in reply.");
+               return -EIO;
+       }
+       for (i = 0; i < rlen; i++)
+               rbuf[i] = ibuf[i + 7];
+       return 0;
+}
+
+int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
+                      int len)
+{
+       struct af9005_device_state *st = d->priv;
+       u8 obuf[16], ibuf[14];
+       int ret, i;
+
+       memset(obuf, 0, sizeof(obuf));
+       memset(ibuf, 0, sizeof(ibuf));
+
+       obuf[0] = 14;           /* length of rest of packet low */
+       obuf[1] = 0;            /* length of rest of packer high */
+
+       obuf[2] = 0x2a;         /* read/write eeprom */
+
+       obuf[3] = 12;           /* size */
+
+       obuf[4] = st->sequence++;
+
+       obuf[5] = 0;            /* read */
+
+       obuf[6] = len;
+       obuf[7] = address;
+       ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);
+       if (ret)
+               return ret;
+       if (ibuf[2] != 0x2b) {
+               err("Read eeprom, invalid reply code");
+               return -EIO;
+       }
+       if (ibuf[3] != 10) {
+               err("Read eeprom, invalid reply length");
+               return -EIO;
+       }
+       if (ibuf[4] != obuf[4]) {
+               err("Read eeprom, wrong sequence in reply ");
+               return -EIO;
+       }
+       if (ibuf[5] != 1) {
+               err("Read eeprom, wrong status in reply ");
+               return -EIO;
+       }
+       for (i = 0; i < len; i++) {
+               values[i] = ibuf[6 + i];
+       }
+       return 0;
+}
+
+static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
+{
+       u8 buf[FW_BULKOUT_SIZE + 2];
+       u16 checksum;
+       int act_len, i, ret;
+       memset(buf, 0, sizeof(buf));
+       buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
+       buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
+       switch (type) {
+       case FW_CONFIG:
+               buf[2] = 0x11;
+               buf[3] = 0x04;
+               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
+               buf[5] = 0x03;
+               checksum = buf[4] + buf[5];
+               buf[6] = (u8) ((checksum >> 8) & 0xff);
+               buf[7] = (u8) (checksum & 0xff);
+               break;
+       case FW_CONFIRM:
+               buf[2] = 0x11;
+               buf[3] = 0x04;
+               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
+               buf[5] = 0x01;
+               checksum = buf[4] + buf[5];
+               buf[6] = (u8) ((checksum >> 8) & 0xff);
+               buf[7] = (u8) (checksum & 0xff);
+               break;
+       case FW_BOOT:
+               buf[2] = 0x10;
+               buf[3] = 0x08;
+               buf[4] = 0x00;  /* sequence number, original driver doesn't increment it here */
+               buf[5] = 0x97;
+               buf[6] = 0xaa;
+               buf[7] = 0x55;
+               buf[8] = 0xa5;
+               buf[9] = 0x5a;
+               checksum = 0;
+               for (i = 4; i <= 9; i++)
+                       checksum += buf[i];
+               buf[10] = (u8) ((checksum >> 8) & 0xff);
+               buf[11] = (u8) (checksum & 0xff);
+               break;
+       default:
+               err("boot packet invalid boot packet type");
+               return -EINVAL;
+       }
+       deb_fw(">>> ");
+       debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
+
+       ret = usb_bulk_msg(udev,
+                          usb_sndbulkpipe(udev, 0x02),
+                          buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
+       if (ret)
+               err("boot packet bulk message failed: %d (%d/%d)", ret,
+                   FW_BULKOUT_SIZE + 2, act_len);
+       else
+               ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
+       if (ret)
+               return ret;
+       memset(buf, 0, 9);
+       ret = usb_bulk_msg(udev,
+                          usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
+       if (ret) {
+               err("boot packet recv bulk message failed: %d", ret);
+               return ret;
+       }
+       deb_fw("<<< ");
+       debug_dump(buf, act_len, deb_fw);
+       checksum = 0;
+       switch (type) {
+       case FW_CONFIG:
+               if (buf[2] != 0x11) {
+                       err("boot bad config header.");
+                       return -EIO;
+               }
+               if (buf[3] != 0x05) {
+                       err("boot bad config size.");
+                       return -EIO;
+               }
+               if (buf[4] != 0x00) {
+                       err("boot bad config sequence.");
+                       return -EIO;
+               }
+               if (buf[5] != 0x04) {
+                       err("boot bad config subtype.");
+                       return -EIO;
+               }
+               for (i = 4; i <= 6; i++)
+                       checksum += buf[i];
+               if (buf[7] * 256 + buf[8] != checksum) {
+                       err("boot bad config checksum.");
+                       return -EIO;
+               }
+               *reply = buf[6];
+               break;
+       case FW_CONFIRM:
+               if (buf[2] != 0x11) {
+                       err("boot bad confirm header.");
+                       return -EIO;
+               }
+               if (buf[3] != 0x05) {
+                       err("boot bad confirm size.");
+                       return -EIO;
+               }
+               if (buf[4] != 0x00) {
+                       err("boot bad confirm sequence.");
+                       return -EIO;
+               }
+               if (buf[5] != 0x02) {
+                       err("boot bad confirm subtype.");
+                       return -EIO;
+               }
+               for (i = 4; i <= 6; i++)
+                       checksum += buf[i];
+               if (buf[7] * 256 + buf[8] != checksum) {
+                       err("boot bad confirm checksum.");
+                       return -EIO;
+               }
+               *reply = buf[6];
+               break;
+       case FW_BOOT:
+               if (buf[2] != 0x10) {
+                       err("boot bad boot header.");
+                       return -EIO;
+               }
+               if (buf[3] != 0x05) {
+                       err("boot bad boot size.");
+                       return -EIO;
+               }
+               if (buf[4] != 0x00) {
+                       err("boot bad boot sequence.");
+                       return -EIO;
+               }
+               if (buf[5] != 0x01) {
+                       err("boot bad boot pattern 01.");
+                       return -EIO;
+               }
+               if (buf[6] != 0x10) {
+                       err("boot bad boot pattern 10.");
+                       return -EIO;
+               }
+               for (i = 4; i <= 6; i++)
+                       checksum += buf[i];
+               if (buf[7] * 256 + buf[8] != checksum) {
+                       err("boot bad boot checksum.");
+                       return -EIO;
+               }
+               break;
+
+       }
+
+       return 0;
+}
+
+static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
+{
+       int i, packets, ret, act_len;
+
+       u8 buf[FW_BULKOUT_SIZE + 2];
+       u8 reply;
+
+       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+       if (ret)
+               return ret;
+       if (reply != 0x01) {
+               err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
+               return -EIO;
+       }
+       packets = fw->size / FW_BULKOUT_SIZE;
+       buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
+       buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
+       for (i = 0; i < packets; i++) {
+               memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
+                      FW_BULKOUT_SIZE);
+               deb_fw(">>> ");
+               debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
+               ret = usb_bulk_msg(udev,
+                                  usb_sndbulkpipe(udev, 0x02),
+                                  buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
+               if (ret) {
+                       err("firmware download failed at packet %d with code %d", i, ret);
+                       return ret;
+               }
+       }
+       ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);
+       if (ret)
+               return ret;
+       if (reply != (u8) (packets & 0xff)) {
+               err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
+               return -EIO;
+       }
+       ret = af9005_boot_packet(udev, FW_BOOT, &reply);
+       if (ret)
+               return ret;
+       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+       if (ret)
+               return ret;
+       if (reply != 0x02) {
+               err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
+               return -EIO;
+       }
+
+       return 0;
+
+}
+
+int af9005_led_control(struct dvb_usb_device *d, int onoff)
+{
+       struct af9005_device_state *st = d->priv;
+       int temp, ret;
+
+       if (onoff && dvb_usb_af9005_led)
+               temp = 1;
+       else
+               temp = 0;
+       if (st->led_state != temp) {
+               ret =
+                   af9005_write_register_bits(d, xd_p_reg_top_locken1,
+                                              reg_top_locken1_pos,
+                                              reg_top_locken1_len, temp);
+               if (ret)
+                       return ret;
+               ret =
+                   af9005_write_register_bits(d, xd_p_reg_top_lock1,
+                                              reg_top_lock1_pos,
+                                              reg_top_lock1_len, temp);
+               if (ret)
+                       return ret;
+               st->led_state = temp;
+       }
+       return 0;
+}
+
+static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       u8 buf[8];
+       int i;
+
+       /* without these calls the first commands after downloading
+          the firmware fail. I put these calls here to simulate
+          what it is done in dvb-usb-init.c.
+        */
+       struct usb_device *udev = adap->dev->udev;
+       usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
+       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
+       if (dvb_usb_af9005_dump_eeprom) {
+               printk("EEPROM DUMP\n");
+               for (i = 0; i < 255; i += 8) {
+                       af9005_read_eeprom(adap->dev, i, buf, 8);
+                       printk("ADDR %x ", i);
+                       debug_dump(buf, 8, printk);
+               }
+       }
+       adap->fe_adap[0].fe = af9005_fe_attach(adap->dev);
+       return 0;
+}
+
+static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
+{
+       struct af9005_device_state *st = d->priv;
+       int ret, len;
+
+       u8 obuf[5];
+       u8 ibuf[256];
+
+       *state = REMOTE_NO_KEY_PRESSED;
+       if (rc_decode == NULL) {
+               /* it shouldn't never come here */
+               return 0;
+       }
+       /* deb_info("rc_query\n"); */
+       obuf[0] = 3;            /* rest of packet length low */
+       obuf[1] = 0;            /* rest of packet lentgh high */
+       obuf[2] = 0x40;         /* read remote */
+       obuf[3] = 1;            /* rest of packet length */
+       obuf[4] = st->sequence++;       /* sequence number */
+       ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);
+       if (ret) {
+               err("rc query failed");
+               return ret;
+       }
+       if (ibuf[2] != 0x41) {
+               err("rc query bad header.");
+               return -EIO;
+       }
+       if (ibuf[4] != obuf[4]) {
+               err("rc query bad sequence.");
+               return -EIO;
+       }
+       len = ibuf[5];
+       if (len > 246) {
+               err("rc query invalid length");
+               return -EIO;
+       }
+       if (len > 0) {
+               deb_rc("rc data (%d) ", len);
+               debug_dump((ibuf + 6), len, deb_rc);
+               ret = rc_decode(d, &ibuf[6], len, event, state);
+               if (ret) {
+                       err("rc_decode failed");
+                       return ret;
+               } else {
+                       deb_rc("rc_decode state %x event %x\n", *state, *event);
+                       if (*state == REMOTE_KEY_REPEAT)
+                               *event = d->last_event;
+               }
+       }
+       return 0;
+}
+
+static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+
+       return 0;
+}
+
+static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+       deb_info("pid filter control  onoff %d\n", onoff);
+       if (onoff) {
+               ret =
+                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
+               if (ret)
+                       return ret;
+               ret =
+                   af9005_write_register_bits(adap->dev,
+                                              XD_MP2IF_DMX_CTRL, 1, 1, 1);
+               if (ret)
+                       return ret;
+               ret =
+                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
+       } else
+               ret =
+                   af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
+       if (ret)
+               return ret;
+       deb_info("pid filter control ok\n");
+       return 0;
+}
+
+static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
+                            u16 pid, int onoff)
+{
+       u8 cmd = index & 0x1f;
+       int ret;
+       deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
+                pid, onoff);
+       if (onoff) {
+               /* cannot use it as pid_filter_ctrl since it has to be done
+                  before setting the first pid */
+               if (adap->feedcount == 1) {
+                       deb_info("first pid set, enable pid table\n");
+                       ret = af9005_pid_filter_control(adap, onoff);
+                       if (ret)
+                               return ret;
+               }
+               ret =
+                   af9005_write_ofdm_register(adap->dev,
+                                              XD_MP2IF_PID_DATA_L,
+                                              (u8) (pid & 0xff));
+               if (ret)
+                       return ret;
+               ret =
+                   af9005_write_ofdm_register(adap->dev,
+                                              XD_MP2IF_PID_DATA_H,
+                                              (u8) (pid >> 8));
+               if (ret)
+                       return ret;
+               cmd |= 0x20 | 0x40;
+       } else {
+               if (adap->feedcount == 0) {
+                       deb_info("last pid unset, disable pid table\n");
+                       ret = af9005_pid_filter_control(adap, onoff);
+                       if (ret)
+                               return ret;
+               }
+       }
+       ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
+       if (ret)
+               return ret;
+       deb_info("set pid ok\n");
+       return 0;
+}
+
+static int af9005_identify_state(struct usb_device *udev,
+                                struct dvb_usb_device_properties *props,
+                                struct dvb_usb_device_description **desc,
+                                int *cold)
+{
+       int ret;
+       u8 reply;
+       ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+       if (ret)
+               return ret;
+       deb_info("result of FW_CONFIG in identify state %d\n", reply);
+       if (reply == 0x01)
+               *cold = 1;
+       else if (reply == 0x02)
+               *cold = 0;
+       else
+               return -EIO;
+       deb_info("Identify state cold = %d\n", *cold);
+       return 0;
+}
+
+static struct dvb_usb_device_properties af9005_properties;
+
+static int af9005_usb_probe(struct usb_interface *intf,
+                           const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &af9005_properties,
+                                  THIS_MODULE, NULL, adapter_nr);
+}
+
+enum af9005_usb_table_entry {
+       AFATECH_AF9005,
+       TERRATEC_AF9005,
+       ANSONIC_AF9005,
+};
+
+static struct usb_device_id af9005_usb_table[] = {
+       [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
+                               USB_PID_AFATECH_AF9005)},
+       [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
+                               USB_PID_TERRATEC_CINERGY_T_USB_XE)},
+       [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
+                               USB_PID_ANSONIC_DVBT_USB)},
+       { }
+};
+
+MODULE_DEVICE_TABLE(usb, af9005_usb_table);
+
+static struct dvb_usb_device_properties af9005_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "af9005.fw",
+       .download_firmware = af9005_download_firmware,
+       .no_reconnect = 1,
+
+       .size_of_priv = sizeof(struct af9005_device_state),
+
+       .num_adapters = 1,
+       .adapter = {
+                   {
+                   .num_frontends = 1,
+                   .fe = {{
+                    .caps =
+                    DVB_USB_ADAP_HAS_PID_FILTER |
+                    DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                    .pid_filter_count = 32,
+                    .pid_filter = af9005_pid_filter,
+                    /* .pid_filter_ctrl = af9005_pid_filter_control, */
+                    .frontend_attach = af9005_frontend_attach,
+                    /* .tuner_attach     = af9005_tuner_attach, */
+                    /* parameter for the MPEG2-data transfer */
+                    .stream = {
+                               .type = USB_BULK,
+                               .count = 10,
+                               .endpoint = 0x04,
+                               .u = {
+                                     .bulk = {
+                                              .buffersize = 4096,      /* actual size seen is 3948 */
+                                              }
+                                     }
+                               },
+                    }},
+                    }
+                   },
+       .power_ctrl = af9005_power_ctrl,
+       .identify_state = af9005_identify_state,
+
+       .i2c_algo = &af9005_i2c_algo,
+
+       .rc.legacy = {
+               .rc_interval = 200,
+               .rc_map_table = NULL,
+               .rc_map_size = 0,
+               .rc_query = af9005_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint          = 2,
+       .generic_bulk_ctrl_endpoint_response = 1,
+
+       .num_device_descs = 3,
+       .devices = {
+                   {.name = "Afatech DVB-T USB1.1 stick",
+                    .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
+                    .warm_ids = {NULL},
+                    },
+                   {.name = "TerraTec Cinergy T USB XE",
+                    .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
+                    .warm_ids = {NULL},
+                    },
+                   {.name = "Ansonic DVB-T USB1.1 stick",
+                    .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
+                    .warm_ids = {NULL},
+                    },
+                   {NULL},
+                   }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver af9005_usb_driver = {
+       .name = "dvb_usb_af9005",
+       .probe = af9005_usb_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table = af9005_usb_table,
+};
+
+/* module stuff */
+static int __init af9005_usb_module_init(void)
+{
+       int result;
+       if ((result = usb_register(&af9005_usb_driver))) {
+               err("usb_register failed. (%d)", result);
+               return result;
+       }
+       rc_decode = symbol_request(af9005_rc_decode);
+       rc_keys = symbol_request(rc_map_af9005_table);
+       rc_keys_size = symbol_request(rc_map_af9005_table_size);
+       if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
+               err("af9005_rc_decode function not found, disabling remote");
+               af9005_properties.rc.legacy.rc_query = NULL;
+       } else {
+               af9005_properties.rc.legacy.rc_map_table = rc_keys;
+               af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
+       }
+
+       return 0;
+}
+
+static void __exit af9005_usb_module_exit(void)
+{
+       /* release rc decode symbols */
+       if (rc_decode != NULL)
+               symbol_put(af9005_rc_decode);
+       if (rc_keys != NULL)
+               symbol_put(rc_map_af9005_table);
+       if (rc_keys_size != NULL)
+               symbol_put(rc_map_af9005_table_size);
+       /* deregister this driver from the USB subsystem */
+       usb_deregister(&af9005_usb_driver);
+}
+
+module_init(af9005_usb_module_init);
+module_exit(af9005_usb_module_exit);
+
+MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
+MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005.h b/drivers/media/usb/dvb-usb/af9005.h
new file mode 100644 (file)
index 0000000..6a2bf3d
--- /dev/null
@@ -0,0 +1,3496 @@
+/* Common header-file of the Linux driver for the Afatech 9005
+ * USB1.1 DVB-T receiver.
+ *
+ * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ * 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_AF9005_H_
+#define _DVB_USB_AF9005_H_
+
+#define DVB_USB_LOG_PREFIX "af9005"
+#include "dvb-usb.h"
+
+extern int dvb_usb_af9005_debug;
+#define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_af9005_debug,0x04,args)
+#define deb_reg(args...)  dprintk(dvb_usb_af9005_debug,0x08,args)
+#define deb_i2c(args...)  dprintk(dvb_usb_af9005_debug,0x10,args)
+#define deb_fw(args...)   dprintk(dvb_usb_af9005_debug,0x20,args)
+
+extern bool dvb_usb_af9005_led;
+
+/* firmware */
+#define FW_BULKOUT_SIZE 250
+enum {
+       FW_CONFIG,
+       FW_CONFIRM,
+       FW_BOOT
+};
+
+/* af9005 commands */
+#define AF9005_OFDM_REG  0
+#define AF9005_TUNER_REG 1
+
+#define AF9005_REGISTER_RW     0x20
+#define AF9005_REGISTER_RW_ACK 0x21
+
+#define AF9005_CMD_OFDM_REG 0x00
+#define AF9005_CMD_TUNER    0x80
+#define AF9005_CMD_BURST    0x02
+#define AF9005_CMD_AUTOINC  0x04
+#define AF9005_CMD_READ     0x00
+#define AF9005_CMD_WRITE    0x01
+
+/* af9005 registers */
+#define APO_REG_RESET                                  0xAEFF
+
+#define APO_REG_I2C_RW_CAN_TUNER            0xF000
+#define APO_REG_I2C_RW_SILICON_TUNER        0xF001
+#define APO_REG_GPIO_RW_SILICON_TUNER       0xFFFE     /*  also for OFSM */
+#define APO_REG_TRIGGER_OFSM                0xFFFF     /*  also for OFSM */
+
+/***********************************************************************
+ *  Apollo Registers from VLSI                                        *
+ ***********************************************************************/
+#define xd_p_reg_aagc_inverted_agc     0xA000
+#define        reg_aagc_inverted_agc_pos 0
+#define        reg_aagc_inverted_agc_len 1
+#define        reg_aagc_inverted_agc_lsb 0
+#define xd_p_reg_aagc_sign_only        0xA000
+#define        reg_aagc_sign_only_pos 1
+#define        reg_aagc_sign_only_len 1
+#define        reg_aagc_sign_only_lsb 0
+#define xd_p_reg_aagc_slow_adc_en      0xA000
+#define        reg_aagc_slow_adc_en_pos 2
+#define        reg_aagc_slow_adc_en_len 1
+#define        reg_aagc_slow_adc_en_lsb 0
+#define xd_p_reg_aagc_slow_adc_scale   0xA000
+#define        reg_aagc_slow_adc_scale_pos 3
+#define        reg_aagc_slow_adc_scale_len 5
+#define        reg_aagc_slow_adc_scale_lsb 0
+#define xd_p_reg_aagc_check_slow_adc_lock      0xA001
+#define        reg_aagc_check_slow_adc_lock_pos 0
+#define        reg_aagc_check_slow_adc_lock_len 1
+#define        reg_aagc_check_slow_adc_lock_lsb 0
+#define xd_p_reg_aagc_init_control     0xA001
+#define        reg_aagc_init_control_pos 1
+#define        reg_aagc_init_control_len 1
+#define        reg_aagc_init_control_lsb 0
+#define xd_p_reg_aagc_total_gain_sel   0xA001
+#define        reg_aagc_total_gain_sel_pos 2
+#define        reg_aagc_total_gain_sel_len 2
+#define        reg_aagc_total_gain_sel_lsb 0
+#define xd_p_reg_aagc_out_inv  0xA001
+#define        reg_aagc_out_inv_pos 5
+#define        reg_aagc_out_inv_len 1
+#define        reg_aagc_out_inv_lsb 0
+#define xd_p_reg_aagc_int_en   0xA001
+#define        reg_aagc_int_en_pos 6
+#define        reg_aagc_int_en_len 1
+#define        reg_aagc_int_en_lsb 0
+#define xd_p_reg_aagc_lock_change_flag 0xA001
+#define        reg_aagc_lock_change_flag_pos 7
+#define        reg_aagc_lock_change_flag_len 1
+#define        reg_aagc_lock_change_flag_lsb 0
+#define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002
+#define        reg_aagc_rf_loop_bw_scale_acquire_pos 0
+#define        reg_aagc_rf_loop_bw_scale_acquire_len 5
+#define        reg_aagc_rf_loop_bw_scale_acquire_lsb 0
+#define xd_p_reg_aagc_rf_loop_bw_scale_track   0xA003
+#define        reg_aagc_rf_loop_bw_scale_track_pos 0
+#define        reg_aagc_rf_loop_bw_scale_track_len 5
+#define        reg_aagc_rf_loop_bw_scale_track_lsb 0
+#define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004
+#define        reg_aagc_if_loop_bw_scale_acquire_pos 0
+#define        reg_aagc_if_loop_bw_scale_acquire_len 5
+#define        reg_aagc_if_loop_bw_scale_acquire_lsb 0
+#define xd_p_reg_aagc_if_loop_bw_scale_track   0xA005
+#define        reg_aagc_if_loop_bw_scale_track_pos 0
+#define        reg_aagc_if_loop_bw_scale_track_len 5
+#define        reg_aagc_if_loop_bw_scale_track_lsb 0
+#define xd_p_reg_aagc_max_rf_agc_7_0   0xA006
+#define        reg_aagc_max_rf_agc_7_0_pos 0
+#define        reg_aagc_max_rf_agc_7_0_len 8
+#define        reg_aagc_max_rf_agc_7_0_lsb 0
+#define xd_p_reg_aagc_max_rf_agc_9_8   0xA007
+#define        reg_aagc_max_rf_agc_9_8_pos 0
+#define        reg_aagc_max_rf_agc_9_8_len 2
+#define        reg_aagc_max_rf_agc_9_8_lsb 8
+#define xd_p_reg_aagc_min_rf_agc_7_0   0xA008
+#define        reg_aagc_min_rf_agc_7_0_pos 0
+#define        reg_aagc_min_rf_agc_7_0_len 8
+#define        reg_aagc_min_rf_agc_7_0_lsb 0
+#define xd_p_reg_aagc_min_rf_agc_9_8   0xA009
+#define        reg_aagc_min_rf_agc_9_8_pos 0
+#define        reg_aagc_min_rf_agc_9_8_len 2
+#define        reg_aagc_min_rf_agc_9_8_lsb 8
+#define xd_p_reg_aagc_max_if_agc_7_0   0xA00A
+#define        reg_aagc_max_if_agc_7_0_pos 0
+#define        reg_aagc_max_if_agc_7_0_len 8
+#define        reg_aagc_max_if_agc_7_0_lsb 0
+#define xd_p_reg_aagc_max_if_agc_9_8   0xA00B
+#define        reg_aagc_max_if_agc_9_8_pos 0
+#define        reg_aagc_max_if_agc_9_8_len 2
+#define        reg_aagc_max_if_agc_9_8_lsb 8
+#define xd_p_reg_aagc_min_if_agc_7_0   0xA00C
+#define        reg_aagc_min_if_agc_7_0_pos 0
+#define        reg_aagc_min_if_agc_7_0_len 8
+#define        reg_aagc_min_if_agc_7_0_lsb 0
+#define xd_p_reg_aagc_min_if_agc_9_8   0xA00D
+#define        reg_aagc_min_if_agc_9_8_pos 0
+#define        reg_aagc_min_if_agc_9_8_len 2
+#define        reg_aagc_min_if_agc_9_8_lsb 8
+#define xd_p_reg_aagc_lock_sample_scale        0xA00E
+#define        reg_aagc_lock_sample_scale_pos 0
+#define        reg_aagc_lock_sample_scale_len 5
+#define        reg_aagc_lock_sample_scale_lsb 0
+#define xd_p_reg_aagc_rf_agc_lock_scale_acquire        0xA00F
+#define        reg_aagc_rf_agc_lock_scale_acquire_pos 0
+#define        reg_aagc_rf_agc_lock_scale_acquire_len 3
+#define        reg_aagc_rf_agc_lock_scale_acquire_lsb 0
+#define xd_p_reg_aagc_rf_agc_lock_scale_track  0xA00F
+#define        reg_aagc_rf_agc_lock_scale_track_pos 3
+#define        reg_aagc_rf_agc_lock_scale_track_len 3
+#define        reg_aagc_rf_agc_lock_scale_track_lsb 0
+#define xd_p_reg_aagc_if_agc_lock_scale_acquire        0xA010
+#define        reg_aagc_if_agc_lock_scale_acquire_pos 0
+#define        reg_aagc_if_agc_lock_scale_acquire_len 3
+#define        reg_aagc_if_agc_lock_scale_acquire_lsb 0
+#define xd_p_reg_aagc_if_agc_lock_scale_track  0xA010
+#define        reg_aagc_if_agc_lock_scale_track_pos 3
+#define        reg_aagc_if_agc_lock_scale_track_len 3
+#define        reg_aagc_if_agc_lock_scale_track_lsb 0
+#define xd_p_reg_aagc_rf_top_numerator_7_0     0xA011
+#define        reg_aagc_rf_top_numerator_7_0_pos 0
+#define        reg_aagc_rf_top_numerator_7_0_len 8
+#define        reg_aagc_rf_top_numerator_7_0_lsb 0
+#define xd_p_reg_aagc_rf_top_numerator_9_8     0xA012
+#define        reg_aagc_rf_top_numerator_9_8_pos 0
+#define        reg_aagc_rf_top_numerator_9_8_len 2
+#define        reg_aagc_rf_top_numerator_9_8_lsb 8
+#define xd_p_reg_aagc_if_top_numerator_7_0     0xA013
+#define        reg_aagc_if_top_numerator_7_0_pos 0
+#define        reg_aagc_if_top_numerator_7_0_len 8
+#define        reg_aagc_if_top_numerator_7_0_lsb 0
+#define xd_p_reg_aagc_if_top_numerator_9_8     0xA014
+#define        reg_aagc_if_top_numerator_9_8_pos 0
+#define        reg_aagc_if_top_numerator_9_8_len 2
+#define        reg_aagc_if_top_numerator_9_8_lsb 8
+#define xd_p_reg_aagc_adc_out_desired_7_0      0xA015
+#define        reg_aagc_adc_out_desired_7_0_pos 0
+#define        reg_aagc_adc_out_desired_7_0_len 8
+#define        reg_aagc_adc_out_desired_7_0_lsb 0
+#define xd_p_reg_aagc_adc_out_desired_8        0xA016
+#define        reg_aagc_adc_out_desired_8_pos 0
+#define        reg_aagc_adc_out_desired_8_len 1
+#define        reg_aagc_adc_out_desired_8_lsb 0
+#define xd_p_reg_aagc_fixed_gain       0xA016
+#define        reg_aagc_fixed_gain_pos 3
+#define        reg_aagc_fixed_gain_len 1
+#define        reg_aagc_fixed_gain_lsb 0
+#define xd_p_reg_aagc_lock_count_th    0xA016
+#define        reg_aagc_lock_count_th_pos 4
+#define        reg_aagc_lock_count_th_len 4
+#define        reg_aagc_lock_count_th_lsb 0
+#define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017
+#define        reg_aagc_fixed_rf_agc_control_7_0_pos 0
+#define        reg_aagc_fixed_rf_agc_control_7_0_len 8
+#define        reg_aagc_fixed_rf_agc_control_7_0_lsb 0
+#define xd_p_reg_aagc_fixed_rf_agc_control_15_8        0xA018
+#define        reg_aagc_fixed_rf_agc_control_15_8_pos 0
+#define        reg_aagc_fixed_rf_agc_control_15_8_len 8
+#define        reg_aagc_fixed_rf_agc_control_15_8_lsb 8
+#define xd_p_reg_aagc_fixed_rf_agc_control_23_16       0xA019
+#define        reg_aagc_fixed_rf_agc_control_23_16_pos 0
+#define        reg_aagc_fixed_rf_agc_control_23_16_len 8
+#define        reg_aagc_fixed_rf_agc_control_23_16_lsb 16
+#define xd_p_reg_aagc_fixed_rf_agc_control_30_24       0xA01A
+#define        reg_aagc_fixed_rf_agc_control_30_24_pos 0
+#define        reg_aagc_fixed_rf_agc_control_30_24_len 7
+#define        reg_aagc_fixed_rf_agc_control_30_24_lsb 24
+#define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B
+#define        reg_aagc_fixed_if_agc_control_7_0_pos 0
+#define        reg_aagc_fixed_if_agc_control_7_0_len 8
+#define        reg_aagc_fixed_if_agc_control_7_0_lsb 0
+#define xd_p_reg_aagc_fixed_if_agc_control_15_8        0xA01C
+#define        reg_aagc_fixed_if_agc_control_15_8_pos 0
+#define        reg_aagc_fixed_if_agc_control_15_8_len 8
+#define        reg_aagc_fixed_if_agc_control_15_8_lsb 8
+#define xd_p_reg_aagc_fixed_if_agc_control_23_16       0xA01D
+#define        reg_aagc_fixed_if_agc_control_23_16_pos 0
+#define        reg_aagc_fixed_if_agc_control_23_16_len 8
+#define        reg_aagc_fixed_if_agc_control_23_16_lsb 16
+#define xd_p_reg_aagc_fixed_if_agc_control_30_24       0xA01E
+#define        reg_aagc_fixed_if_agc_control_30_24_pos 0
+#define        reg_aagc_fixed_if_agc_control_30_24_len 7
+#define        reg_aagc_fixed_if_agc_control_30_24_lsb 24
+#define xd_p_reg_aagc_rf_agc_unlock_numerator  0xA01F
+#define        reg_aagc_rf_agc_unlock_numerator_pos 0
+#define        reg_aagc_rf_agc_unlock_numerator_len 6
+#define        reg_aagc_rf_agc_unlock_numerator_lsb 0
+#define xd_p_reg_aagc_if_agc_unlock_numerator  0xA020
+#define        reg_aagc_if_agc_unlock_numerator_pos 0
+#define        reg_aagc_if_agc_unlock_numerator_len 6
+#define        reg_aagc_if_agc_unlock_numerator_lsb 0
+#define xd_p_reg_unplug_th     0xA021
+#define        reg_unplug_th_pos 0
+#define        reg_unplug_th_len 8
+#define        reg_aagc_rf_x0_lsb 0
+#define xd_p_reg_weak_signal_rfagc_thr 0xA022
+#define        reg_weak_signal_rfagc_thr_pos 0
+#define        reg_weak_signal_rfagc_thr_len 8
+#define        reg_weak_signal_rfagc_thr_lsb 0
+#define xd_p_reg_unplug_rf_gain_th 0xA023
+#define        reg_unplug_rf_gain_th_pos 0
+#define        reg_unplug_rf_gain_th_len 8
+#define        reg_unplug_rf_gain_th_lsb 0
+#define xd_p_reg_unplug_dtop_rf_gain_th 0xA024
+#define        reg_unplug_dtop_rf_gain_th_pos 0
+#define        reg_unplug_dtop_rf_gain_th_len 8
+#define        reg_unplug_dtop_rf_gain_th_lsb 0
+#define xd_p_reg_unplug_dtop_if_gain_th 0xA025
+#define        reg_unplug_dtop_if_gain_th_pos 0
+#define        reg_unplug_dtop_if_gain_th_len 8
+#define        reg_unplug_dtop_if_gain_th_lsb 0
+#define xd_p_reg_top_recover_at_unplug_en 0xA026
+#define        reg_top_recover_at_unplug_en_pos 0
+#define        reg_top_recover_at_unplug_en_len 1
+#define        reg_top_recover_at_unplug_en_lsb 0
+#define xd_p_reg_aagc_rf_x6    0xA027
+#define        reg_aagc_rf_x6_pos 0
+#define        reg_aagc_rf_x6_len 8
+#define        reg_aagc_rf_x6_lsb 0
+#define xd_p_reg_aagc_rf_x7    0xA028
+#define        reg_aagc_rf_x7_pos 0
+#define        reg_aagc_rf_x7_len 8
+#define        reg_aagc_rf_x7_lsb 0
+#define xd_p_reg_aagc_rf_x8    0xA029
+#define        reg_aagc_rf_x8_pos 0
+#define        reg_aagc_rf_x8_len 8
+#define        reg_aagc_rf_x8_lsb 0
+#define xd_p_reg_aagc_rf_x9    0xA02A
+#define        reg_aagc_rf_x9_pos 0
+#define        reg_aagc_rf_x9_len 8
+#define        reg_aagc_rf_x9_lsb 0
+#define xd_p_reg_aagc_rf_x10   0xA02B
+#define        reg_aagc_rf_x10_pos 0
+#define        reg_aagc_rf_x10_len 8
+#define        reg_aagc_rf_x10_lsb 0
+#define xd_p_reg_aagc_rf_x11   0xA02C
+#define        reg_aagc_rf_x11_pos 0
+#define        reg_aagc_rf_x11_len 8
+#define        reg_aagc_rf_x11_lsb 0
+#define xd_p_reg_aagc_rf_x12   0xA02D
+#define        reg_aagc_rf_x12_pos 0
+#define        reg_aagc_rf_x12_len 8
+#define        reg_aagc_rf_x12_lsb 0
+#define xd_p_reg_aagc_rf_x13   0xA02E
+#define        reg_aagc_rf_x13_pos 0
+#define        reg_aagc_rf_x13_len 8
+#define        reg_aagc_rf_x13_lsb 0
+#define xd_p_reg_aagc_if_x0    0xA02F
+#define        reg_aagc_if_x0_pos 0
+#define        reg_aagc_if_x0_len 8
+#define        reg_aagc_if_x0_lsb 0
+#define xd_p_reg_aagc_if_x1    0xA030
+#define        reg_aagc_if_x1_pos 0
+#define        reg_aagc_if_x1_len 8
+#define        reg_aagc_if_x1_lsb 0
+#define xd_p_reg_aagc_if_x2    0xA031
+#define        reg_aagc_if_x2_pos 0
+#define        reg_aagc_if_x2_len 8
+#define        reg_aagc_if_x2_lsb 0
+#define xd_p_reg_aagc_if_x3    0xA032
+#define        reg_aagc_if_x3_pos 0
+#define        reg_aagc_if_x3_len 8
+#define        reg_aagc_if_x3_lsb 0
+#define xd_p_reg_aagc_if_x4    0xA033
+#define        reg_aagc_if_x4_pos 0
+#define        reg_aagc_if_x4_len 8
+#define        reg_aagc_if_x4_lsb 0
+#define xd_p_reg_aagc_if_x5    0xA034
+#define        reg_aagc_if_x5_pos 0
+#define        reg_aagc_if_x5_len 8
+#define        reg_aagc_if_x5_lsb 0
+#define xd_p_reg_aagc_if_x6    0xA035
+#define        reg_aagc_if_x6_pos 0
+#define        reg_aagc_if_x6_len 8
+#define        reg_aagc_if_x6_lsb 0
+#define xd_p_reg_aagc_if_x7    0xA036
+#define        reg_aagc_if_x7_pos 0
+#define        reg_aagc_if_x7_len 8
+#define        reg_aagc_if_x7_lsb 0
+#define xd_p_reg_aagc_if_x8    0xA037
+#define        reg_aagc_if_x8_pos 0
+#define        reg_aagc_if_x8_len 8
+#define        reg_aagc_if_x8_lsb 0
+#define xd_p_reg_aagc_if_x9    0xA038
+#define        reg_aagc_if_x9_pos 0
+#define        reg_aagc_if_x9_len 8
+#define        reg_aagc_if_x9_lsb 0
+#define xd_p_reg_aagc_if_x10   0xA039
+#define        reg_aagc_if_x10_pos 0
+#define        reg_aagc_if_x10_len 8
+#define        reg_aagc_if_x10_lsb 0
+#define xd_p_reg_aagc_if_x11   0xA03A
+#define        reg_aagc_if_x11_pos 0
+#define        reg_aagc_if_x11_len 8
+#define        reg_aagc_if_x11_lsb 0
+#define xd_p_reg_aagc_if_x12   0xA03B
+#define        reg_aagc_if_x12_pos 0
+#define        reg_aagc_if_x12_len 8
+#define        reg_aagc_if_x12_lsb 0
+#define xd_p_reg_aagc_if_x13   0xA03C
+#define        reg_aagc_if_x13_pos 0
+#define        reg_aagc_if_x13_len 8
+#define        reg_aagc_if_x13_lsb 0
+#define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca  0xA03D
+#define        reg_aagc_min_rf_ctl_8bit_for_dca_pos 0
+#define        reg_aagc_min_rf_ctl_8bit_for_dca_len 8
+#define        reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0
+#define xd_p_reg_aagc_min_if_ctl_8bit_for_dca  0xA03E
+#define        reg_aagc_min_if_ctl_8bit_for_dca_pos 0
+#define        reg_aagc_min_if_ctl_8bit_for_dca_len 8
+#define        reg_aagc_min_if_ctl_8bit_for_dca_lsb 0
+#define xd_r_reg_aagc_total_gain_7_0   0xA070
+#define        reg_aagc_total_gain_7_0_pos 0
+#define        reg_aagc_total_gain_7_0_len 8
+#define        reg_aagc_total_gain_7_0_lsb 0
+#define xd_r_reg_aagc_total_gain_15_8  0xA071
+#define        reg_aagc_total_gain_15_8_pos 0
+#define        reg_aagc_total_gain_15_8_len 8
+#define        reg_aagc_total_gain_15_8_lsb 8
+#define xd_p_reg_aagc_in_sat_cnt_7_0   0xA074
+#define        reg_aagc_in_sat_cnt_7_0_pos 0
+#define        reg_aagc_in_sat_cnt_7_0_len 8
+#define        reg_aagc_in_sat_cnt_7_0_lsb 0
+#define xd_p_reg_aagc_in_sat_cnt_15_8  0xA075
+#define        reg_aagc_in_sat_cnt_15_8_pos 0
+#define        reg_aagc_in_sat_cnt_15_8_len 8
+#define        reg_aagc_in_sat_cnt_15_8_lsb 8
+#define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076
+#define        reg_aagc_in_sat_cnt_23_16_pos 0
+#define        reg_aagc_in_sat_cnt_23_16_len 8
+#define        reg_aagc_in_sat_cnt_23_16_lsb 16
+#define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077
+#define        reg_aagc_in_sat_cnt_31_24_pos 0
+#define        reg_aagc_in_sat_cnt_31_24_len 8
+#define        reg_aagc_in_sat_cnt_31_24_lsb 24
+#define xd_r_reg_aagc_digital_rf_volt_7_0      0xA078
+#define        reg_aagc_digital_rf_volt_7_0_pos 0
+#define        reg_aagc_digital_rf_volt_7_0_len 8
+#define        reg_aagc_digital_rf_volt_7_0_lsb 0
+#define xd_r_reg_aagc_digital_rf_volt_9_8      0xA079
+#define        reg_aagc_digital_rf_volt_9_8_pos 0
+#define        reg_aagc_digital_rf_volt_9_8_len 2
+#define        reg_aagc_digital_rf_volt_9_8_lsb 8
+#define xd_r_reg_aagc_digital_if_volt_7_0      0xA07A
+#define        reg_aagc_digital_if_volt_7_0_pos 0
+#define        reg_aagc_digital_if_volt_7_0_len 8
+#define        reg_aagc_digital_if_volt_7_0_lsb 0
+#define xd_r_reg_aagc_digital_if_volt_9_8      0xA07B
+#define        reg_aagc_digital_if_volt_9_8_pos 0
+#define        reg_aagc_digital_if_volt_9_8_len 2
+#define        reg_aagc_digital_if_volt_9_8_lsb 8
+#define xd_r_reg_aagc_rf_gain  0xA07C
+#define        reg_aagc_rf_gain_pos 0
+#define        reg_aagc_rf_gain_len 8
+#define        reg_aagc_rf_gain_lsb 0
+#define xd_r_reg_aagc_if_gain  0xA07D
+#define        reg_aagc_if_gain_pos 0
+#define        reg_aagc_if_gain_len 8
+#define        reg_aagc_if_gain_lsb 0
+#define xd_p_tinr_imp_indicator        0xA080
+#define        tinr_imp_indicator_pos 0
+#define        tinr_imp_indicator_len 2
+#define        tinr_imp_indicator_lsb 0
+#define xd_p_reg_tinr_fifo_size        0xA080
+#define        reg_tinr_fifo_size_pos 2
+#define        reg_tinr_fifo_size_len 5
+#define        reg_tinr_fifo_size_lsb 0
+#define xd_p_reg_tinr_saturation_cnt_th        0xA081
+#define        reg_tinr_saturation_cnt_th_pos 0
+#define        reg_tinr_saturation_cnt_th_len 4
+#define        reg_tinr_saturation_cnt_th_lsb 0
+#define xd_p_reg_tinr_saturation_th_3_0        0xA081
+#define        reg_tinr_saturation_th_3_0_pos 4
+#define        reg_tinr_saturation_th_3_0_len 4
+#define        reg_tinr_saturation_th_3_0_lsb 0
+#define xd_p_reg_tinr_saturation_th_8_4        0xA082
+#define        reg_tinr_saturation_th_8_4_pos 0
+#define        reg_tinr_saturation_th_8_4_len 5
+#define        reg_tinr_saturation_th_8_4_lsb 4
+#define xd_p_reg_tinr_imp_duration_th_2k_7_0   0xA083
+#define        reg_tinr_imp_duration_th_2k_7_0_pos 0
+#define        reg_tinr_imp_duration_th_2k_7_0_len 8
+#define        reg_tinr_imp_duration_th_2k_7_0_lsb 0
+#define xd_p_reg_tinr_imp_duration_th_2k_8     0xA084
+#define        reg_tinr_imp_duration_th_2k_8_pos 0
+#define        reg_tinr_imp_duration_th_2k_8_len 1
+#define        reg_tinr_imp_duration_th_2k_8_lsb 0
+#define xd_p_reg_tinr_imp_duration_th_8k_7_0   0xA085
+#define        reg_tinr_imp_duration_th_8k_7_0_pos 0
+#define        reg_tinr_imp_duration_th_8k_7_0_len 8
+#define        reg_tinr_imp_duration_th_8k_7_0_lsb 0
+#define xd_p_reg_tinr_imp_duration_th_8k_10_8  0xA086
+#define        reg_tinr_imp_duration_th_8k_10_8_pos 0
+#define        reg_tinr_imp_duration_th_8k_10_8_len 3
+#define        reg_tinr_imp_duration_th_8k_10_8_lsb 8
+#define xd_p_reg_tinr_freq_ratio_6m_7_0        0xA087
+#define        reg_tinr_freq_ratio_6m_7_0_pos 0
+#define        reg_tinr_freq_ratio_6m_7_0_len 8
+#define        reg_tinr_freq_ratio_6m_7_0_lsb 0
+#define xd_p_reg_tinr_freq_ratio_6m_12_8       0xA088
+#define        reg_tinr_freq_ratio_6m_12_8_pos 0
+#define        reg_tinr_freq_ratio_6m_12_8_len 5
+#define        reg_tinr_freq_ratio_6m_12_8_lsb 8
+#define xd_p_reg_tinr_freq_ratio_7m_7_0        0xA089
+#define        reg_tinr_freq_ratio_7m_7_0_pos 0
+#define        reg_tinr_freq_ratio_7m_7_0_len 8
+#define        reg_tinr_freq_ratio_7m_7_0_lsb 0
+#define xd_p_reg_tinr_freq_ratio_7m_12_8       0xA08A
+#define        reg_tinr_freq_ratio_7m_12_8_pos 0
+#define        reg_tinr_freq_ratio_7m_12_8_len 5
+#define        reg_tinr_freq_ratio_7m_12_8_lsb 8
+#define xd_p_reg_tinr_freq_ratio_8m_7_0        0xA08B
+#define        reg_tinr_freq_ratio_8m_7_0_pos 0
+#define        reg_tinr_freq_ratio_8m_7_0_len 8
+#define        reg_tinr_freq_ratio_8m_7_0_lsb 0
+#define xd_p_reg_tinr_freq_ratio_8m_12_8       0xA08C
+#define        reg_tinr_freq_ratio_8m_12_8_pos 0
+#define        reg_tinr_freq_ratio_8m_12_8_len 5
+#define        reg_tinr_freq_ratio_8m_12_8_lsb 8
+#define xd_p_reg_tinr_imp_duration_th_low_2k   0xA08D
+#define        reg_tinr_imp_duration_th_low_2k_pos 0
+#define        reg_tinr_imp_duration_th_low_2k_len 8
+#define        reg_tinr_imp_duration_th_low_2k_lsb 0
+#define xd_p_reg_tinr_imp_duration_th_low_8k   0xA08E
+#define        reg_tinr_imp_duration_th_low_8k_pos 0
+#define        reg_tinr_imp_duration_th_low_8k_len 8
+#define        reg_tinr_imp_duration_th_low_8k_lsb 0
+#define xd_r_reg_tinr_counter_7_0      0xA090
+#define        reg_tinr_counter_7_0_pos 0
+#define        reg_tinr_counter_7_0_len 8
+#define        reg_tinr_counter_7_0_lsb 0
+#define xd_r_reg_tinr_counter_15_8     0xA091
+#define        reg_tinr_counter_15_8_pos 0
+#define        reg_tinr_counter_15_8_len 8
+#define        reg_tinr_counter_15_8_lsb 8
+#define xd_p_reg_tinr_adative_tinr_en  0xA093
+#define        reg_tinr_adative_tinr_en_pos 0
+#define        reg_tinr_adative_tinr_en_len 1
+#define        reg_tinr_adative_tinr_en_lsb 0
+#define xd_p_reg_tinr_peak_fifo_size   0xA093
+#define        reg_tinr_peak_fifo_size_pos 1
+#define        reg_tinr_peak_fifo_size_len 5
+#define        reg_tinr_peak_fifo_size_lsb 0
+#define xd_p_reg_tinr_counter_rst      0xA093
+#define        reg_tinr_counter_rst_pos 6
+#define        reg_tinr_counter_rst_len 1
+#define        reg_tinr_counter_rst_lsb 0
+#define xd_p_reg_tinr_search_period_7_0        0xA094
+#define        reg_tinr_search_period_7_0_pos 0
+#define        reg_tinr_search_period_7_0_len 8
+#define        reg_tinr_search_period_7_0_lsb 0
+#define xd_p_reg_tinr_search_period_15_8       0xA095
+#define        reg_tinr_search_period_15_8_pos 0
+#define        reg_tinr_search_period_15_8_len 8
+#define        reg_tinr_search_period_15_8_lsb 8
+#define xd_p_reg_ccifs_fcw_7_0 0xA0A0
+#define        reg_ccifs_fcw_7_0_pos 0
+#define        reg_ccifs_fcw_7_0_len 8
+#define        reg_ccifs_fcw_7_0_lsb 0
+#define xd_p_reg_ccifs_fcw_12_8        0xA0A1
+#define        reg_ccifs_fcw_12_8_pos 0
+#define        reg_ccifs_fcw_12_8_len 5
+#define        reg_ccifs_fcw_12_8_lsb 8
+#define xd_p_reg_ccifs_spec_inv        0xA0A1
+#define        reg_ccifs_spec_inv_pos 5
+#define        reg_ccifs_spec_inv_len 1
+#define        reg_ccifs_spec_inv_lsb 0
+#define xd_p_reg_gp_trigger    0xA0A2
+#define        reg_gp_trigger_pos 0
+#define        reg_gp_trigger_len 1
+#define        reg_gp_trigger_lsb 0
+#define xd_p_reg_trigger_sel   0xA0A2
+#define        reg_trigger_sel_pos 1
+#define        reg_trigger_sel_len 2
+#define        reg_trigger_sel_lsb 0
+#define xd_p_reg_debug_ofdm    0xA0A2
+#define        reg_debug_ofdm_pos 3
+#define        reg_debug_ofdm_len 2
+#define        reg_debug_ofdm_lsb 0
+#define xd_p_reg_trigger_module_sel    0xA0A3
+#define        reg_trigger_module_sel_pos 0
+#define        reg_trigger_module_sel_len 6
+#define        reg_trigger_module_sel_lsb 0
+#define xd_p_reg_trigger_set_sel       0xA0A4
+#define        reg_trigger_set_sel_pos 0
+#define        reg_trigger_set_sel_len 6
+#define        reg_trigger_set_sel_lsb 0
+#define xd_p_reg_fw_int_mask_n 0xA0A4
+#define        reg_fw_int_mask_n_pos 6
+#define        reg_fw_int_mask_n_len 1
+#define        reg_fw_int_mask_n_lsb 0
+#define xd_p_reg_debug_group   0xA0A5
+#define        reg_debug_group_pos 0
+#define        reg_debug_group_len 4
+#define        reg_debug_group_lsb 0
+#define xd_p_reg_odbg_clk_sel  0xA0A5
+#define        reg_odbg_clk_sel_pos 4
+#define        reg_odbg_clk_sel_len 2
+#define        reg_odbg_clk_sel_lsb 0
+#define xd_p_reg_ccif_sc       0xA0C0
+#define        reg_ccif_sc_pos 0
+#define        reg_ccif_sc_len 4
+#define        reg_ccif_sc_lsb 0
+#define xd_r_reg_ccif_saturate 0xA0C1
+#define        reg_ccif_saturate_pos 0
+#define        reg_ccif_saturate_len 2
+#define        reg_ccif_saturate_lsb 0
+#define xd_r_reg_antif_saturate        0xA0C1
+#define        reg_antif_saturate_pos 2
+#define        reg_antif_saturate_len 4
+#define        reg_antif_saturate_lsb 0
+#define xd_r_reg_acif_saturate 0xA0C2
+#define        reg_acif_saturate_pos 0
+#define        reg_acif_saturate_len 8
+#define        reg_acif_saturate_lsb 0
+#define xd_p_reg_tmr_timer0_threshold_7_0      0xA0C8
+#define        reg_tmr_timer0_threshold_7_0_pos 0
+#define        reg_tmr_timer0_threshold_7_0_len 8
+#define        reg_tmr_timer0_threshold_7_0_lsb 0
+#define xd_p_reg_tmr_timer0_threshold_15_8     0xA0C9
+#define        reg_tmr_timer0_threshold_15_8_pos 0
+#define        reg_tmr_timer0_threshold_15_8_len 8
+#define        reg_tmr_timer0_threshold_15_8_lsb 8
+#define xd_p_reg_tmr_timer0_enable     0xA0CA
+#define        reg_tmr_timer0_enable_pos 0
+#define        reg_tmr_timer0_enable_len 1
+#define        reg_tmr_timer0_enable_lsb 0
+#define xd_p_reg_tmr_timer0_clk_sel    0xA0CA
+#define        reg_tmr_timer0_clk_sel_pos 1
+#define        reg_tmr_timer0_clk_sel_len 1
+#define        reg_tmr_timer0_clk_sel_lsb 0
+#define xd_p_reg_tmr_timer0_int        0xA0CA
+#define        reg_tmr_timer0_int_pos 2
+#define        reg_tmr_timer0_int_len 1
+#define        reg_tmr_timer0_int_lsb 0
+#define xd_p_reg_tmr_timer0_rst        0xA0CA
+#define        reg_tmr_timer0_rst_pos 3
+#define        reg_tmr_timer0_rst_len 1
+#define        reg_tmr_timer0_rst_lsb 0
+#define xd_r_reg_tmr_timer0_count_7_0  0xA0CB
+#define        reg_tmr_timer0_count_7_0_pos 0
+#define        reg_tmr_timer0_count_7_0_len 8
+#define        reg_tmr_timer0_count_7_0_lsb 0
+#define xd_r_reg_tmr_timer0_count_15_8 0xA0CC
+#define        reg_tmr_timer0_count_15_8_pos 0
+#define        reg_tmr_timer0_count_15_8_len 8
+#define        reg_tmr_timer0_count_15_8_lsb 8
+#define xd_p_reg_suspend       0xA0CD
+#define        reg_suspend_pos 0
+#define        reg_suspend_len 1
+#define        reg_suspend_lsb 0
+#define xd_p_reg_suspend_rdy   0xA0CD
+#define        reg_suspend_rdy_pos 1
+#define        reg_suspend_rdy_len 1
+#define        reg_suspend_rdy_lsb 0
+#define xd_p_reg_resume        0xA0CD
+#define        reg_resume_pos 2
+#define        reg_resume_len 1
+#define        reg_resume_lsb 0
+#define xd_p_reg_resume_rdy    0xA0CD
+#define        reg_resume_rdy_pos 3
+#define        reg_resume_rdy_len 1
+#define        reg_resume_rdy_lsb 0
+#define xd_p_reg_fmf   0xA0CE
+#define        reg_fmf_pos 0
+#define        reg_fmf_len 8
+#define        reg_fmf_lsb 0
+#define xd_p_ccid_accumulate_num_2k_7_0        0xA100
+#define        ccid_accumulate_num_2k_7_0_pos 0
+#define        ccid_accumulate_num_2k_7_0_len 8
+#define        ccid_accumulate_num_2k_7_0_lsb 0
+#define xd_p_ccid_accumulate_num_2k_12_8       0xA101
+#define        ccid_accumulate_num_2k_12_8_pos 0
+#define        ccid_accumulate_num_2k_12_8_len 5
+#define        ccid_accumulate_num_2k_12_8_lsb 8
+#define xd_p_ccid_accumulate_num_8k_7_0        0xA102
+#define        ccid_accumulate_num_8k_7_0_pos 0
+#define        ccid_accumulate_num_8k_7_0_len 8
+#define        ccid_accumulate_num_8k_7_0_lsb 0
+#define xd_p_ccid_accumulate_num_8k_14_8       0xA103
+#define        ccid_accumulate_num_8k_14_8_pos 0
+#define        ccid_accumulate_num_8k_14_8_len 7
+#define        ccid_accumulate_num_8k_14_8_lsb 8
+#define xd_p_ccid_desired_level_0      0xA103
+#define        ccid_desired_level_0_pos 7
+#define        ccid_desired_level_0_len 1
+#define        ccid_desired_level_0_lsb 0
+#define xd_p_ccid_desired_level_8_1    0xA104
+#define        ccid_desired_level_8_1_pos 0
+#define        ccid_desired_level_8_1_len 8
+#define        ccid_desired_level_8_1_lsb 1
+#define xd_p_ccid_apply_delay  0xA105
+#define        ccid_apply_delay_pos 0
+#define        ccid_apply_delay_len 7
+#define        ccid_apply_delay_lsb 0
+#define xd_p_ccid_CCID_Threshold1      0xA106
+#define        ccid_CCID_Threshold1_pos 0
+#define        ccid_CCID_Threshold1_len 8
+#define        ccid_CCID_Threshold1_lsb 0
+#define xd_p_ccid_CCID_Threshold2      0xA107
+#define        ccid_CCID_Threshold2_pos 0
+#define        ccid_CCID_Threshold2_len 8
+#define        ccid_CCID_Threshold2_lsb 0
+#define xd_p_reg_ccid_gain_scale       0xA108
+#define        reg_ccid_gain_scale_pos 0
+#define        reg_ccid_gain_scale_len 4
+#define        reg_ccid_gain_scale_lsb 0
+#define xd_p_reg_ccid2_passband_gain_set       0xA108
+#define        reg_ccid2_passband_gain_set_pos 4
+#define        reg_ccid2_passband_gain_set_len 4
+#define        reg_ccid2_passband_gain_set_lsb 0
+#define xd_r_ccid_multiplier_7_0       0xA109
+#define        ccid_multiplier_7_0_pos 0
+#define        ccid_multiplier_7_0_len 8
+#define        ccid_multiplier_7_0_lsb 0
+#define xd_r_ccid_multiplier_15_8      0xA10A
+#define        ccid_multiplier_15_8_pos 0
+#define        ccid_multiplier_15_8_len 8
+#define        ccid_multiplier_15_8_lsb 8
+#define xd_r_ccid_right_shift_bits     0xA10B
+#define        ccid_right_shift_bits_pos 0
+#define        ccid_right_shift_bits_len 4
+#define        ccid_right_shift_bits_lsb 0
+#define xd_r_reg_ccid_sx_7_0   0xA10C
+#define        reg_ccid_sx_7_0_pos 0
+#define        reg_ccid_sx_7_0_len 8
+#define        reg_ccid_sx_7_0_lsb 0
+#define xd_r_reg_ccid_sx_15_8  0xA10D
+#define        reg_ccid_sx_15_8_pos 0
+#define        reg_ccid_sx_15_8_len 8
+#define        reg_ccid_sx_15_8_lsb 8
+#define xd_r_reg_ccid_sx_21_16 0xA10E
+#define        reg_ccid_sx_21_16_pos 0
+#define        reg_ccid_sx_21_16_len 6
+#define        reg_ccid_sx_21_16_lsb 16
+#define xd_r_reg_ccid_sy_7_0   0xA110
+#define        reg_ccid_sy_7_0_pos 0
+#define        reg_ccid_sy_7_0_len 8
+#define        reg_ccid_sy_7_0_lsb 0
+#define xd_r_reg_ccid_sy_15_8  0xA111
+#define        reg_ccid_sy_15_8_pos 0
+#define        reg_ccid_sy_15_8_len 8
+#define        reg_ccid_sy_15_8_lsb 8
+#define xd_r_reg_ccid_sy_23_16 0xA112
+#define        reg_ccid_sy_23_16_pos 0
+#define        reg_ccid_sy_23_16_len 8
+#define        reg_ccid_sy_23_16_lsb 16
+#define xd_r_reg_ccid2_sz_7_0  0xA114
+#define        reg_ccid2_sz_7_0_pos 0
+#define        reg_ccid2_sz_7_0_len 8
+#define        reg_ccid2_sz_7_0_lsb 0
+#define xd_r_reg_ccid2_sz_15_8 0xA115
+#define        reg_ccid2_sz_15_8_pos 0
+#define        reg_ccid2_sz_15_8_len 8
+#define        reg_ccid2_sz_15_8_lsb 8
+#define xd_r_reg_ccid2_sz_23_16        0xA116
+#define        reg_ccid2_sz_23_16_pos 0
+#define        reg_ccid2_sz_23_16_len 8
+#define        reg_ccid2_sz_23_16_lsb 16
+#define xd_r_reg_ccid2_sz_25_24        0xA117
+#define        reg_ccid2_sz_25_24_pos 0
+#define        reg_ccid2_sz_25_24_len 2
+#define        reg_ccid2_sz_25_24_lsb 24
+#define xd_r_reg_ccid2_sy_7_0  0xA118
+#define        reg_ccid2_sy_7_0_pos 0
+#define        reg_ccid2_sy_7_0_len 8
+#define        reg_ccid2_sy_7_0_lsb 0
+#define xd_r_reg_ccid2_sy_15_8 0xA119
+#define        reg_ccid2_sy_15_8_pos 0
+#define        reg_ccid2_sy_15_8_len 8
+#define        reg_ccid2_sy_15_8_lsb 8
+#define xd_r_reg_ccid2_sy_23_16        0xA11A
+#define        reg_ccid2_sy_23_16_pos 0
+#define        reg_ccid2_sy_23_16_len 8
+#define        reg_ccid2_sy_23_16_lsb 16
+#define xd_r_reg_ccid2_sy_25_24        0xA11B
+#define        reg_ccid2_sy_25_24_pos 0
+#define        reg_ccid2_sy_25_24_len 2
+#define        reg_ccid2_sy_25_24_lsb 24
+#define xd_p_dagc1_accumulate_num_2k_7_0       0xA120
+#define        dagc1_accumulate_num_2k_7_0_pos 0
+#define        dagc1_accumulate_num_2k_7_0_len 8
+#define        dagc1_accumulate_num_2k_7_0_lsb 0
+#define xd_p_dagc1_accumulate_num_2k_12_8      0xA121
+#define        dagc1_accumulate_num_2k_12_8_pos 0
+#define        dagc1_accumulate_num_2k_12_8_len 5
+#define        dagc1_accumulate_num_2k_12_8_lsb 8
+#define xd_p_dagc1_accumulate_num_8k_7_0       0xA122
+#define        dagc1_accumulate_num_8k_7_0_pos 0
+#define        dagc1_accumulate_num_8k_7_0_len 8
+#define        dagc1_accumulate_num_8k_7_0_lsb 0
+#define xd_p_dagc1_accumulate_num_8k_14_8      0xA123
+#define        dagc1_accumulate_num_8k_14_8_pos 0
+#define        dagc1_accumulate_num_8k_14_8_len 7
+#define        dagc1_accumulate_num_8k_14_8_lsb 8
+#define xd_p_dagc1_desired_level_0     0xA123
+#define        dagc1_desired_level_0_pos 7
+#define        dagc1_desired_level_0_len 1
+#define        dagc1_desired_level_0_lsb 0
+#define xd_p_dagc1_desired_level_8_1   0xA124
+#define        dagc1_desired_level_8_1_pos 0
+#define        dagc1_desired_level_8_1_len 8
+#define        dagc1_desired_level_8_1_lsb 1
+#define xd_p_dagc1_apply_delay 0xA125
+#define        dagc1_apply_delay_pos 0
+#define        dagc1_apply_delay_len 7
+#define        dagc1_apply_delay_lsb 0
+#define xd_p_dagc1_bypass_scale_ctl    0xA126
+#define        dagc1_bypass_scale_ctl_pos 0
+#define        dagc1_bypass_scale_ctl_len 2
+#define        dagc1_bypass_scale_ctl_lsb 0
+#define xd_p_reg_dagc1_in_sat_cnt_7_0  0xA127
+#define        reg_dagc1_in_sat_cnt_7_0_pos 0
+#define        reg_dagc1_in_sat_cnt_7_0_len 8
+#define        reg_dagc1_in_sat_cnt_7_0_lsb 0
+#define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128
+#define        reg_dagc1_in_sat_cnt_15_8_pos 0
+#define        reg_dagc1_in_sat_cnt_15_8_len 8
+#define        reg_dagc1_in_sat_cnt_15_8_lsb 8
+#define xd_p_reg_dagc1_in_sat_cnt_23_16        0xA129
+#define        reg_dagc1_in_sat_cnt_23_16_pos 0
+#define        reg_dagc1_in_sat_cnt_23_16_len 8
+#define        reg_dagc1_in_sat_cnt_23_16_lsb 16
+#define xd_p_reg_dagc1_in_sat_cnt_31_24        0xA12A
+#define        reg_dagc1_in_sat_cnt_31_24_pos 0
+#define        reg_dagc1_in_sat_cnt_31_24_len 8
+#define        reg_dagc1_in_sat_cnt_31_24_lsb 24
+#define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B
+#define        reg_dagc1_out_sat_cnt_7_0_pos 0
+#define        reg_dagc1_out_sat_cnt_7_0_len 8
+#define        reg_dagc1_out_sat_cnt_7_0_lsb 0
+#define xd_p_reg_dagc1_out_sat_cnt_15_8        0xA12C
+#define        reg_dagc1_out_sat_cnt_15_8_pos 0
+#define        reg_dagc1_out_sat_cnt_15_8_len 8
+#define        reg_dagc1_out_sat_cnt_15_8_lsb 8
+#define xd_p_reg_dagc1_out_sat_cnt_23_16       0xA12D
+#define        reg_dagc1_out_sat_cnt_23_16_pos 0
+#define        reg_dagc1_out_sat_cnt_23_16_len 8
+#define        reg_dagc1_out_sat_cnt_23_16_lsb 16
+#define xd_p_reg_dagc1_out_sat_cnt_31_24       0xA12E
+#define        reg_dagc1_out_sat_cnt_31_24_pos 0
+#define        reg_dagc1_out_sat_cnt_31_24_len 8
+#define        reg_dagc1_out_sat_cnt_31_24_lsb 24
+#define xd_r_dagc1_multiplier_7_0      0xA136
+#define        dagc1_multiplier_7_0_pos 0
+#define        dagc1_multiplier_7_0_len 8
+#define        dagc1_multiplier_7_0_lsb 0
+#define xd_r_dagc1_multiplier_15_8     0xA137
+#define        dagc1_multiplier_15_8_pos 0
+#define        dagc1_multiplier_15_8_len 8
+#define        dagc1_multiplier_15_8_lsb 8
+#define xd_r_dagc1_right_shift_bits    0xA138
+#define        dagc1_right_shift_bits_pos 0
+#define        dagc1_right_shift_bits_len 4
+#define        dagc1_right_shift_bits_lsb 0
+#define xd_p_reg_bfs_fcw_7_0   0xA140
+#define        reg_bfs_fcw_7_0_pos 0
+#define        reg_bfs_fcw_7_0_len 8
+#define        reg_bfs_fcw_7_0_lsb 0
+#define xd_p_reg_bfs_fcw_15_8  0xA141
+#define        reg_bfs_fcw_15_8_pos 0
+#define        reg_bfs_fcw_15_8_len 8
+#define        reg_bfs_fcw_15_8_lsb 8
+#define xd_p_reg_bfs_fcw_22_16 0xA142
+#define        reg_bfs_fcw_22_16_pos 0
+#define        reg_bfs_fcw_22_16_len 7
+#define        reg_bfs_fcw_22_16_lsb 16
+#define xd_p_reg_antif_sf_7_0  0xA144
+#define        reg_antif_sf_7_0_pos 0
+#define        reg_antif_sf_7_0_len 8
+#define        reg_antif_sf_7_0_lsb 0
+#define xd_p_reg_antif_sf_11_8 0xA145
+#define        reg_antif_sf_11_8_pos 0
+#define        reg_antif_sf_11_8_len 4
+#define        reg_antif_sf_11_8_lsb 8
+#define xd_r_bfs_fcw_q_7_0     0xA150
+#define        bfs_fcw_q_7_0_pos 0
+#define        bfs_fcw_q_7_0_len 8
+#define        bfs_fcw_q_7_0_lsb 0
+#define xd_r_bfs_fcw_q_15_8    0xA151
+#define        bfs_fcw_q_15_8_pos 0
+#define        bfs_fcw_q_15_8_len 8
+#define        bfs_fcw_q_15_8_lsb 8
+#define xd_r_bfs_fcw_q_22_16   0xA152
+#define        bfs_fcw_q_22_16_pos 0
+#define        bfs_fcw_q_22_16_len 7
+#define        bfs_fcw_q_22_16_lsb 16
+#define xd_p_reg_dca_enu       0xA160
+#define        reg_dca_enu_pos 0
+#define        reg_dca_enu_len 1
+#define        reg_dca_enu_lsb 0
+#define xd_p_reg_dca_enl       0xA160
+#define        reg_dca_enl_pos 1
+#define        reg_dca_enl_len 1
+#define        reg_dca_enl_lsb 0
+#define xd_p_reg_dca_lower_chip        0xA160
+#define        reg_dca_lower_chip_pos 2
+#define        reg_dca_lower_chip_len 1
+#define        reg_dca_lower_chip_lsb 0
+#define xd_p_reg_dca_upper_chip        0xA160
+#define        reg_dca_upper_chip_pos 3
+#define        reg_dca_upper_chip_len 1
+#define        reg_dca_upper_chip_lsb 0
+#define xd_p_reg_dca_platch    0xA160
+#define        reg_dca_platch_pos 4
+#define        reg_dca_platch_len 1
+#define        reg_dca_platch_lsb 0
+#define xd_p_reg_dca_th        0xA161
+#define        reg_dca_th_pos 0
+#define        reg_dca_th_len 5
+#define        reg_dca_th_lsb 0
+#define xd_p_reg_dca_scale     0xA162
+#define        reg_dca_scale_pos 0
+#define        reg_dca_scale_len 4
+#define        reg_dca_scale_lsb 0
+#define xd_p_reg_dca_tone_7_0  0xA163
+#define        reg_dca_tone_7_0_pos 0
+#define        reg_dca_tone_7_0_len 8
+#define        reg_dca_tone_7_0_lsb 0
+#define xd_p_reg_dca_tone_12_8 0xA164
+#define        reg_dca_tone_12_8_pos 0
+#define        reg_dca_tone_12_8_len 5
+#define        reg_dca_tone_12_8_lsb 8
+#define xd_p_reg_dca_time_7_0  0xA165
+#define        reg_dca_time_7_0_pos 0
+#define        reg_dca_time_7_0_len 8
+#define        reg_dca_time_7_0_lsb 0
+#define xd_p_reg_dca_time_15_8 0xA166
+#define        reg_dca_time_15_8_pos 0
+#define        reg_dca_time_15_8_len 8
+#define        reg_dca_time_15_8_lsb 8
+#define xd_r_dcasm     0xA167
+#define        dcasm_pos 0
+#define        dcasm_len 3
+#define        dcasm_lsb 0
+#define xd_p_reg_qnt_valuew_7_0        0xA168
+#define        reg_qnt_valuew_7_0_pos 0
+#define        reg_qnt_valuew_7_0_len 8
+#define        reg_qnt_valuew_7_0_lsb 0
+#define xd_p_reg_qnt_valuew_10_8       0xA169
+#define        reg_qnt_valuew_10_8_pos 0
+#define        reg_qnt_valuew_10_8_len 3
+#define        reg_qnt_valuew_10_8_lsb 8
+#define xd_p_dca_sbx_gain_diff_7_0     0xA16A
+#define        dca_sbx_gain_diff_7_0_pos 0
+#define        dca_sbx_gain_diff_7_0_len 8
+#define        dca_sbx_gain_diff_7_0_lsb 0
+#define xd_p_dca_sbx_gain_diff_9_8     0xA16B
+#define        dca_sbx_gain_diff_9_8_pos 0
+#define        dca_sbx_gain_diff_9_8_len 2
+#define        dca_sbx_gain_diff_9_8_lsb 8
+#define xd_p_reg_dca_stand_alone       0xA16C
+#define        reg_dca_stand_alone_pos 0
+#define        reg_dca_stand_alone_len 1
+#define        reg_dca_stand_alone_lsb 0
+#define xd_p_reg_dca_upper_out_en      0xA16C
+#define        reg_dca_upper_out_en_pos 1
+#define        reg_dca_upper_out_en_len 1
+#define        reg_dca_upper_out_en_lsb 0
+#define xd_p_reg_dca_rc_en     0xA16C
+#define        reg_dca_rc_en_pos 2
+#define        reg_dca_rc_en_len 1
+#define        reg_dca_rc_en_lsb 0
+#define xd_p_reg_dca_retrain_send      0xA16C
+#define        reg_dca_retrain_send_pos 3
+#define        reg_dca_retrain_send_len 1
+#define        reg_dca_retrain_send_lsb 0
+#define xd_p_reg_dca_retrain_rec       0xA16C
+#define        reg_dca_retrain_rec_pos 4
+#define        reg_dca_retrain_rec_len 1
+#define        reg_dca_retrain_rec_lsb 0
+#define xd_p_reg_dca_api_tpsrdy        0xA16C
+#define        reg_dca_api_tpsrdy_pos 5
+#define        reg_dca_api_tpsrdy_len 1
+#define        reg_dca_api_tpsrdy_lsb 0
+#define xd_p_reg_dca_symbol_gap        0xA16D
+#define        reg_dca_symbol_gap_pos 0
+#define        reg_dca_symbol_gap_len 4
+#define        reg_dca_symbol_gap_lsb 0
+#define xd_p_reg_qnt_nfvaluew_7_0      0xA16E
+#define        reg_qnt_nfvaluew_7_0_pos 0
+#define        reg_qnt_nfvaluew_7_0_len 8
+#define        reg_qnt_nfvaluew_7_0_lsb 0
+#define xd_p_reg_qnt_nfvaluew_10_8     0xA16F
+#define        reg_qnt_nfvaluew_10_8_pos 0
+#define        reg_qnt_nfvaluew_10_8_len 3
+#define        reg_qnt_nfvaluew_10_8_lsb 8
+#define xd_p_reg_qnt_flatness_thr_7_0  0xA170
+#define        reg_qnt_flatness_thr_7_0_pos 0
+#define        reg_qnt_flatness_thr_7_0_len 8
+#define        reg_qnt_flatness_thr_7_0_lsb 0
+#define xd_p_reg_qnt_flatness_thr_9_8  0xA171
+#define        reg_qnt_flatness_thr_9_8_pos 0
+#define        reg_qnt_flatness_thr_9_8_len 2
+#define        reg_qnt_flatness_thr_9_8_lsb 8
+#define xd_p_reg_dca_tone_idx_5_0      0xA171
+#define        reg_dca_tone_idx_5_0_pos 2
+#define        reg_dca_tone_idx_5_0_len 6
+#define        reg_dca_tone_idx_5_0_lsb 0
+#define xd_p_reg_dca_tone_idx_12_6     0xA172
+#define        reg_dca_tone_idx_12_6_pos 0
+#define        reg_dca_tone_idx_12_6_len 7
+#define        reg_dca_tone_idx_12_6_lsb 6
+#define xd_p_reg_dca_data_vld  0xA173
+#define        reg_dca_data_vld_pos 0
+#define        reg_dca_data_vld_len 1
+#define        reg_dca_data_vld_lsb 0
+#define xd_p_reg_dca_read_update       0xA173
+#define        reg_dca_read_update_pos 1
+#define        reg_dca_read_update_len 1
+#define        reg_dca_read_update_lsb 0
+#define xd_r_reg_dca_data_re_5_0       0xA173
+#define        reg_dca_data_re_5_0_pos 2
+#define        reg_dca_data_re_5_0_len 6
+#define        reg_dca_data_re_5_0_lsb 0
+#define xd_r_reg_dca_data_re_10_6      0xA174
+#define        reg_dca_data_re_10_6_pos 0
+#define        reg_dca_data_re_10_6_len 5
+#define        reg_dca_data_re_10_6_lsb 6
+#define xd_r_reg_dca_data_im_7_0       0xA175
+#define        reg_dca_data_im_7_0_pos 0
+#define        reg_dca_data_im_7_0_len 8
+#define        reg_dca_data_im_7_0_lsb 0
+#define xd_r_reg_dca_data_im_10_8      0xA176
+#define        reg_dca_data_im_10_8_pos 0
+#define        reg_dca_data_im_10_8_len 3
+#define        reg_dca_data_im_10_8_lsb 8
+#define xd_r_reg_dca_data_h2_7_0       0xA178
+#define        reg_dca_data_h2_7_0_pos 0
+#define        reg_dca_data_h2_7_0_len 8
+#define        reg_dca_data_h2_7_0_lsb 0
+#define xd_r_reg_dca_data_h2_9_8       0xA179
+#define        reg_dca_data_h2_9_8_pos 0
+#define        reg_dca_data_h2_9_8_len 2
+#define        reg_dca_data_h2_9_8_lsb 8
+#define xd_p_reg_f_adc_7_0     0xA180
+#define        reg_f_adc_7_0_pos 0
+#define        reg_f_adc_7_0_len 8
+#define        reg_f_adc_7_0_lsb 0
+#define xd_p_reg_f_adc_15_8    0xA181
+#define        reg_f_adc_15_8_pos 0
+#define        reg_f_adc_15_8_len 8
+#define        reg_f_adc_15_8_lsb 8
+#define xd_p_reg_f_adc_23_16   0xA182
+#define        reg_f_adc_23_16_pos 0
+#define        reg_f_adc_23_16_len 8
+#define        reg_f_adc_23_16_lsb 16
+#define xd_r_intp_mu_7_0       0xA190
+#define        intp_mu_7_0_pos 0
+#define        intp_mu_7_0_len 8
+#define        intp_mu_7_0_lsb 0
+#define xd_r_intp_mu_15_8      0xA191
+#define        intp_mu_15_8_pos 0
+#define        intp_mu_15_8_len 8
+#define        intp_mu_15_8_lsb 8
+#define xd_r_intp_mu_19_16     0xA192
+#define        intp_mu_19_16_pos 0
+#define        intp_mu_19_16_len 4
+#define        intp_mu_19_16_lsb 16
+#define xd_p_reg_agc_rst       0xA1A0
+#define        reg_agc_rst_pos 0
+#define        reg_agc_rst_len 1
+#define        reg_agc_rst_lsb 0
+#define xd_p_rf_agc_en 0xA1A0
+#define        rf_agc_en_pos 1
+#define        rf_agc_en_len 1
+#define        rf_agc_en_lsb 0
+#define xd_p_rf_agc_dis        0xA1A0
+#define        rf_agc_dis_pos 2
+#define        rf_agc_dis_len 1
+#define        rf_agc_dis_lsb 0
+#define xd_p_if_agc_rst        0xA1A0
+#define        if_agc_rst_pos 3
+#define        if_agc_rst_len 1
+#define        if_agc_rst_lsb 0
+#define xd_p_if_agc_en 0xA1A0
+#define        if_agc_en_pos 4
+#define        if_agc_en_len 1
+#define        if_agc_en_lsb 0
+#define xd_p_if_agc_dis        0xA1A0
+#define        if_agc_dis_pos 5
+#define        if_agc_dis_len 1
+#define        if_agc_dis_lsb 0
+#define xd_p_agc_lock  0xA1A0
+#define        agc_lock_pos 6
+#define        agc_lock_len 1
+#define        agc_lock_lsb 0
+#define xd_p_reg_tinr_rst      0xA1A1
+#define        reg_tinr_rst_pos 0
+#define        reg_tinr_rst_len 1
+#define        reg_tinr_rst_lsb 0
+#define xd_p_reg_tinr_en       0xA1A1
+#define        reg_tinr_en_pos 1
+#define        reg_tinr_en_len 1
+#define        reg_tinr_en_lsb 0
+#define xd_p_reg_ccifs_en      0xA1A2
+#define        reg_ccifs_en_pos 0
+#define        reg_ccifs_en_len 1
+#define        reg_ccifs_en_lsb 0
+#define xd_p_reg_ccifs_dis     0xA1A2
+#define        reg_ccifs_dis_pos 1
+#define        reg_ccifs_dis_len 1
+#define        reg_ccifs_dis_lsb 0
+#define xd_p_reg_ccifs_rst     0xA1A2
+#define        reg_ccifs_rst_pos 2
+#define        reg_ccifs_rst_len 1
+#define        reg_ccifs_rst_lsb 0
+#define xd_p_reg_ccifs_byp     0xA1A2
+#define        reg_ccifs_byp_pos 3
+#define        reg_ccifs_byp_len 1
+#define        reg_ccifs_byp_lsb 0
+#define xd_p_reg_ccif_en       0xA1A3
+#define        reg_ccif_en_pos 0
+#define        reg_ccif_en_len 1
+#define        reg_ccif_en_lsb 0
+#define xd_p_reg_ccif_dis      0xA1A3
+#define        reg_ccif_dis_pos 1
+#define        reg_ccif_dis_len 1
+#define        reg_ccif_dis_lsb 0
+#define xd_p_reg_ccif_rst      0xA1A3
+#define        reg_ccif_rst_pos 2
+#define        reg_ccif_rst_len 1
+#define        reg_ccif_rst_lsb 0
+#define xd_p_reg_ccif_byp      0xA1A3
+#define        reg_ccif_byp_pos 3
+#define        reg_ccif_byp_len 1
+#define        reg_ccif_byp_lsb 0
+#define xd_p_dagc1_rst 0xA1A4
+#define        dagc1_rst_pos 0
+#define        dagc1_rst_len 1
+#define        dagc1_rst_lsb 0
+#define xd_p_dagc1_en  0xA1A4
+#define        dagc1_en_pos 1
+#define        dagc1_en_len 1
+#define        dagc1_en_lsb 0
+#define xd_p_dagc1_mode        0xA1A4
+#define        dagc1_mode_pos 2
+#define        dagc1_mode_len 2
+#define        dagc1_mode_lsb 0
+#define xd_p_dagc1_done        0xA1A4
+#define        dagc1_done_pos 4
+#define        dagc1_done_len 1
+#define        dagc1_done_lsb 0
+#define xd_p_ccid_rst  0xA1A5
+#define        ccid_rst_pos 0
+#define        ccid_rst_len 1
+#define        ccid_rst_lsb 0
+#define xd_p_ccid_en   0xA1A5
+#define        ccid_en_pos 1
+#define        ccid_en_len 1
+#define        ccid_en_lsb 0
+#define xd_p_ccid_mode 0xA1A5
+#define        ccid_mode_pos 2
+#define        ccid_mode_len 2
+#define        ccid_mode_lsb 0
+#define xd_p_ccid_done 0xA1A5
+#define        ccid_done_pos 4
+#define        ccid_done_len 1
+#define        ccid_done_lsb 0
+#define xd_r_ccid_deted        0xA1A5
+#define        ccid_deted_pos 5
+#define        ccid_deted_len 1
+#define        ccid_deted_lsb 0
+#define xd_p_ccid2_en  0xA1A5
+#define        ccid2_en_pos 6
+#define        ccid2_en_len 1
+#define        ccid2_en_lsb 0
+#define xd_p_ccid2_done        0xA1A5
+#define        ccid2_done_pos 7
+#define        ccid2_done_len 1
+#define        ccid2_done_lsb 0
+#define xd_p_reg_bfs_en        0xA1A6
+#define        reg_bfs_en_pos 0
+#define        reg_bfs_en_len 1
+#define        reg_bfs_en_lsb 0
+#define xd_p_reg_bfs_dis       0xA1A6
+#define        reg_bfs_dis_pos 1
+#define        reg_bfs_dis_len 1
+#define        reg_bfs_dis_lsb 0
+#define xd_p_reg_bfs_rst       0xA1A6
+#define        reg_bfs_rst_pos 2
+#define        reg_bfs_rst_len 1
+#define        reg_bfs_rst_lsb 0
+#define xd_p_reg_bfs_byp       0xA1A6
+#define        reg_bfs_byp_pos 3
+#define        reg_bfs_byp_len 1
+#define        reg_bfs_byp_lsb 0
+#define xd_p_reg_antif_en      0xA1A7
+#define        reg_antif_en_pos 0
+#define        reg_antif_en_len 1
+#define        reg_antif_en_lsb 0
+#define xd_p_reg_antif_dis     0xA1A7
+#define        reg_antif_dis_pos 1
+#define        reg_antif_dis_len 1
+#define        reg_antif_dis_lsb 0
+#define xd_p_reg_antif_rst     0xA1A7
+#define        reg_antif_rst_pos 2
+#define        reg_antif_rst_len 1
+#define        reg_antif_rst_lsb 0
+#define xd_p_reg_antif_byp     0xA1A7
+#define        reg_antif_byp_pos 3
+#define        reg_antif_byp_len 1
+#define        reg_antif_byp_lsb 0
+#define xd_p_intp_en   0xA1A8
+#define        intp_en_pos 0
+#define        intp_en_len 1
+#define        intp_en_lsb 0
+#define xd_p_intp_dis  0xA1A8
+#define        intp_dis_pos 1
+#define        intp_dis_len 1
+#define        intp_dis_lsb 0
+#define xd_p_intp_rst  0xA1A8
+#define        intp_rst_pos 2
+#define        intp_rst_len 1
+#define        intp_rst_lsb 0
+#define xd_p_intp_byp  0xA1A8
+#define        intp_byp_pos 3
+#define        intp_byp_len 1
+#define        intp_byp_lsb 0
+#define xd_p_reg_acif_en       0xA1A9
+#define        reg_acif_en_pos 0
+#define        reg_acif_en_len 1
+#define        reg_acif_en_lsb 0
+#define xd_p_reg_acif_dis      0xA1A9
+#define        reg_acif_dis_pos 1
+#define        reg_acif_dis_len 1
+#define        reg_acif_dis_lsb 0
+#define xd_p_reg_acif_rst      0xA1A9
+#define        reg_acif_rst_pos 2
+#define        reg_acif_rst_len 1
+#define        reg_acif_rst_lsb 0
+#define xd_p_reg_acif_byp      0xA1A9
+#define        reg_acif_byp_pos 3
+#define        reg_acif_byp_len 1
+#define        reg_acif_byp_lsb 0
+#define xd_p_reg_acif_sync_mode        0xA1A9
+#define        reg_acif_sync_mode_pos 4
+#define        reg_acif_sync_mode_len 1
+#define        reg_acif_sync_mode_lsb 0
+#define xd_p_dagc2_rst 0xA1AA
+#define        dagc2_rst_pos 0
+#define        dagc2_rst_len 1
+#define        dagc2_rst_lsb 0
+#define xd_p_dagc2_en  0xA1AA
+#define        dagc2_en_pos 1
+#define        dagc2_en_len 1
+#define        dagc2_en_lsb 0
+#define xd_p_dagc2_mode        0xA1AA
+#define        dagc2_mode_pos 2
+#define        dagc2_mode_len 2
+#define        dagc2_mode_lsb 0
+#define xd_p_dagc2_done        0xA1AA
+#define        dagc2_done_pos 4
+#define        dagc2_done_len 1
+#define        dagc2_done_lsb 0
+#define xd_p_reg_dca_en        0xA1AB
+#define        reg_dca_en_pos 0
+#define        reg_dca_en_len 1
+#define        reg_dca_en_lsb 0
+#define xd_p_dagc2_accumulate_num_2k_7_0       0xA1C0
+#define        dagc2_accumulate_num_2k_7_0_pos 0
+#define        dagc2_accumulate_num_2k_7_0_len 8
+#define        dagc2_accumulate_num_2k_7_0_lsb 0
+#define xd_p_dagc2_accumulate_num_2k_12_8      0xA1C1
+#define        dagc2_accumulate_num_2k_12_8_pos 0
+#define        dagc2_accumulate_num_2k_12_8_len 5
+#define        dagc2_accumulate_num_2k_12_8_lsb 8
+#define xd_p_dagc2_accumulate_num_8k_7_0       0xA1C2
+#define        dagc2_accumulate_num_8k_7_0_pos 0
+#define        dagc2_accumulate_num_8k_7_0_len 8
+#define        dagc2_accumulate_num_8k_7_0_lsb 0
+#define xd_p_dagc2_accumulate_num_8k_12_8      0xA1C3
+#define        dagc2_accumulate_num_8k_12_8_pos 0
+#define        dagc2_accumulate_num_8k_12_8_len 5
+#define        dagc2_accumulate_num_8k_12_8_lsb 8
+#define xd_p_dagc2_desired_level_2_0   0xA1C3
+#define        dagc2_desired_level_2_0_pos 5
+#define        dagc2_desired_level_2_0_len 3
+#define        dagc2_desired_level_2_0_lsb 0
+#define xd_p_dagc2_desired_level_8_3   0xA1C4
+#define        dagc2_desired_level_8_3_pos 0
+#define        dagc2_desired_level_8_3_len 6
+#define        dagc2_desired_level_8_3_lsb 3
+#define xd_p_dagc2_apply_delay 0xA1C5
+#define        dagc2_apply_delay_pos 0
+#define        dagc2_apply_delay_len 7
+#define        dagc2_apply_delay_lsb 0
+#define xd_p_dagc2_bypass_scale_ctl    0xA1C6
+#define        dagc2_bypass_scale_ctl_pos 0
+#define        dagc2_bypass_scale_ctl_len 3
+#define        dagc2_bypass_scale_ctl_lsb 0
+#define xd_p_dagc2_programmable_shift1 0xA1C7
+#define        dagc2_programmable_shift1_pos 0
+#define        dagc2_programmable_shift1_len 8
+#define        dagc2_programmable_shift1_lsb 0
+#define xd_p_dagc2_programmable_shift2 0xA1C8
+#define        dagc2_programmable_shift2_pos 0
+#define        dagc2_programmable_shift2_len 8
+#define        dagc2_programmable_shift2_lsb 0
+#define xd_p_reg_dagc2_in_sat_cnt_7_0  0xA1C9
+#define        reg_dagc2_in_sat_cnt_7_0_pos 0
+#define        reg_dagc2_in_sat_cnt_7_0_len 8
+#define        reg_dagc2_in_sat_cnt_7_0_lsb 0
+#define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA
+#define        reg_dagc2_in_sat_cnt_15_8_pos 0
+#define        reg_dagc2_in_sat_cnt_15_8_len 8
+#define        reg_dagc2_in_sat_cnt_15_8_lsb 8
+#define xd_p_reg_dagc2_in_sat_cnt_23_16        0xA1CB
+#define        reg_dagc2_in_sat_cnt_23_16_pos 0
+#define        reg_dagc2_in_sat_cnt_23_16_len 8
+#define        reg_dagc2_in_sat_cnt_23_16_lsb 16
+#define xd_p_reg_dagc2_in_sat_cnt_31_24        0xA1CC
+#define        reg_dagc2_in_sat_cnt_31_24_pos 0
+#define        reg_dagc2_in_sat_cnt_31_24_len 8
+#define        reg_dagc2_in_sat_cnt_31_24_lsb 24
+#define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD
+#define        reg_dagc2_out_sat_cnt_7_0_pos 0
+#define        reg_dagc2_out_sat_cnt_7_0_len 8
+#define        reg_dagc2_out_sat_cnt_7_0_lsb 0
+#define xd_p_reg_dagc2_out_sat_cnt_15_8        0xA1CE
+#define        reg_dagc2_out_sat_cnt_15_8_pos 0
+#define        reg_dagc2_out_sat_cnt_15_8_len 8
+#define        reg_dagc2_out_sat_cnt_15_8_lsb 8
+#define xd_p_reg_dagc2_out_sat_cnt_23_16       0xA1CF
+#define        reg_dagc2_out_sat_cnt_23_16_pos 0
+#define        reg_dagc2_out_sat_cnt_23_16_len 8
+#define        reg_dagc2_out_sat_cnt_23_16_lsb 16
+#define xd_p_reg_dagc2_out_sat_cnt_31_24       0xA1D0
+#define        reg_dagc2_out_sat_cnt_31_24_pos 0
+#define        reg_dagc2_out_sat_cnt_31_24_len 8
+#define        reg_dagc2_out_sat_cnt_31_24_lsb 24
+#define xd_r_dagc2_multiplier_7_0      0xA1D6
+#define        dagc2_multiplier_7_0_pos 0
+#define        dagc2_multiplier_7_0_len 8
+#define        dagc2_multiplier_7_0_lsb 0
+#define xd_r_dagc2_multiplier_15_8     0xA1D7
+#define        dagc2_multiplier_15_8_pos 0
+#define        dagc2_multiplier_15_8_len 8
+#define        dagc2_multiplier_15_8_lsb 8
+#define xd_r_dagc2_right_shift_bits    0xA1D8
+#define        dagc2_right_shift_bits_pos 0
+#define        dagc2_right_shift_bits_len 4
+#define        dagc2_right_shift_bits_lsb 0
+#define xd_p_cfoe_NS_coeff1_7_0        0xA200
+#define        cfoe_NS_coeff1_7_0_pos 0
+#define        cfoe_NS_coeff1_7_0_len 8
+#define        cfoe_NS_coeff1_7_0_lsb 0
+#define xd_p_cfoe_NS_coeff1_15_8       0xA201
+#define        cfoe_NS_coeff1_15_8_pos 0
+#define        cfoe_NS_coeff1_15_8_len 8
+#define        cfoe_NS_coeff1_15_8_lsb 8
+#define xd_p_cfoe_NS_coeff1_23_16      0xA202
+#define        cfoe_NS_coeff1_23_16_pos 0
+#define        cfoe_NS_coeff1_23_16_len 8
+#define        cfoe_NS_coeff1_23_16_lsb 16
+#define xd_p_cfoe_NS_coeff1_25_24      0xA203
+#define        cfoe_NS_coeff1_25_24_pos 0
+#define        cfoe_NS_coeff1_25_24_len 2
+#define        cfoe_NS_coeff1_25_24_lsb 24
+#define xd_p_cfoe_NS_coeff2_5_0        0xA203
+#define        cfoe_NS_coeff2_5_0_pos 2
+#define        cfoe_NS_coeff2_5_0_len 6
+#define        cfoe_NS_coeff2_5_0_lsb 0
+#define xd_p_cfoe_NS_coeff2_13_6       0xA204
+#define        cfoe_NS_coeff2_13_6_pos 0
+#define        cfoe_NS_coeff2_13_6_len 8
+#define        cfoe_NS_coeff2_13_6_lsb 6
+#define xd_p_cfoe_NS_coeff2_21_14      0xA205
+#define        cfoe_NS_coeff2_21_14_pos 0
+#define        cfoe_NS_coeff2_21_14_len 8
+#define        cfoe_NS_coeff2_21_14_lsb 14
+#define xd_p_cfoe_NS_coeff2_24_22      0xA206
+#define        cfoe_NS_coeff2_24_22_pos 0
+#define        cfoe_NS_coeff2_24_22_len 3
+#define        cfoe_NS_coeff2_24_22_lsb 22
+#define xd_p_cfoe_lf_c1_4_0    0xA206
+#define        cfoe_lf_c1_4_0_pos 3
+#define        cfoe_lf_c1_4_0_len 5
+#define        cfoe_lf_c1_4_0_lsb 0
+#define xd_p_cfoe_lf_c1_12_5   0xA207
+#define        cfoe_lf_c1_12_5_pos 0
+#define        cfoe_lf_c1_12_5_len 8
+#define        cfoe_lf_c1_12_5_lsb 5
+#define xd_p_cfoe_lf_c1_20_13  0xA208
+#define        cfoe_lf_c1_20_13_pos 0
+#define        cfoe_lf_c1_20_13_len 8
+#define        cfoe_lf_c1_20_13_lsb 13
+#define xd_p_cfoe_lf_c1_25_21  0xA209
+#define        cfoe_lf_c1_25_21_pos 0
+#define        cfoe_lf_c1_25_21_len 5
+#define        cfoe_lf_c1_25_21_lsb 21
+#define xd_p_cfoe_lf_c2_2_0    0xA209
+#define        cfoe_lf_c2_2_0_pos 5
+#define        cfoe_lf_c2_2_0_len 3
+#define        cfoe_lf_c2_2_0_lsb 0
+#define xd_p_cfoe_lf_c2_10_3   0xA20A
+#define        cfoe_lf_c2_10_3_pos 0
+#define        cfoe_lf_c2_10_3_len 8
+#define        cfoe_lf_c2_10_3_lsb 3
+#define xd_p_cfoe_lf_c2_18_11  0xA20B
+#define        cfoe_lf_c2_18_11_pos 0
+#define        cfoe_lf_c2_18_11_len 8
+#define        cfoe_lf_c2_18_11_lsb 11
+#define xd_p_cfoe_lf_c2_25_19  0xA20C
+#define        cfoe_lf_c2_25_19_pos 0
+#define        cfoe_lf_c2_25_19_len 7
+#define        cfoe_lf_c2_25_19_lsb 19
+#define xd_p_cfoe_ifod_7_0     0xA20D
+#define        cfoe_ifod_7_0_pos 0
+#define        cfoe_ifod_7_0_len 8
+#define        cfoe_ifod_7_0_lsb 0
+#define xd_p_cfoe_ifod_10_8    0xA20E
+#define        cfoe_ifod_10_8_pos 0
+#define        cfoe_ifod_10_8_len 3
+#define        cfoe_ifod_10_8_lsb 8
+#define xd_p_cfoe_Divg_ctr_th  0xA20E
+#define        cfoe_Divg_ctr_th_pos 4
+#define        cfoe_Divg_ctr_th_len 4
+#define        cfoe_Divg_ctr_th_lsb 0
+#define xd_p_cfoe_FOT_divg_th  0xA20F
+#define        cfoe_FOT_divg_th_pos 0
+#define        cfoe_FOT_divg_th_len 8
+#define        cfoe_FOT_divg_th_lsb 0
+#define xd_p_cfoe_FOT_cnvg_th  0xA210
+#define        cfoe_FOT_cnvg_th_pos 0
+#define        cfoe_FOT_cnvg_th_len 8
+#define        cfoe_FOT_cnvg_th_lsb 0
+#define xd_p_reg_cfoe_offset_7_0       0xA211
+#define        reg_cfoe_offset_7_0_pos 0
+#define        reg_cfoe_offset_7_0_len 8
+#define        reg_cfoe_offset_7_0_lsb 0
+#define xd_p_reg_cfoe_offset_9_8       0xA212
+#define        reg_cfoe_offset_9_8_pos 0
+#define        reg_cfoe_offset_9_8_len 2
+#define        reg_cfoe_offset_9_8_lsb 8
+#define xd_p_reg_cfoe_ifoe_sign_corr   0xA212
+#define        reg_cfoe_ifoe_sign_corr_pos 2
+#define        reg_cfoe_ifoe_sign_corr_len 1
+#define        reg_cfoe_ifoe_sign_corr_lsb 0
+#define xd_r_cfoe_fot_LF_output_7_0    0xA218
+#define        cfoe_fot_LF_output_7_0_pos 0
+#define        cfoe_fot_LF_output_7_0_len 8
+#define        cfoe_fot_LF_output_7_0_lsb 0
+#define xd_r_cfoe_fot_LF_output_15_8   0xA219
+#define        cfoe_fot_LF_output_15_8_pos 0
+#define        cfoe_fot_LF_output_15_8_len 8
+#define        cfoe_fot_LF_output_15_8_lsb 8
+#define xd_r_cfoe_ifo_metric_7_0       0xA21A
+#define        cfoe_ifo_metric_7_0_pos 0
+#define        cfoe_ifo_metric_7_0_len 8
+#define        cfoe_ifo_metric_7_0_lsb 0
+#define xd_r_cfoe_ifo_metric_15_8      0xA21B
+#define        cfoe_ifo_metric_15_8_pos 0
+#define        cfoe_ifo_metric_15_8_len 8
+#define        cfoe_ifo_metric_15_8_lsb 8
+#define xd_r_cfoe_ifo_metric_23_16     0xA21C
+#define        cfoe_ifo_metric_23_16_pos 0
+#define        cfoe_ifo_metric_23_16_len 8
+#define        cfoe_ifo_metric_23_16_lsb 16
+#define xd_p_ste_Nu    0xA220
+#define        ste_Nu_pos 0
+#define        ste_Nu_len 2
+#define        ste_Nu_lsb 0
+#define xd_p_ste_GI    0xA220
+#define        ste_GI_pos 2
+#define        ste_GI_len 3
+#define        ste_GI_lsb 0
+#define xd_p_ste_symbol_num    0xA221
+#define        ste_symbol_num_pos 0
+#define        ste_symbol_num_len 2
+#define        ste_symbol_num_lsb 0
+#define xd_p_ste_sample_num    0xA221
+#define        ste_sample_num_pos 2
+#define        ste_sample_num_len 2
+#define        ste_sample_num_lsb 0
+#define xd_p_reg_ste_buf_en    0xA221
+#define        reg_ste_buf_en_pos 7
+#define        reg_ste_buf_en_len 1
+#define        reg_ste_buf_en_lsb 0
+#define xd_p_ste_FFT_offset_7_0        0xA222
+#define        ste_FFT_offset_7_0_pos 0
+#define        ste_FFT_offset_7_0_len 8
+#define        ste_FFT_offset_7_0_lsb 0
+#define xd_p_ste_FFT_offset_11_8       0xA223
+#define        ste_FFT_offset_11_8_pos 0
+#define        ste_FFT_offset_11_8_len 4
+#define        ste_FFT_offset_11_8_lsb 8
+#define xd_p_reg_ste_tstmod    0xA223
+#define        reg_ste_tstmod_pos 5
+#define        reg_ste_tstmod_len 1
+#define        reg_ste_tstmod_lsb 0
+#define xd_p_ste_adv_start_7_0 0xA224
+#define        ste_adv_start_7_0_pos 0
+#define        ste_adv_start_7_0_len 8
+#define        ste_adv_start_7_0_lsb 0
+#define xd_p_ste_adv_start_10_8        0xA225
+#define        ste_adv_start_10_8_pos 0
+#define        ste_adv_start_10_8_len 3
+#define        ste_adv_start_10_8_lsb 8
+#define xd_p_ste_adv_stop      0xA226
+#define        ste_adv_stop_pos 0
+#define        ste_adv_stop_len 8
+#define        ste_adv_stop_lsb 0
+#define xd_r_ste_P_value_7_0   0xA228
+#define        ste_P_value_7_0_pos 0
+#define        ste_P_value_7_0_len 8
+#define        ste_P_value_7_0_lsb 0
+#define xd_r_ste_P_value_10_8  0xA229
+#define        ste_P_value_10_8_pos 0
+#define        ste_P_value_10_8_len 3
+#define        ste_P_value_10_8_lsb 8
+#define xd_r_ste_M_value_7_0   0xA22A
+#define        ste_M_value_7_0_pos 0
+#define        ste_M_value_7_0_len 8
+#define        ste_M_value_7_0_lsb 0
+#define xd_r_ste_M_value_10_8  0xA22B
+#define        ste_M_value_10_8_pos 0
+#define        ste_M_value_10_8_len 3
+#define        ste_M_value_10_8_lsb 8
+#define xd_r_ste_H1    0xA22C
+#define        ste_H1_pos 0
+#define        ste_H1_len 7
+#define        ste_H1_lsb 0
+#define xd_r_ste_H2    0xA22D
+#define        ste_H2_pos 0
+#define        ste_H2_len 7
+#define        ste_H2_lsb 0
+#define xd_r_ste_H3    0xA22E
+#define        ste_H3_pos 0
+#define        ste_H3_len 7
+#define        ste_H3_lsb 0
+#define xd_r_ste_H4    0xA22F
+#define        ste_H4_pos 0
+#define        ste_H4_len 7
+#define        ste_H4_lsb 0
+#define xd_r_ste_Corr_value_I_7_0      0xA230
+#define        ste_Corr_value_I_7_0_pos 0
+#define        ste_Corr_value_I_7_0_len 8
+#define        ste_Corr_value_I_7_0_lsb 0
+#define xd_r_ste_Corr_value_I_15_8     0xA231
+#define        ste_Corr_value_I_15_8_pos 0
+#define        ste_Corr_value_I_15_8_len 8
+#define        ste_Corr_value_I_15_8_lsb 8
+#define xd_r_ste_Corr_value_I_23_16    0xA232
+#define        ste_Corr_value_I_23_16_pos 0
+#define        ste_Corr_value_I_23_16_len 8
+#define        ste_Corr_value_I_23_16_lsb 16
+#define xd_r_ste_Corr_value_I_27_24    0xA233
+#define        ste_Corr_value_I_27_24_pos 0
+#define        ste_Corr_value_I_27_24_len 4
+#define        ste_Corr_value_I_27_24_lsb 24
+#define xd_r_ste_Corr_value_Q_7_0      0xA234
+#define        ste_Corr_value_Q_7_0_pos 0
+#define        ste_Corr_value_Q_7_0_len 8
+#define        ste_Corr_value_Q_7_0_lsb 0
+#define xd_r_ste_Corr_value_Q_15_8     0xA235
+#define        ste_Corr_value_Q_15_8_pos 0
+#define        ste_Corr_value_Q_15_8_len 8
+#define        ste_Corr_value_Q_15_8_lsb 8
+#define xd_r_ste_Corr_value_Q_23_16    0xA236
+#define        ste_Corr_value_Q_23_16_pos 0
+#define        ste_Corr_value_Q_23_16_len 8
+#define        ste_Corr_value_Q_23_16_lsb 16
+#define xd_r_ste_Corr_value_Q_27_24    0xA237
+#define        ste_Corr_value_Q_27_24_pos 0
+#define        ste_Corr_value_Q_27_24_len 4
+#define        ste_Corr_value_Q_27_24_lsb 24
+#define xd_r_ste_J_num_7_0     0xA238
+#define        ste_J_num_7_0_pos 0
+#define        ste_J_num_7_0_len 8
+#define        ste_J_num_7_0_lsb 0
+#define xd_r_ste_J_num_15_8    0xA239
+#define        ste_J_num_15_8_pos 0
+#define        ste_J_num_15_8_len 8
+#define        ste_J_num_15_8_lsb 8
+#define xd_r_ste_J_num_23_16   0xA23A
+#define        ste_J_num_23_16_pos 0
+#define        ste_J_num_23_16_len 8
+#define        ste_J_num_23_16_lsb 16
+#define xd_r_ste_J_num_31_24   0xA23B
+#define        ste_J_num_31_24_pos 0
+#define        ste_J_num_31_24_len 8
+#define        ste_J_num_31_24_lsb 24
+#define xd_r_ste_J_den_7_0     0xA23C
+#define        ste_J_den_7_0_pos 0
+#define        ste_J_den_7_0_len 8
+#define        ste_J_den_7_0_lsb 0
+#define xd_r_ste_J_den_15_8    0xA23D
+#define        ste_J_den_15_8_pos 0
+#define        ste_J_den_15_8_len 8
+#define        ste_J_den_15_8_lsb 8
+#define xd_r_ste_J_den_18_16   0xA23E
+#define        ste_J_den_18_16_pos 0
+#define        ste_J_den_18_16_len 3
+#define        ste_J_den_18_16_lsb 16
+#define xd_r_ste_Beacon_Indicator      0xA23E
+#define        ste_Beacon_Indicator_pos 4
+#define        ste_Beacon_Indicator_len 1
+#define        ste_Beacon_Indicator_lsb 0
+#define xd_r_tpsd_Frame_Num    0xA250
+#define        tpsd_Frame_Num_pos 0
+#define        tpsd_Frame_Num_len 2
+#define        tpsd_Frame_Num_lsb 0
+#define xd_r_tpsd_Constel      0xA250
+#define        tpsd_Constel_pos 2
+#define        tpsd_Constel_len 2
+#define        tpsd_Constel_lsb 0
+#define xd_r_tpsd_GI   0xA250
+#define        tpsd_GI_pos 4
+#define        tpsd_GI_len 2
+#define        tpsd_GI_lsb 0
+#define xd_r_tpsd_Mode 0xA250
+#define        tpsd_Mode_pos 6
+#define        tpsd_Mode_len 2
+#define        tpsd_Mode_lsb 0
+#define xd_r_tpsd_CR_HP        0xA251
+#define        tpsd_CR_HP_pos 0
+#define        tpsd_CR_HP_len 3
+#define        tpsd_CR_HP_lsb 0
+#define xd_r_tpsd_CR_LP        0xA251
+#define        tpsd_CR_LP_pos 3
+#define        tpsd_CR_LP_len 3
+#define        tpsd_CR_LP_lsb 0
+#define xd_r_tpsd_Hie  0xA252
+#define        tpsd_Hie_pos 0
+#define        tpsd_Hie_len 3
+#define        tpsd_Hie_lsb 0
+#define xd_r_tpsd_Res_Bits     0xA252
+#define        tpsd_Res_Bits_pos 3
+#define        tpsd_Res_Bits_len 5
+#define        tpsd_Res_Bits_lsb 0
+#define xd_r_tpsd_Res_Bits_0   0xA253
+#define        tpsd_Res_Bits_0_pos 0
+#define        tpsd_Res_Bits_0_len 1
+#define        tpsd_Res_Bits_0_lsb 0
+#define xd_r_tpsd_LengthInd    0xA253
+#define        tpsd_LengthInd_pos 1
+#define        tpsd_LengthInd_len 6
+#define        tpsd_LengthInd_lsb 0
+#define xd_r_tpsd_Cell_Id_7_0  0xA254
+#define        tpsd_Cell_Id_7_0_pos 0
+#define        tpsd_Cell_Id_7_0_len 8
+#define        tpsd_Cell_Id_7_0_lsb 0
+#define xd_r_tpsd_Cell_Id_15_8 0xA255
+#define        tpsd_Cell_Id_15_8_pos 0
+#define        tpsd_Cell_Id_15_8_len 8
+#define        tpsd_Cell_Id_15_8_lsb 0
+#define xd_p_reg_fft_mask_tone0_7_0    0xA260
+#define        reg_fft_mask_tone0_7_0_pos 0
+#define        reg_fft_mask_tone0_7_0_len 8
+#define        reg_fft_mask_tone0_7_0_lsb 0
+#define xd_p_reg_fft_mask_tone0_12_8   0xA261
+#define        reg_fft_mask_tone0_12_8_pos 0
+#define        reg_fft_mask_tone0_12_8_len 5
+#define        reg_fft_mask_tone0_12_8_lsb 8
+#define xd_p_reg_fft_mask_tone1_7_0    0xA262
+#define        reg_fft_mask_tone1_7_0_pos 0
+#define        reg_fft_mask_tone1_7_0_len 8
+#define        reg_fft_mask_tone1_7_0_lsb 0
+#define xd_p_reg_fft_mask_tone1_12_8   0xA263
+#define        reg_fft_mask_tone1_12_8_pos 0
+#define        reg_fft_mask_tone1_12_8_len 5
+#define        reg_fft_mask_tone1_12_8_lsb 8
+#define xd_p_reg_fft_mask_tone2_7_0    0xA264
+#define        reg_fft_mask_tone2_7_0_pos 0
+#define        reg_fft_mask_tone2_7_0_len 8
+#define        reg_fft_mask_tone2_7_0_lsb 0
+#define xd_p_reg_fft_mask_tone2_12_8   0xA265
+#define        reg_fft_mask_tone2_12_8_pos 0
+#define        reg_fft_mask_tone2_12_8_len 5
+#define        reg_fft_mask_tone2_12_8_lsb 8
+#define xd_p_reg_fft_mask_tone3_7_0    0xA266
+#define        reg_fft_mask_tone3_7_0_pos 0
+#define        reg_fft_mask_tone3_7_0_len 8
+#define        reg_fft_mask_tone3_7_0_lsb 0
+#define xd_p_reg_fft_mask_tone3_12_8   0xA267
+#define        reg_fft_mask_tone3_12_8_pos 0
+#define        reg_fft_mask_tone3_12_8_len 5
+#define        reg_fft_mask_tone3_12_8_lsb 8
+#define xd_p_reg_fft_mask_from0_7_0    0xA268
+#define        reg_fft_mask_from0_7_0_pos 0
+#define        reg_fft_mask_from0_7_0_len 8
+#define        reg_fft_mask_from0_7_0_lsb 0
+#define xd_p_reg_fft_mask_from0_12_8   0xA269
+#define        reg_fft_mask_from0_12_8_pos 0
+#define        reg_fft_mask_from0_12_8_len 5
+#define        reg_fft_mask_from0_12_8_lsb 8
+#define xd_p_reg_fft_mask_to0_7_0      0xA26A
+#define        reg_fft_mask_to0_7_0_pos 0
+#define        reg_fft_mask_to0_7_0_len 8
+#define        reg_fft_mask_to0_7_0_lsb 0
+#define xd_p_reg_fft_mask_to0_12_8     0xA26B
+#define        reg_fft_mask_to0_12_8_pos 0
+#define        reg_fft_mask_to0_12_8_len 5
+#define        reg_fft_mask_to0_12_8_lsb 8
+#define xd_p_reg_fft_mask_from1_7_0    0xA26C
+#define        reg_fft_mask_from1_7_0_pos 0
+#define        reg_fft_mask_from1_7_0_len 8
+#define        reg_fft_mask_from1_7_0_lsb 0
+#define xd_p_reg_fft_mask_from1_12_8   0xA26D
+#define        reg_fft_mask_from1_12_8_pos 0
+#define        reg_fft_mask_from1_12_8_len 5
+#define        reg_fft_mask_from1_12_8_lsb 8
+#define xd_p_reg_fft_mask_to1_7_0      0xA26E
+#define        reg_fft_mask_to1_7_0_pos 0
+#define        reg_fft_mask_to1_7_0_len 8
+#define        reg_fft_mask_to1_7_0_lsb 0
+#define xd_p_reg_fft_mask_to1_12_8     0xA26F
+#define        reg_fft_mask_to1_12_8_pos 0
+#define        reg_fft_mask_to1_12_8_len 5
+#define        reg_fft_mask_to1_12_8_lsb 8
+#define xd_p_reg_cge_idx0_7_0  0xA280
+#define        reg_cge_idx0_7_0_pos 0
+#define        reg_cge_idx0_7_0_len 8
+#define        reg_cge_idx0_7_0_lsb 0
+#define xd_p_reg_cge_idx0_12_8 0xA281
+#define        reg_cge_idx0_12_8_pos 0
+#define        reg_cge_idx0_12_8_len 5
+#define        reg_cge_idx0_12_8_lsb 8
+#define xd_p_reg_cge_idx1_7_0  0xA282
+#define        reg_cge_idx1_7_0_pos 0
+#define        reg_cge_idx1_7_0_len 8
+#define        reg_cge_idx1_7_0_lsb 0
+#define xd_p_reg_cge_idx1_12_8 0xA283
+#define        reg_cge_idx1_12_8_pos 0
+#define        reg_cge_idx1_12_8_len 5
+#define        reg_cge_idx1_12_8_lsb 8
+#define xd_p_reg_cge_idx2_7_0  0xA284
+#define        reg_cge_idx2_7_0_pos 0
+#define        reg_cge_idx2_7_0_len 8
+#define        reg_cge_idx2_7_0_lsb 0
+#define xd_p_reg_cge_idx2_12_8 0xA285
+#define        reg_cge_idx2_12_8_pos 0
+#define        reg_cge_idx2_12_8_len 5
+#define        reg_cge_idx2_12_8_lsb 8
+#define xd_p_reg_cge_idx3_7_0  0xA286
+#define        reg_cge_idx3_7_0_pos 0
+#define        reg_cge_idx3_7_0_len 8
+#define        reg_cge_idx3_7_0_lsb 0
+#define xd_p_reg_cge_idx3_12_8 0xA287
+#define        reg_cge_idx3_12_8_pos 0
+#define        reg_cge_idx3_12_8_len 5
+#define        reg_cge_idx3_12_8_lsb 8
+#define xd_p_reg_cge_idx4_7_0  0xA288
+#define        reg_cge_idx4_7_0_pos 0
+#define        reg_cge_idx4_7_0_len 8
+#define        reg_cge_idx4_7_0_lsb 0
+#define xd_p_reg_cge_idx4_12_8 0xA289
+#define        reg_cge_idx4_12_8_pos 0
+#define        reg_cge_idx4_12_8_len 5
+#define        reg_cge_idx4_12_8_lsb 8
+#define xd_p_reg_cge_idx5_7_0  0xA28A
+#define        reg_cge_idx5_7_0_pos 0
+#define        reg_cge_idx5_7_0_len 8
+#define        reg_cge_idx5_7_0_lsb 0
+#define xd_p_reg_cge_idx5_12_8 0xA28B
+#define        reg_cge_idx5_12_8_pos 0
+#define        reg_cge_idx5_12_8_len 5
+#define        reg_cge_idx5_12_8_lsb 8
+#define xd_p_reg_cge_idx6_7_0  0xA28C
+#define        reg_cge_idx6_7_0_pos 0
+#define        reg_cge_idx6_7_0_len 8
+#define        reg_cge_idx6_7_0_lsb 0
+#define xd_p_reg_cge_idx6_12_8 0xA28D
+#define        reg_cge_idx6_12_8_pos 0
+#define        reg_cge_idx6_12_8_len 5
+#define        reg_cge_idx6_12_8_lsb 8
+#define xd_p_reg_cge_idx7_7_0  0xA28E
+#define        reg_cge_idx7_7_0_pos 0
+#define        reg_cge_idx7_7_0_len 8
+#define        reg_cge_idx7_7_0_lsb 0
+#define xd_p_reg_cge_idx7_12_8 0xA28F
+#define        reg_cge_idx7_12_8_pos 0
+#define        reg_cge_idx7_12_8_len 5
+#define        reg_cge_idx7_12_8_lsb 8
+#define xd_p_reg_cge_idx8_7_0  0xA290
+#define        reg_cge_idx8_7_0_pos 0
+#define        reg_cge_idx8_7_0_len 8
+#define        reg_cge_idx8_7_0_lsb 0
+#define xd_p_reg_cge_idx8_12_8 0xA291
+#define        reg_cge_idx8_12_8_pos 0
+#define        reg_cge_idx8_12_8_len 5
+#define        reg_cge_idx8_12_8_lsb 8
+#define xd_p_reg_cge_idx9_7_0  0xA292
+#define        reg_cge_idx9_7_0_pos 0
+#define        reg_cge_idx9_7_0_len 8
+#define        reg_cge_idx9_7_0_lsb 0
+#define xd_p_reg_cge_idx9_12_8 0xA293
+#define        reg_cge_idx9_12_8_pos 0
+#define        reg_cge_idx9_12_8_len 5
+#define        reg_cge_idx9_12_8_lsb 8
+#define xd_p_reg_cge_idx10_7_0 0xA294
+#define        reg_cge_idx10_7_0_pos 0
+#define        reg_cge_idx10_7_0_len 8
+#define        reg_cge_idx10_7_0_lsb 0
+#define xd_p_reg_cge_idx10_12_8        0xA295
+#define        reg_cge_idx10_12_8_pos 0
+#define        reg_cge_idx10_12_8_len 5
+#define        reg_cge_idx10_12_8_lsb 8
+#define xd_p_reg_cge_idx11_7_0 0xA296
+#define        reg_cge_idx11_7_0_pos 0
+#define        reg_cge_idx11_7_0_len 8
+#define        reg_cge_idx11_7_0_lsb 0
+#define xd_p_reg_cge_idx11_12_8        0xA297
+#define        reg_cge_idx11_12_8_pos 0
+#define        reg_cge_idx11_12_8_len 5
+#define        reg_cge_idx11_12_8_lsb 8
+#define xd_p_reg_cge_idx12_7_0 0xA298
+#define        reg_cge_idx12_7_0_pos 0
+#define        reg_cge_idx12_7_0_len 8
+#define        reg_cge_idx12_7_0_lsb 0
+#define xd_p_reg_cge_idx12_12_8        0xA299
+#define        reg_cge_idx12_12_8_pos 0
+#define        reg_cge_idx12_12_8_len 5
+#define        reg_cge_idx12_12_8_lsb 8
+#define xd_p_reg_cge_idx13_7_0 0xA29A
+#define        reg_cge_idx13_7_0_pos 0
+#define        reg_cge_idx13_7_0_len 8
+#define        reg_cge_idx13_7_0_lsb 0
+#define xd_p_reg_cge_idx13_12_8        0xA29B
+#define        reg_cge_idx13_12_8_pos 0
+#define        reg_cge_idx13_12_8_len 5
+#define        reg_cge_idx13_12_8_lsb 8
+#define xd_p_reg_cge_idx14_7_0 0xA29C
+#define        reg_cge_idx14_7_0_pos 0
+#define        reg_cge_idx14_7_0_len 8
+#define        reg_cge_idx14_7_0_lsb 0
+#define xd_p_reg_cge_idx14_12_8        0xA29D
+#define        reg_cge_idx14_12_8_pos 0
+#define        reg_cge_idx14_12_8_len 5
+#define        reg_cge_idx14_12_8_lsb 8
+#define xd_p_reg_cge_idx15_7_0 0xA29E
+#define        reg_cge_idx15_7_0_pos 0
+#define        reg_cge_idx15_7_0_len 8
+#define        reg_cge_idx15_7_0_lsb 0
+#define xd_p_reg_cge_idx15_12_8        0xA29F
+#define        reg_cge_idx15_12_8_pos 0
+#define        reg_cge_idx15_12_8_len 5
+#define        reg_cge_idx15_12_8_lsb 8
+#define xd_r_reg_fft_crc       0xA2A8
+#define        reg_fft_crc_pos 0
+#define        reg_fft_crc_len 8
+#define        reg_fft_crc_lsb 0
+#define xd_p_fd_fft_shift_max  0xA2A9
+#define        fd_fft_shift_max_pos 0
+#define        fd_fft_shift_max_len 4
+#define        fd_fft_shift_max_lsb 0
+#define xd_r_fd_fft_shift      0xA2A9
+#define        fd_fft_shift_pos 4
+#define        fd_fft_shift_len 4
+#define        fd_fft_shift_lsb 0
+#define xd_r_fd_fft_frame_num  0xA2AA
+#define        fd_fft_frame_num_pos 0
+#define        fd_fft_frame_num_len 2
+#define        fd_fft_frame_num_lsb 0
+#define xd_r_fd_fft_symbol_count       0xA2AB
+#define        fd_fft_symbol_count_pos 0
+#define        fd_fft_symbol_count_len 7
+#define        fd_fft_symbol_count_lsb 0
+#define xd_r_reg_fft_idx_max_7_0       0xA2AC
+#define        reg_fft_idx_max_7_0_pos 0
+#define        reg_fft_idx_max_7_0_len 8
+#define        reg_fft_idx_max_7_0_lsb 0
+#define xd_r_reg_fft_idx_max_12_8      0xA2AD
+#define        reg_fft_idx_max_12_8_pos 0
+#define        reg_fft_idx_max_12_8_len 5
+#define        reg_fft_idx_max_12_8_lsb 8
+#define xd_p_reg_cge_program   0xA2AE
+#define        reg_cge_program_pos 0
+#define        reg_cge_program_len 1
+#define        reg_cge_program_lsb 0
+#define xd_p_reg_cge_fixed     0xA2AE
+#define        reg_cge_fixed_pos 1
+#define        reg_cge_fixed_len 1
+#define        reg_cge_fixed_lsb 0
+#define xd_p_reg_fft_rotate_en 0xA2AE
+#define        reg_fft_rotate_en_pos 2
+#define        reg_fft_rotate_en_len 1
+#define        reg_fft_rotate_en_lsb 0
+#define xd_p_reg_fft_rotate_base_4_0   0xA2AE
+#define        reg_fft_rotate_base_4_0_pos 3
+#define        reg_fft_rotate_base_4_0_len 5
+#define        reg_fft_rotate_base_4_0_lsb 0
+#define xd_p_reg_fft_rotate_base_12_5  0xA2AF
+#define        reg_fft_rotate_base_12_5_pos 0
+#define        reg_fft_rotate_base_12_5_len 8
+#define        reg_fft_rotate_base_12_5_lsb 5
+#define xd_p_reg_gp_trigger_fd 0xA2B8
+#define        reg_gp_trigger_fd_pos 0
+#define        reg_gp_trigger_fd_len 1
+#define        reg_gp_trigger_fd_lsb 0
+#define xd_p_reg_trigger_sel_fd        0xA2B8
+#define        reg_trigger_sel_fd_pos 1
+#define        reg_trigger_sel_fd_len 2
+#define        reg_trigger_sel_fd_lsb 0
+#define xd_p_reg_trigger_module_sel_fd 0xA2B9
+#define        reg_trigger_module_sel_fd_pos 0
+#define        reg_trigger_module_sel_fd_len 6
+#define        reg_trigger_module_sel_fd_lsb 0
+#define xd_p_reg_trigger_set_sel_fd    0xA2BA
+#define        reg_trigger_set_sel_fd_pos 0
+#define        reg_trigger_set_sel_fd_len 6
+#define        reg_trigger_set_sel_fd_lsb 0
+#define xd_p_reg_fd_noname_7_0 0xA2BC
+#define        reg_fd_noname_7_0_pos 0
+#define        reg_fd_noname_7_0_len 8
+#define        reg_fd_noname_7_0_lsb 0
+#define xd_p_reg_fd_noname_15_8        0xA2BD
+#define        reg_fd_noname_15_8_pos 0
+#define        reg_fd_noname_15_8_len 8
+#define        reg_fd_noname_15_8_lsb 8
+#define xd_p_reg_fd_noname_23_16       0xA2BE
+#define        reg_fd_noname_23_16_pos 0
+#define        reg_fd_noname_23_16_len 8
+#define        reg_fd_noname_23_16_lsb 16
+#define xd_p_reg_fd_noname_31_24       0xA2BF
+#define        reg_fd_noname_31_24_pos 0
+#define        reg_fd_noname_31_24_len 8
+#define        reg_fd_noname_31_24_lsb 24
+#define xd_r_fd_fpcc_cp_corr_signn     0xA2C0
+#define        fd_fpcc_cp_corr_signn_pos 0
+#define        fd_fpcc_cp_corr_signn_len 8
+#define        fd_fpcc_cp_corr_signn_lsb 0
+#define xd_p_reg_feq_s1        0xA2C1
+#define        reg_feq_s1_pos 0
+#define        reg_feq_s1_len 5
+#define        reg_feq_s1_lsb 0
+#define xd_p_fd_fpcc_cp_corr_tone_th   0xA2C2
+#define        fd_fpcc_cp_corr_tone_th_pos 0
+#define        fd_fpcc_cp_corr_tone_th_len 6
+#define        fd_fpcc_cp_corr_tone_th_lsb 0
+#define xd_p_fd_fpcc_cp_corr_symbol_log_th     0xA2C3
+#define        fd_fpcc_cp_corr_symbol_log_th_pos 0
+#define        fd_fpcc_cp_corr_symbol_log_th_len 4
+#define        fd_fpcc_cp_corr_symbol_log_th_lsb 0
+#define xd_p_fd_fpcc_cp_corr_int       0xA2C4
+#define        fd_fpcc_cp_corr_int_pos 0
+#define        fd_fpcc_cp_corr_int_len 1
+#define        fd_fpcc_cp_corr_int_lsb 0
+#define xd_p_reg_sfoe_ns_7_0   0xA320
+#define        reg_sfoe_ns_7_0_pos 0
+#define        reg_sfoe_ns_7_0_len 8
+#define        reg_sfoe_ns_7_0_lsb 0
+#define xd_p_reg_sfoe_ns_14_8  0xA321
+#define        reg_sfoe_ns_14_8_pos 0
+#define        reg_sfoe_ns_14_8_len 7
+#define        reg_sfoe_ns_14_8_lsb 8
+#define xd_p_reg_sfoe_c1_7_0   0xA322
+#define        reg_sfoe_c1_7_0_pos 0
+#define        reg_sfoe_c1_7_0_len 8
+#define        reg_sfoe_c1_7_0_lsb 0
+#define xd_p_reg_sfoe_c1_15_8  0xA323
+#define        reg_sfoe_c1_15_8_pos 0
+#define        reg_sfoe_c1_15_8_len 8
+#define        reg_sfoe_c1_15_8_lsb 8
+#define xd_p_reg_sfoe_c1_17_16 0xA324
+#define        reg_sfoe_c1_17_16_pos 0
+#define        reg_sfoe_c1_17_16_len 2
+#define        reg_sfoe_c1_17_16_lsb 16
+#define xd_p_reg_sfoe_c2_7_0   0xA325
+#define        reg_sfoe_c2_7_0_pos 0
+#define        reg_sfoe_c2_7_0_len 8
+#define        reg_sfoe_c2_7_0_lsb 0
+#define xd_p_reg_sfoe_c2_15_8  0xA326
+#define        reg_sfoe_c2_15_8_pos 0
+#define        reg_sfoe_c2_15_8_len 8
+#define        reg_sfoe_c2_15_8_lsb 8
+#define xd_p_reg_sfoe_c2_17_16 0xA327
+#define        reg_sfoe_c2_17_16_pos 0
+#define        reg_sfoe_c2_17_16_len 2
+#define        reg_sfoe_c2_17_16_lsb 16
+#define xd_r_reg_sfoe_out_9_2  0xA328
+#define        reg_sfoe_out_9_2_pos 0
+#define        reg_sfoe_out_9_2_len 8
+#define        reg_sfoe_out_9_2_lsb 0
+#define xd_r_reg_sfoe_out_1_0  0xA329
+#define        reg_sfoe_out_1_0_pos 0
+#define        reg_sfoe_out_1_0_len 2
+#define        reg_sfoe_out_1_0_lsb 0
+#define xd_p_reg_sfoe_lm_counter_th    0xA32A
+#define        reg_sfoe_lm_counter_th_pos 0
+#define        reg_sfoe_lm_counter_th_len 4
+#define        reg_sfoe_lm_counter_th_lsb 0
+#define xd_p_reg_sfoe_convg_th 0xA32B
+#define        reg_sfoe_convg_th_pos 0
+#define        reg_sfoe_convg_th_len 8
+#define        reg_sfoe_convg_th_lsb 0
+#define xd_p_reg_sfoe_divg_th  0xA32C
+#define        reg_sfoe_divg_th_pos 0
+#define        reg_sfoe_divg_th_len 8
+#define        reg_sfoe_divg_th_lsb 0
+#define xd_p_fd_tpsd_en        0xA330
+#define        fd_tpsd_en_pos 0
+#define        fd_tpsd_en_len 1
+#define        fd_tpsd_en_lsb 0
+#define xd_p_fd_tpsd_dis       0xA330
+#define        fd_tpsd_dis_pos 1
+#define        fd_tpsd_dis_len 1
+#define        fd_tpsd_dis_lsb 0
+#define xd_p_fd_tpsd_rst       0xA330
+#define        fd_tpsd_rst_pos 2
+#define        fd_tpsd_rst_len 1
+#define        fd_tpsd_rst_lsb 0
+#define xd_p_fd_tpsd_lock      0xA330
+#define        fd_tpsd_lock_pos 3
+#define        fd_tpsd_lock_len 1
+#define        fd_tpsd_lock_lsb 0
+#define xd_r_fd_tpsd_s19       0xA330
+#define        fd_tpsd_s19_pos 4
+#define        fd_tpsd_s19_len 1
+#define        fd_tpsd_s19_lsb 0
+#define xd_r_fd_tpsd_s17       0xA330
+#define        fd_tpsd_s17_pos 5
+#define        fd_tpsd_s17_len 1
+#define        fd_tpsd_s17_lsb 0
+#define xd_p_fd_sfr_ste_en     0xA331
+#define        fd_sfr_ste_en_pos 0
+#define        fd_sfr_ste_en_len 1
+#define        fd_sfr_ste_en_lsb 0
+#define xd_p_fd_sfr_ste_dis    0xA331
+#define        fd_sfr_ste_dis_pos 1
+#define        fd_sfr_ste_dis_len 1
+#define        fd_sfr_ste_dis_lsb 0
+#define xd_p_fd_sfr_ste_rst    0xA331
+#define        fd_sfr_ste_rst_pos 2
+#define        fd_sfr_ste_rst_len 1
+#define        fd_sfr_ste_rst_lsb 0
+#define xd_p_fd_sfr_ste_mode   0xA331
+#define        fd_sfr_ste_mode_pos 3
+#define        fd_sfr_ste_mode_len 1
+#define        fd_sfr_ste_mode_lsb 0
+#define xd_p_fd_sfr_ste_done   0xA331
+#define        fd_sfr_ste_done_pos 4
+#define        fd_sfr_ste_done_len 1
+#define        fd_sfr_ste_done_lsb 0
+#define xd_p_reg_cfoe_ffoe_en  0xA332
+#define        reg_cfoe_ffoe_en_pos 0
+#define        reg_cfoe_ffoe_en_len 1
+#define        reg_cfoe_ffoe_en_lsb 0
+#define xd_p_reg_cfoe_ffoe_dis 0xA332
+#define        reg_cfoe_ffoe_dis_pos 1
+#define        reg_cfoe_ffoe_dis_len 1
+#define        reg_cfoe_ffoe_dis_lsb 0
+#define xd_p_reg_cfoe_ffoe_rst 0xA332
+#define        reg_cfoe_ffoe_rst_pos 2
+#define        reg_cfoe_ffoe_rst_len 1
+#define        reg_cfoe_ffoe_rst_lsb 0
+#define xd_p_reg_cfoe_ifoe_en  0xA332
+#define        reg_cfoe_ifoe_en_pos 3
+#define        reg_cfoe_ifoe_en_len 1
+#define        reg_cfoe_ifoe_en_lsb 0
+#define xd_p_reg_cfoe_ifoe_dis 0xA332
+#define        reg_cfoe_ifoe_dis_pos 4
+#define        reg_cfoe_ifoe_dis_len 1
+#define        reg_cfoe_ifoe_dis_lsb 0
+#define xd_p_reg_cfoe_ifoe_rst 0xA332
+#define        reg_cfoe_ifoe_rst_pos 5
+#define        reg_cfoe_ifoe_rst_len 1
+#define        reg_cfoe_ifoe_rst_lsb 0
+#define xd_p_reg_cfoe_fot_en   0xA332
+#define        reg_cfoe_fot_en_pos 6
+#define        reg_cfoe_fot_en_len 1
+#define        reg_cfoe_fot_en_lsb 0
+#define xd_p_reg_cfoe_fot_lm_en        0xA332
+#define        reg_cfoe_fot_lm_en_pos 7
+#define        reg_cfoe_fot_lm_en_len 1
+#define        reg_cfoe_fot_lm_en_lsb 0
+#define xd_p_reg_cfoe_fot_rst  0xA333
+#define        reg_cfoe_fot_rst_pos 0
+#define        reg_cfoe_fot_rst_len 1
+#define        reg_cfoe_fot_rst_lsb 0
+#define xd_r_fd_cfoe_ffoe_done 0xA333
+#define        fd_cfoe_ffoe_done_pos 1
+#define        fd_cfoe_ffoe_done_len 1
+#define        fd_cfoe_ffoe_done_lsb 0
+#define xd_p_fd_cfoe_metric_vld        0xA333
+#define        fd_cfoe_metric_vld_pos 2
+#define        fd_cfoe_metric_vld_len 1
+#define        fd_cfoe_metric_vld_lsb 0
+#define xd_p_reg_cfoe_ifod_vld 0xA333
+#define        reg_cfoe_ifod_vld_pos 3
+#define        reg_cfoe_ifod_vld_len 1
+#define        reg_cfoe_ifod_vld_lsb 0
+#define xd_r_fd_cfoe_ifoe_done 0xA333
+#define        fd_cfoe_ifoe_done_pos 4
+#define        fd_cfoe_ifoe_done_len 1
+#define        fd_cfoe_ifoe_done_lsb 0
+#define xd_r_fd_cfoe_fot_valid 0xA333
+#define        fd_cfoe_fot_valid_pos 5
+#define        fd_cfoe_fot_valid_len 1
+#define        fd_cfoe_fot_valid_lsb 0
+#define xd_p_reg_cfoe_divg_int 0xA333
+#define        reg_cfoe_divg_int_pos 6
+#define        reg_cfoe_divg_int_len 1
+#define        reg_cfoe_divg_int_lsb 0
+#define xd_r_reg_cfoe_divg_flag        0xA333
+#define        reg_cfoe_divg_flag_pos 7
+#define        reg_cfoe_divg_flag_len 1
+#define        reg_cfoe_divg_flag_lsb 0
+#define xd_p_reg_sfoe_en       0xA334
+#define        reg_sfoe_en_pos 0
+#define        reg_sfoe_en_len 1
+#define        reg_sfoe_en_lsb 0
+#define xd_p_reg_sfoe_dis      0xA334
+#define        reg_sfoe_dis_pos 1
+#define        reg_sfoe_dis_len 1
+#define        reg_sfoe_dis_lsb 0
+#define xd_p_reg_sfoe_rst      0xA334
+#define        reg_sfoe_rst_pos 2
+#define        reg_sfoe_rst_len 1
+#define        reg_sfoe_rst_lsb 0
+#define xd_p_reg_sfoe_vld_int  0xA334
+#define        reg_sfoe_vld_int_pos 3
+#define        reg_sfoe_vld_int_len 1
+#define        reg_sfoe_vld_int_lsb 0
+#define xd_p_reg_sfoe_lm_en    0xA334
+#define        reg_sfoe_lm_en_pos 4
+#define        reg_sfoe_lm_en_len 1
+#define        reg_sfoe_lm_en_lsb 0
+#define xd_p_reg_sfoe_divg_int 0xA334
+#define        reg_sfoe_divg_int_pos 5
+#define        reg_sfoe_divg_int_len 1
+#define        reg_sfoe_divg_int_lsb 0
+#define xd_r_reg_sfoe_divg_flag        0xA334
+#define        reg_sfoe_divg_flag_pos 6
+#define        reg_sfoe_divg_flag_len 1
+#define        reg_sfoe_divg_flag_lsb 0
+#define xd_p_reg_fft_rst       0xA335
+#define        reg_fft_rst_pos 0
+#define        reg_fft_rst_len 1
+#define        reg_fft_rst_lsb 0
+#define xd_p_reg_fft_fast_beacon       0xA335
+#define        reg_fft_fast_beacon_pos 1
+#define        reg_fft_fast_beacon_len 1
+#define        reg_fft_fast_beacon_lsb 0
+#define xd_p_reg_fft_fast_valid        0xA335
+#define        reg_fft_fast_valid_pos 2
+#define        reg_fft_fast_valid_len 1
+#define        reg_fft_fast_valid_lsb 0
+#define xd_p_reg_fft_mask_en   0xA335
+#define        reg_fft_mask_en_pos 3
+#define        reg_fft_mask_en_len 1
+#define        reg_fft_mask_en_lsb 0
+#define xd_p_reg_fft_crc_en    0xA335
+#define        reg_fft_crc_en_pos 4
+#define        reg_fft_crc_en_len 1
+#define        reg_fft_crc_en_lsb 0
+#define xd_p_reg_finr_en       0xA336
+#define        reg_finr_en_pos 0
+#define        reg_finr_en_len 1
+#define        reg_finr_en_lsb 0
+#define xd_p_fd_fste_en        0xA337
+#define        fd_fste_en_pos 1
+#define        fd_fste_en_len 1
+#define        fd_fste_en_lsb 0
+#define xd_p_fd_sqi_tps_level_shift    0xA338
+#define        fd_sqi_tps_level_shift_pos 0
+#define        fd_sqi_tps_level_shift_len 8
+#define        fd_sqi_tps_level_shift_lsb 0
+#define xd_p_fd_pilot_ma_len   0xA339
+#define        fd_pilot_ma_len_pos 0
+#define        fd_pilot_ma_len_len 6
+#define        fd_pilot_ma_len_lsb 0
+#define xd_p_fd_tps_ma_len     0xA33A
+#define        fd_tps_ma_len_pos 0
+#define        fd_tps_ma_len_len 6
+#define        fd_tps_ma_len_lsb 0
+#define xd_p_fd_sqi_s3 0xA33B
+#define        fd_sqi_s3_pos 0
+#define        fd_sqi_s3_len 8
+#define        fd_sqi_s3_lsb 0
+#define xd_p_fd_sqi_dummy_reg_0        0xA33C
+#define        fd_sqi_dummy_reg_0_pos 0
+#define        fd_sqi_dummy_reg_0_len 1
+#define        fd_sqi_dummy_reg_0_lsb 0
+#define xd_p_fd_sqi_debug_sel  0xA33C
+#define        fd_sqi_debug_sel_pos 1
+#define        fd_sqi_debug_sel_len 2
+#define        fd_sqi_debug_sel_lsb 0
+#define xd_p_fd_sqi_s2 0xA33C
+#define        fd_sqi_s2_pos 3
+#define        fd_sqi_s2_len 5
+#define        fd_sqi_s2_lsb 0
+#define xd_p_fd_sqi_dummy_reg_1        0xA33D
+#define        fd_sqi_dummy_reg_1_pos 0
+#define        fd_sqi_dummy_reg_1_len 1
+#define        fd_sqi_dummy_reg_1_lsb 0
+#define xd_p_fd_inr_ignore     0xA33D
+#define        fd_inr_ignore_pos 1
+#define        fd_inr_ignore_len 1
+#define        fd_inr_ignore_lsb 0
+#define xd_p_fd_pilot_ignore   0xA33D
+#define        fd_pilot_ignore_pos 2
+#define        fd_pilot_ignore_len 1
+#define        fd_pilot_ignore_lsb 0
+#define xd_p_fd_etps_ignore    0xA33D
+#define        fd_etps_ignore_pos 3
+#define        fd_etps_ignore_len 1
+#define        fd_etps_ignore_lsb 0
+#define xd_p_fd_sqi_s1 0xA33D
+#define        fd_sqi_s1_pos 4
+#define        fd_sqi_s1_len 4
+#define        fd_sqi_s1_lsb 0
+#define xd_p_reg_fste_ehw_7_0  0xA33E
+#define        reg_fste_ehw_7_0_pos 0
+#define        reg_fste_ehw_7_0_len 8
+#define        reg_fste_ehw_7_0_lsb 0
+#define xd_p_reg_fste_ehw_9_8  0xA33F
+#define        reg_fste_ehw_9_8_pos 0
+#define        reg_fste_ehw_9_8_len 2
+#define        reg_fste_ehw_9_8_lsb 8
+#define xd_p_reg_fste_i_adj_vld        0xA33F
+#define        reg_fste_i_adj_vld_pos 2
+#define        reg_fste_i_adj_vld_len 1
+#define        reg_fste_i_adj_vld_lsb 0
+#define xd_p_reg_fste_phase_ini_7_0    0xA340
+#define        reg_fste_phase_ini_7_0_pos 0
+#define        reg_fste_phase_ini_7_0_len 8
+#define        reg_fste_phase_ini_7_0_lsb 0
+#define xd_p_reg_fste_phase_ini_11_8   0xA341
+#define        reg_fste_phase_ini_11_8_pos 0
+#define        reg_fste_phase_ini_11_8_len 4
+#define        reg_fste_phase_ini_11_8_lsb 8
+#define xd_p_reg_fste_phase_inc_3_0    0xA341
+#define        reg_fste_phase_inc_3_0_pos 4
+#define        reg_fste_phase_inc_3_0_len 4
+#define        reg_fste_phase_inc_3_0_lsb 0
+#define xd_p_reg_fste_phase_inc_11_4   0xA342
+#define        reg_fste_phase_inc_11_4_pos 0
+#define        reg_fste_phase_inc_11_4_len 8
+#define        reg_fste_phase_inc_11_4_lsb 4
+#define xd_p_reg_fste_acum_cost_cnt_max        0xA343
+#define        reg_fste_acum_cost_cnt_max_pos 0
+#define        reg_fste_acum_cost_cnt_max_len 4
+#define        reg_fste_acum_cost_cnt_max_lsb 0
+#define xd_p_reg_fste_step_size_std    0xA343
+#define        reg_fste_step_size_std_pos 4
+#define        reg_fste_step_size_std_len 4
+#define        reg_fste_step_size_std_lsb 0
+#define xd_p_reg_fste_step_size_max    0xA344
+#define        reg_fste_step_size_max_pos 0
+#define        reg_fste_step_size_max_len 4
+#define        reg_fste_step_size_max_lsb 0
+#define xd_p_reg_fste_step_size_min    0xA344
+#define        reg_fste_step_size_min_pos 4
+#define        reg_fste_step_size_min_len 4
+#define        reg_fste_step_size_min_lsb 0
+#define xd_p_reg_fste_frac_step_size_7_0       0xA345
+#define        reg_fste_frac_step_size_7_0_pos 0
+#define        reg_fste_frac_step_size_7_0_len 8
+#define        reg_fste_frac_step_size_7_0_lsb 0
+#define xd_p_reg_fste_frac_step_size_15_8      0xA346
+#define        reg_fste_frac_step_size_15_8_pos 0
+#define        reg_fste_frac_step_size_15_8_len 8
+#define        reg_fste_frac_step_size_15_8_lsb 8
+#define xd_p_reg_fste_frac_step_size_19_16     0xA347
+#define        reg_fste_frac_step_size_19_16_pos 0
+#define        reg_fste_frac_step_size_19_16_len 4
+#define        reg_fste_frac_step_size_19_16_lsb 16
+#define xd_p_reg_fste_rpd_dir_cnt_max  0xA347
+#define        reg_fste_rpd_dir_cnt_max_pos 4
+#define        reg_fste_rpd_dir_cnt_max_len 4
+#define        reg_fste_rpd_dir_cnt_max_lsb 0
+#define xd_p_reg_fste_ehs      0xA348
+#define        reg_fste_ehs_pos 0
+#define        reg_fste_ehs_len 4
+#define        reg_fste_ehs_lsb 0
+#define xd_p_reg_fste_frac_cost_cnt_max_3_0    0xA348
+#define        reg_fste_frac_cost_cnt_max_3_0_pos 4
+#define        reg_fste_frac_cost_cnt_max_3_0_len 4
+#define        reg_fste_frac_cost_cnt_max_3_0_lsb 0
+#define xd_p_reg_fste_frac_cost_cnt_max_9_4    0xA349
+#define        reg_fste_frac_cost_cnt_max_9_4_pos 0
+#define        reg_fste_frac_cost_cnt_max_9_4_len 6
+#define        reg_fste_frac_cost_cnt_max_9_4_lsb 4
+#define xd_p_reg_fste_w0_7_0   0xA34A
+#define        reg_fste_w0_7_0_pos 0
+#define        reg_fste_w0_7_0_len 8
+#define        reg_fste_w0_7_0_lsb 0
+#define xd_p_reg_fste_w0_11_8  0xA34B
+#define        reg_fste_w0_11_8_pos 0
+#define        reg_fste_w0_11_8_len 4
+#define        reg_fste_w0_11_8_lsb 8
+#define xd_p_reg_fste_w1_3_0   0xA34B
+#define        reg_fste_w1_3_0_pos 4
+#define        reg_fste_w1_3_0_len 4
+#define        reg_fste_w1_3_0_lsb 0
+#define xd_p_reg_fste_w1_11_4  0xA34C
+#define        reg_fste_w1_11_4_pos 0
+#define        reg_fste_w1_11_4_len 8
+#define        reg_fste_w1_11_4_lsb 4
+#define xd_p_reg_fste_w2_7_0   0xA34D
+#define        reg_fste_w2_7_0_pos 0
+#define        reg_fste_w2_7_0_len 8
+#define        reg_fste_w2_7_0_lsb 0
+#define xd_p_reg_fste_w2_11_8  0xA34E
+#define        reg_fste_w2_11_8_pos 0
+#define        reg_fste_w2_11_8_len 4
+#define        reg_fste_w2_11_8_lsb 8
+#define xd_p_reg_fste_w3_3_0   0xA34E
+#define        reg_fste_w3_3_0_pos 4
+#define        reg_fste_w3_3_0_len 4
+#define        reg_fste_w3_3_0_lsb 0
+#define xd_p_reg_fste_w3_11_4  0xA34F
+#define        reg_fste_w3_11_4_pos 0
+#define        reg_fste_w3_11_4_len 8
+#define        reg_fste_w3_11_4_lsb 4
+#define xd_p_reg_fste_w4_7_0   0xA350
+#define        reg_fste_w4_7_0_pos 0
+#define        reg_fste_w4_7_0_len 8
+#define        reg_fste_w4_7_0_lsb 0
+#define xd_p_reg_fste_w4_11_8  0xA351
+#define        reg_fste_w4_11_8_pos 0
+#define        reg_fste_w4_11_8_len 4
+#define        reg_fste_w4_11_8_lsb 8
+#define xd_p_reg_fste_w5_3_0   0xA351
+#define        reg_fste_w5_3_0_pos 4
+#define        reg_fste_w5_3_0_len 4
+#define        reg_fste_w5_3_0_lsb 0
+#define xd_p_reg_fste_w5_11_4  0xA352
+#define        reg_fste_w5_11_4_pos 0
+#define        reg_fste_w5_11_4_len 8
+#define        reg_fste_w5_11_4_lsb 4
+#define xd_p_reg_fste_w6_7_0   0xA353
+#define        reg_fste_w6_7_0_pos 0
+#define        reg_fste_w6_7_0_len 8
+#define        reg_fste_w6_7_0_lsb 0
+#define xd_p_reg_fste_w6_11_8  0xA354
+#define        reg_fste_w6_11_8_pos 0
+#define        reg_fste_w6_11_8_len 4
+#define        reg_fste_w6_11_8_lsb 8
+#define xd_p_reg_fste_w7_3_0   0xA354
+#define        reg_fste_w7_3_0_pos 4
+#define        reg_fste_w7_3_0_len 4
+#define        reg_fste_w7_3_0_lsb 0
+#define xd_p_reg_fste_w7_11_4  0xA355
+#define        reg_fste_w7_11_4_pos 0
+#define        reg_fste_w7_11_4_len 8
+#define        reg_fste_w7_11_4_lsb 4
+#define xd_p_reg_fste_w8_7_0   0xA356
+#define        reg_fste_w8_7_0_pos 0
+#define        reg_fste_w8_7_0_len 8
+#define        reg_fste_w8_7_0_lsb 0
+#define xd_p_reg_fste_w8_11_8  0xA357
+#define        reg_fste_w8_11_8_pos 0
+#define        reg_fste_w8_11_8_len 4
+#define        reg_fste_w8_11_8_lsb 8
+#define xd_p_reg_fste_w9_3_0   0xA357
+#define        reg_fste_w9_3_0_pos 4
+#define        reg_fste_w9_3_0_len 4
+#define        reg_fste_w9_3_0_lsb 0
+#define xd_p_reg_fste_w9_11_4  0xA358
+#define        reg_fste_w9_11_4_pos 0
+#define        reg_fste_w9_11_4_len 8
+#define        reg_fste_w9_11_4_lsb 4
+#define xd_p_reg_fste_wa_7_0   0xA359
+#define        reg_fste_wa_7_0_pos 0
+#define        reg_fste_wa_7_0_len 8
+#define        reg_fste_wa_7_0_lsb 0
+#define xd_p_reg_fste_wa_11_8  0xA35A
+#define        reg_fste_wa_11_8_pos 0
+#define        reg_fste_wa_11_8_len 4
+#define        reg_fste_wa_11_8_lsb 8
+#define xd_p_reg_fste_wb_3_0   0xA35A
+#define        reg_fste_wb_3_0_pos 4
+#define        reg_fste_wb_3_0_len 4
+#define        reg_fste_wb_3_0_lsb 0
+#define xd_p_reg_fste_wb_11_4  0xA35B
+#define        reg_fste_wb_11_4_pos 0
+#define        reg_fste_wb_11_4_len 8
+#define        reg_fste_wb_11_4_lsb 4
+#define xd_r_fd_fste_i_adj     0xA35C
+#define        fd_fste_i_adj_pos 0
+#define        fd_fste_i_adj_len 5
+#define        fd_fste_i_adj_lsb 0
+#define xd_r_fd_fste_f_adj_7_0 0xA35D
+#define        fd_fste_f_adj_7_0_pos 0
+#define        fd_fste_f_adj_7_0_len 8
+#define        fd_fste_f_adj_7_0_lsb 0
+#define xd_r_fd_fste_f_adj_15_8        0xA35E
+#define        fd_fste_f_adj_15_8_pos 0
+#define        fd_fste_f_adj_15_8_len 8
+#define        fd_fste_f_adj_15_8_lsb 8
+#define xd_r_fd_fste_f_adj_19_16       0xA35F
+#define        fd_fste_f_adj_19_16_pos 0
+#define        fd_fste_f_adj_19_16_len 4
+#define        fd_fste_f_adj_19_16_lsb 16
+#define xd_p_reg_feq_Leak_Bypass       0xA366
+#define        reg_feq_Leak_Bypass_pos 0
+#define        reg_feq_Leak_Bypass_len 1
+#define        reg_feq_Leak_Bypass_lsb 0
+#define xd_p_reg_feq_Leak_Mneg1        0xA366
+#define        reg_feq_Leak_Mneg1_pos 1
+#define        reg_feq_Leak_Mneg1_len 3
+#define        reg_feq_Leak_Mneg1_lsb 0
+#define xd_p_reg_feq_Leak_B_ShiftQ     0xA366
+#define        reg_feq_Leak_B_ShiftQ_pos 4
+#define        reg_feq_Leak_B_ShiftQ_len 4
+#define        reg_feq_Leak_B_ShiftQ_lsb 0
+#define xd_p_reg_feq_Leak_B_Float0     0xA367
+#define        reg_feq_Leak_B_Float0_pos 0
+#define        reg_feq_Leak_B_Float0_len 8
+#define        reg_feq_Leak_B_Float0_lsb 0
+#define xd_p_reg_feq_Leak_B_Float1     0xA368
+#define        reg_feq_Leak_B_Float1_pos 0
+#define        reg_feq_Leak_B_Float1_len 8
+#define        reg_feq_Leak_B_Float1_lsb 0
+#define xd_p_reg_feq_Leak_B_Float2     0xA369
+#define        reg_feq_Leak_B_Float2_pos 0
+#define        reg_feq_Leak_B_Float2_len 8
+#define        reg_feq_Leak_B_Float2_lsb 0
+#define xd_p_reg_feq_Leak_B_Float3     0xA36A
+#define        reg_feq_Leak_B_Float3_pos 0
+#define        reg_feq_Leak_B_Float3_len 8
+#define        reg_feq_Leak_B_Float3_lsb 0
+#define xd_p_reg_feq_Leak_B_Float4     0xA36B
+#define        reg_feq_Leak_B_Float4_pos 0
+#define        reg_feq_Leak_B_Float4_len 8
+#define        reg_feq_Leak_B_Float4_lsb 0
+#define xd_p_reg_feq_Leak_B_Float5     0xA36C
+#define        reg_feq_Leak_B_Float5_pos 0
+#define        reg_feq_Leak_B_Float5_len 8
+#define        reg_feq_Leak_B_Float5_lsb 0
+#define xd_p_reg_feq_Leak_B_Float6     0xA36D
+#define        reg_feq_Leak_B_Float6_pos 0
+#define        reg_feq_Leak_B_Float6_len 8
+#define        reg_feq_Leak_B_Float6_lsb 0
+#define xd_p_reg_feq_Leak_B_Float7     0xA36E
+#define        reg_feq_Leak_B_Float7_pos 0
+#define        reg_feq_Leak_B_Float7_len 8
+#define        reg_feq_Leak_B_Float7_lsb 0
+#define xd_r_reg_feq_data_h2_7_0       0xA36F
+#define        reg_feq_data_h2_7_0_pos 0
+#define        reg_feq_data_h2_7_0_len 8
+#define        reg_feq_data_h2_7_0_lsb 0
+#define xd_r_reg_feq_data_h2_9_8       0xA370
+#define        reg_feq_data_h2_9_8_pos 0
+#define        reg_feq_data_h2_9_8_len 2
+#define        reg_feq_data_h2_9_8_lsb 8
+#define xd_p_reg_feq_leak_use_slice_tps        0xA371
+#define        reg_feq_leak_use_slice_tps_pos 0
+#define        reg_feq_leak_use_slice_tps_len 1
+#define        reg_feq_leak_use_slice_tps_lsb 0
+#define xd_p_reg_feq_read_update       0xA371
+#define        reg_feq_read_update_pos 1
+#define        reg_feq_read_update_len 1
+#define        reg_feq_read_update_lsb 0
+#define xd_p_reg_feq_data_vld  0xA371
+#define        reg_feq_data_vld_pos 2
+#define        reg_feq_data_vld_len 1
+#define        reg_feq_data_vld_lsb 0
+#define xd_p_reg_feq_tone_idx_4_0      0xA371
+#define        reg_feq_tone_idx_4_0_pos 3
+#define        reg_feq_tone_idx_4_0_len 5
+#define        reg_feq_tone_idx_4_0_lsb 0
+#define xd_p_reg_feq_tone_idx_12_5     0xA372
+#define        reg_feq_tone_idx_12_5_pos 0
+#define        reg_feq_tone_idx_12_5_len 8
+#define        reg_feq_tone_idx_12_5_lsb 5
+#define xd_r_reg_feq_data_re_7_0       0xA373
+#define        reg_feq_data_re_7_0_pos 0
+#define        reg_feq_data_re_7_0_len 8
+#define        reg_feq_data_re_7_0_lsb 0
+#define xd_r_reg_feq_data_re_10_8      0xA374
+#define        reg_feq_data_re_10_8_pos 0
+#define        reg_feq_data_re_10_8_len 3
+#define        reg_feq_data_re_10_8_lsb 8
+#define xd_r_reg_feq_data_im_7_0       0xA375
+#define        reg_feq_data_im_7_0_pos 0
+#define        reg_feq_data_im_7_0_len 8
+#define        reg_feq_data_im_7_0_lsb 0
+#define xd_r_reg_feq_data_im_10_8      0xA376
+#define        reg_feq_data_im_10_8_pos 0
+#define        reg_feq_data_im_10_8_len 3
+#define        reg_feq_data_im_10_8_lsb 8
+#define xd_r_reg_feq_y_re      0xA377
+#define        reg_feq_y_re_pos 0
+#define        reg_feq_y_re_len 8
+#define        reg_feq_y_re_lsb 0
+#define xd_r_reg_feq_y_im      0xA378
+#define        reg_feq_y_im_pos 0
+#define        reg_feq_y_im_len 8
+#define        reg_feq_y_im_lsb 0
+#define xd_r_reg_feq_h_re_7_0  0xA379
+#define        reg_feq_h_re_7_0_pos 0
+#define        reg_feq_h_re_7_0_len 8
+#define        reg_feq_h_re_7_0_lsb 0
+#define xd_r_reg_feq_h_re_8    0xA37A
+#define        reg_feq_h_re_8_pos 0
+#define        reg_feq_h_re_8_len 1
+#define        reg_feq_h_re_8_lsb 0
+#define xd_r_reg_feq_h_im_7_0  0xA37B
+#define        reg_feq_h_im_7_0_pos 0
+#define        reg_feq_h_im_7_0_len 8
+#define        reg_feq_h_im_7_0_lsb 0
+#define xd_r_reg_feq_h_im_8    0xA37C
+#define        reg_feq_h_im_8_pos 0
+#define        reg_feq_h_im_8_len 1
+#define        reg_feq_h_im_8_lsb 0
+#define xd_p_fec_super_frm_unit_7_0    0xA380
+#define        fec_super_frm_unit_7_0_pos 0
+#define        fec_super_frm_unit_7_0_len 8
+#define        fec_super_frm_unit_7_0_lsb 0
+#define xd_p_fec_super_frm_unit_15_8   0xA381
+#define        fec_super_frm_unit_15_8_pos 0
+#define        fec_super_frm_unit_15_8_len 8
+#define        fec_super_frm_unit_15_8_lsb 8
+#define xd_r_fec_vtb_err_bit_cnt_7_0   0xA382
+#define        fec_vtb_err_bit_cnt_7_0_pos 0
+#define        fec_vtb_err_bit_cnt_7_0_len 8
+#define        fec_vtb_err_bit_cnt_7_0_lsb 0
+#define xd_r_fec_vtb_err_bit_cnt_15_8  0xA383
+#define        fec_vtb_err_bit_cnt_15_8_pos 0
+#define        fec_vtb_err_bit_cnt_15_8_len 8
+#define        fec_vtb_err_bit_cnt_15_8_lsb 8
+#define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384
+#define        fec_vtb_err_bit_cnt_23_16_pos 0
+#define        fec_vtb_err_bit_cnt_23_16_len 8
+#define        fec_vtb_err_bit_cnt_23_16_lsb 16
+#define xd_p_fec_rsd_packet_unit_7_0   0xA385
+#define        fec_rsd_packet_unit_7_0_pos 0
+#define        fec_rsd_packet_unit_7_0_len 8
+#define        fec_rsd_packet_unit_7_0_lsb 0
+#define xd_p_fec_rsd_packet_unit_15_8  0xA386
+#define        fec_rsd_packet_unit_15_8_pos 0
+#define        fec_rsd_packet_unit_15_8_len 8
+#define        fec_rsd_packet_unit_15_8_lsb 8
+#define xd_r_fec_rsd_bit_err_cnt_7_0   0xA387
+#define        fec_rsd_bit_err_cnt_7_0_pos 0
+#define        fec_rsd_bit_err_cnt_7_0_len 8
+#define        fec_rsd_bit_err_cnt_7_0_lsb 0
+#define xd_r_fec_rsd_bit_err_cnt_15_8  0xA388
+#define        fec_rsd_bit_err_cnt_15_8_pos 0
+#define        fec_rsd_bit_err_cnt_15_8_len 8
+#define        fec_rsd_bit_err_cnt_15_8_lsb 8
+#define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389
+#define        fec_rsd_bit_err_cnt_23_16_pos 0
+#define        fec_rsd_bit_err_cnt_23_16_len 8
+#define        fec_rsd_bit_err_cnt_23_16_lsb 16
+#define xd_r_fec_rsd_abort_packet_cnt_7_0      0xA38A
+#define        fec_rsd_abort_packet_cnt_7_0_pos 0
+#define        fec_rsd_abort_packet_cnt_7_0_len 8
+#define        fec_rsd_abort_packet_cnt_7_0_lsb 0
+#define xd_r_fec_rsd_abort_packet_cnt_15_8     0xA38B
+#define        fec_rsd_abort_packet_cnt_15_8_pos 0
+#define        fec_rsd_abort_packet_cnt_15_8_len 8
+#define        fec_rsd_abort_packet_cnt_15_8_lsb 8
+#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0      0xA38C
+#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0
+#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8
+#define        fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0
+#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8     0xA38D
+#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0
+#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8
+#define        fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8
+#define xd_p_fec_RS_TH_1_7_0   0xA38E
+#define        fec_RS_TH_1_7_0_pos 0
+#define        fec_RS_TH_1_7_0_len 8
+#define        fec_RS_TH_1_7_0_lsb 0
+#define xd_p_fec_RS_TH_1_15_8  0xA38F
+#define        fec_RS_TH_1_15_8_pos 0
+#define        fec_RS_TH_1_15_8_len 8
+#define        fec_RS_TH_1_15_8_lsb 8
+#define xd_p_fec_RS_TH_2       0xA390
+#define        fec_RS_TH_2_pos 0
+#define        fec_RS_TH_2_len 8
+#define        fec_RS_TH_2_lsb 0
+#define xd_p_fec_mon_en        0xA391
+#define        fec_mon_en_pos 0
+#define        fec_mon_en_len 1
+#define        fec_mon_en_lsb 0
+#define xd_p_reg_b8to47        0xA391
+#define        reg_b8to47_pos 1
+#define        reg_b8to47_len 1
+#define        reg_b8to47_lsb 0
+#define xd_p_reg_rsd_sync_rep  0xA391
+#define        reg_rsd_sync_rep_pos 2
+#define        reg_rsd_sync_rep_len 1
+#define        reg_rsd_sync_rep_lsb 0
+#define xd_p_fec_rsd_retrain_rst       0xA391
+#define        fec_rsd_retrain_rst_pos 3
+#define        fec_rsd_retrain_rst_len 1
+#define        fec_rsd_retrain_rst_lsb 0
+#define xd_r_fec_rsd_ber_rdy   0xA391
+#define        fec_rsd_ber_rdy_pos 4
+#define        fec_rsd_ber_rdy_len 1
+#define        fec_rsd_ber_rdy_lsb 0
+#define xd_p_fec_rsd_ber_rst   0xA391
+#define        fec_rsd_ber_rst_pos 5
+#define        fec_rsd_ber_rst_len 1
+#define        fec_rsd_ber_rst_lsb 0
+#define xd_r_fec_vtb_ber_rdy   0xA391
+#define        fec_vtb_ber_rdy_pos 6
+#define        fec_vtb_ber_rdy_len 1
+#define        fec_vtb_ber_rdy_lsb 0
+#define xd_p_fec_vtb_ber_rst   0xA391
+#define        fec_vtb_ber_rst_pos 7
+#define        fec_vtb_ber_rst_len 1
+#define        fec_vtb_ber_rst_lsb 0
+#define xd_p_reg_vtb_clk40en   0xA392
+#define        reg_vtb_clk40en_pos 0
+#define        reg_vtb_clk40en_len 1
+#define        reg_vtb_clk40en_lsb 0
+#define xd_p_fec_vtb_rsd_mon_en        0xA392
+#define        fec_vtb_rsd_mon_en_pos 1
+#define        fec_vtb_rsd_mon_en_len 1
+#define        fec_vtb_rsd_mon_en_lsb 0
+#define xd_p_reg_fec_data_en   0xA392
+#define        reg_fec_data_en_pos 2
+#define        reg_fec_data_en_len 1
+#define        reg_fec_data_en_lsb 0
+#define xd_p_fec_dummy_reg_2   0xA392
+#define        fec_dummy_reg_2_pos 3
+#define        fec_dummy_reg_2_len 3
+#define        fec_dummy_reg_2_lsb 0
+#define xd_p_reg_sync_chk      0xA392
+#define        reg_sync_chk_pos 6
+#define        reg_sync_chk_len 1
+#define        reg_sync_chk_lsb 0
+#define xd_p_fec_rsd_bypass    0xA392
+#define        fec_rsd_bypass_pos 7
+#define        fec_rsd_bypass_len 1
+#define        fec_rsd_bypass_lsb 0
+#define xd_p_fec_sw_rst        0xA393
+#define        fec_sw_rst_pos 0
+#define        fec_sw_rst_len 1
+#define        fec_sw_rst_lsb 0
+#define xd_r_fec_vtb_pm_crc    0xA394
+#define        fec_vtb_pm_crc_pos 0
+#define        fec_vtb_pm_crc_len 8
+#define        fec_vtb_pm_crc_lsb 0
+#define xd_r_fec_vtb_tb_7_crc  0xA395
+#define        fec_vtb_tb_7_crc_pos 0
+#define        fec_vtb_tb_7_crc_len 8
+#define        fec_vtb_tb_7_crc_lsb 0
+#define xd_r_fec_vtb_tb_6_crc  0xA396
+#define        fec_vtb_tb_6_crc_pos 0
+#define        fec_vtb_tb_6_crc_len 8
+#define        fec_vtb_tb_6_crc_lsb 0
+#define xd_r_fec_vtb_tb_5_crc  0xA397
+#define        fec_vtb_tb_5_crc_pos 0
+#define        fec_vtb_tb_5_crc_len 8
+#define        fec_vtb_tb_5_crc_lsb 0
+#define xd_r_fec_vtb_tb_4_crc  0xA398
+#define        fec_vtb_tb_4_crc_pos 0
+#define        fec_vtb_tb_4_crc_len 8
+#define        fec_vtb_tb_4_crc_lsb 0
+#define xd_r_fec_vtb_tb_3_crc  0xA399
+#define        fec_vtb_tb_3_crc_pos 0
+#define        fec_vtb_tb_3_crc_len 8
+#define        fec_vtb_tb_3_crc_lsb 0
+#define xd_r_fec_vtb_tb_2_crc  0xA39A
+#define        fec_vtb_tb_2_crc_pos 0
+#define        fec_vtb_tb_2_crc_len 8
+#define        fec_vtb_tb_2_crc_lsb 0
+#define xd_r_fec_vtb_tb_1_crc  0xA39B
+#define        fec_vtb_tb_1_crc_pos 0
+#define        fec_vtb_tb_1_crc_len 8
+#define        fec_vtb_tb_1_crc_lsb 0
+#define xd_r_fec_vtb_tb_0_crc  0xA39C
+#define        fec_vtb_tb_0_crc_pos 0
+#define        fec_vtb_tb_0_crc_len 8
+#define        fec_vtb_tb_0_crc_lsb 0
+#define xd_r_fec_rsd_bank0_crc 0xA39D
+#define        fec_rsd_bank0_crc_pos 0
+#define        fec_rsd_bank0_crc_len 8
+#define        fec_rsd_bank0_crc_lsb 0
+#define xd_r_fec_rsd_bank1_crc 0xA39E
+#define        fec_rsd_bank1_crc_pos 0
+#define        fec_rsd_bank1_crc_len 8
+#define        fec_rsd_bank1_crc_lsb 0
+#define xd_r_fec_idi_vtb_crc   0xA39F
+#define        fec_idi_vtb_crc_pos 0
+#define        fec_idi_vtb_crc_len 8
+#define        fec_idi_vtb_crc_lsb 0
+#define xd_g_reg_tpsd_txmod    0xA3C0
+#define        reg_tpsd_txmod_pos 0
+#define        reg_tpsd_txmod_len 2
+#define        reg_tpsd_txmod_lsb 0
+#define xd_g_reg_tpsd_gi       0xA3C0
+#define        reg_tpsd_gi_pos 2
+#define        reg_tpsd_gi_len 2
+#define        reg_tpsd_gi_lsb 0
+#define xd_g_reg_tpsd_hier     0xA3C0
+#define        reg_tpsd_hier_pos 4
+#define        reg_tpsd_hier_len 3
+#define        reg_tpsd_hier_lsb 0
+#define xd_g_reg_bw    0xA3C1
+#define        reg_bw_pos 2
+#define        reg_bw_len 2
+#define        reg_bw_lsb 0
+#define xd_g_reg_dec_pri       0xA3C1
+#define        reg_dec_pri_pos 4
+#define        reg_dec_pri_len 1
+#define        reg_dec_pri_lsb 0
+#define xd_g_reg_tpsd_const    0xA3C1
+#define        reg_tpsd_const_pos 6
+#define        reg_tpsd_const_len 2
+#define        reg_tpsd_const_lsb 0
+#define xd_g_reg_tpsd_hpcr     0xA3C2
+#define        reg_tpsd_hpcr_pos 0
+#define        reg_tpsd_hpcr_len 3
+#define        reg_tpsd_hpcr_lsb 0
+#define xd_g_reg_tpsd_lpcr     0xA3C2
+#define        reg_tpsd_lpcr_pos 3
+#define        reg_tpsd_lpcr_len 3
+#define        reg_tpsd_lpcr_lsb 0
+#define xd_g_reg_ofsm_clk      0xA3D0
+#define        reg_ofsm_clk_pos 0
+#define        reg_ofsm_clk_len 3
+#define        reg_ofsm_clk_lsb 0
+#define xd_g_reg_fclk_cfg      0xA3D1
+#define        reg_fclk_cfg_pos 0
+#define        reg_fclk_cfg_len 1
+#define        reg_fclk_cfg_lsb 0
+#define xd_g_reg_fclk_idi      0xA3D1
+#define        reg_fclk_idi_pos 1
+#define        reg_fclk_idi_len 1
+#define        reg_fclk_idi_lsb 0
+#define xd_g_reg_fclk_odi      0xA3D1
+#define        reg_fclk_odi_pos 2
+#define        reg_fclk_odi_len 1
+#define        reg_fclk_odi_lsb 0
+#define xd_g_reg_fclk_rsd      0xA3D1
+#define        reg_fclk_rsd_pos 3
+#define        reg_fclk_rsd_len 1
+#define        reg_fclk_rsd_lsb 0
+#define xd_g_reg_fclk_vtb      0xA3D1
+#define        reg_fclk_vtb_pos 4
+#define        reg_fclk_vtb_len 1
+#define        reg_fclk_vtb_lsb 0
+#define xd_g_reg_fclk_cste     0xA3D1
+#define        reg_fclk_cste_pos 5
+#define        reg_fclk_cste_len 1
+#define        reg_fclk_cste_lsb 0
+#define xd_g_reg_fclk_mp2if    0xA3D1
+#define        reg_fclk_mp2if_pos 6
+#define        reg_fclk_mp2if_len 1
+#define        reg_fclk_mp2if_lsb 0
+#define xd_I2C_i2c_m_slave_addr        0xA400
+#define        i2c_m_slave_addr_pos 0
+#define        i2c_m_slave_addr_len 8
+#define        i2c_m_slave_addr_lsb 0
+#define xd_I2C_i2c_m_data1     0xA401
+#define        i2c_m_data1_pos 0
+#define        i2c_m_data1_len 8
+#define        i2c_m_data1_lsb 0
+#define xd_I2C_i2c_m_data2     0xA402
+#define        i2c_m_data2_pos 0
+#define        i2c_m_data2_len 8
+#define        i2c_m_data2_lsb 0
+#define xd_I2C_i2c_m_data3     0xA403
+#define        i2c_m_data3_pos 0
+#define        i2c_m_data3_len 8
+#define        i2c_m_data3_lsb 0
+#define xd_I2C_i2c_m_data4     0xA404
+#define        i2c_m_data4_pos 0
+#define        i2c_m_data4_len 8
+#define        i2c_m_data4_lsb 0
+#define xd_I2C_i2c_m_data5     0xA405
+#define        i2c_m_data5_pos 0
+#define        i2c_m_data5_len 8
+#define        i2c_m_data5_lsb 0
+#define xd_I2C_i2c_m_data6     0xA406
+#define        i2c_m_data6_pos 0
+#define        i2c_m_data6_len 8
+#define        i2c_m_data6_lsb 0
+#define xd_I2C_i2c_m_data7     0xA407
+#define        i2c_m_data7_pos 0
+#define        i2c_m_data7_len 8
+#define        i2c_m_data7_lsb 0
+#define xd_I2C_i2c_m_data8     0xA408
+#define        i2c_m_data8_pos 0
+#define        i2c_m_data8_len 8
+#define        i2c_m_data8_lsb 0
+#define xd_I2C_i2c_m_data9     0xA409
+#define        i2c_m_data9_pos 0
+#define        i2c_m_data9_len 8
+#define        i2c_m_data9_lsb 0
+#define xd_I2C_i2c_m_data10    0xA40A
+#define        i2c_m_data10_pos 0
+#define        i2c_m_data10_len 8
+#define        i2c_m_data10_lsb 0
+#define xd_I2C_i2c_m_data11    0xA40B
+#define        i2c_m_data11_pos 0
+#define        i2c_m_data11_len 8
+#define        i2c_m_data11_lsb 0
+#define xd_I2C_i2c_m_cmd_rw    0xA40C
+#define        i2c_m_cmd_rw_pos 0
+#define        i2c_m_cmd_rw_len 1
+#define        i2c_m_cmd_rw_lsb 0
+#define xd_I2C_i2c_m_cmd_rwlen 0xA40C
+#define        i2c_m_cmd_rwlen_pos 3
+#define        i2c_m_cmd_rwlen_len 4
+#define        i2c_m_cmd_rwlen_lsb 0
+#define xd_I2C_i2c_m_status_cmd_exe    0xA40D
+#define        i2c_m_status_cmd_exe_pos 0
+#define        i2c_m_status_cmd_exe_len 1
+#define        i2c_m_status_cmd_exe_lsb 0
+#define xd_I2C_i2c_m_status_wdat_done  0xA40D
+#define        i2c_m_status_wdat_done_pos 1
+#define        i2c_m_status_wdat_done_len 1
+#define        i2c_m_status_wdat_done_lsb 0
+#define xd_I2C_i2c_m_status_wdat_fail  0xA40D
+#define        i2c_m_status_wdat_fail_pos 2
+#define        i2c_m_status_wdat_fail_len 1
+#define        i2c_m_status_wdat_fail_lsb 0
+#define xd_I2C_i2c_m_period    0xA40E
+#define        i2c_m_period_pos 0
+#define        i2c_m_period_len 8
+#define        i2c_m_period_lsb 0
+#define xd_I2C_i2c_m_reg_msb_lsb       0xA40F
+#define        i2c_m_reg_msb_lsb_pos 0
+#define        i2c_m_reg_msb_lsb_len 1
+#define        i2c_m_reg_msb_lsb_lsb 0
+#define xd_I2C_reg_ofdm_rst    0xA40F
+#define        reg_ofdm_rst_pos 1
+#define        reg_ofdm_rst_len 1
+#define        reg_ofdm_rst_lsb 0
+#define xd_I2C_reg_sample_period_on_tuner      0xA40F
+#define        reg_sample_period_on_tuner_pos 2
+#define        reg_sample_period_on_tuner_len 1
+#define        reg_sample_period_on_tuner_lsb 0
+#define xd_I2C_reg_rst_i2c     0xA40F
+#define        reg_rst_i2c_pos 3
+#define        reg_rst_i2c_len 1
+#define        reg_rst_i2c_lsb 0
+#define xd_I2C_reg_ofdm_rst_en 0xA40F
+#define        reg_ofdm_rst_en_pos 4
+#define        reg_ofdm_rst_en_len 1
+#define        reg_ofdm_rst_en_lsb 0
+#define xd_I2C_reg_tuner_sda_sync_on   0xA40F
+#define        reg_tuner_sda_sync_on_pos 5
+#define        reg_tuner_sda_sync_on_len 1
+#define        reg_tuner_sda_sync_on_lsb 0
+#define xd_p_mp2if_data_access_disable_ofsm    0xA500
+#define        mp2if_data_access_disable_ofsm_pos 0
+#define        mp2if_data_access_disable_ofsm_len 1
+#define        mp2if_data_access_disable_ofsm_lsb 0
+#define xd_p_reg_mp2_sw_rst_ofsm       0xA500
+#define        reg_mp2_sw_rst_ofsm_pos 1
+#define        reg_mp2_sw_rst_ofsm_len 1
+#define        reg_mp2_sw_rst_ofsm_lsb 0
+#define xd_p_reg_mp2if_clk_en_ofsm     0xA500
+#define        reg_mp2if_clk_en_ofsm_pos 2
+#define        reg_mp2if_clk_en_ofsm_len 1
+#define        reg_mp2if_clk_en_ofsm_lsb 0
+#define xd_r_mp2if_sync_byte_locked    0xA500
+#define        mp2if_sync_byte_locked_pos 3
+#define        mp2if_sync_byte_locked_len 1
+#define        mp2if_sync_byte_locked_lsb 0
+#define xd_r_mp2if_ts_not_188  0xA500
+#define        mp2if_ts_not_188_pos 4
+#define        mp2if_ts_not_188_len 1
+#define        mp2if_ts_not_188_lsb 0
+#define xd_r_mp2if_psb_empty   0xA500
+#define        mp2if_psb_empty_pos 5
+#define        mp2if_psb_empty_len 1
+#define        mp2if_psb_empty_lsb 0
+#define xd_r_mp2if_psb_overflow        0xA500
+#define        mp2if_psb_overflow_pos 6
+#define        mp2if_psb_overflow_len 1
+#define        mp2if_psb_overflow_lsb 0
+#define xd_p_mp2if_keep_sf_sync_byte_ofsm      0xA500
+#define        mp2if_keep_sf_sync_byte_ofsm_pos 7
+#define        mp2if_keep_sf_sync_byte_ofsm_len 1
+#define        mp2if_keep_sf_sync_byte_ofsm_lsb 0
+#define xd_r_mp2if_psb_mp2if_num_pkt   0xA501
+#define        mp2if_psb_mp2if_num_pkt_pos 0
+#define        mp2if_psb_mp2if_num_pkt_len 6
+#define        mp2if_psb_mp2if_num_pkt_lsb 0
+#define xd_p_reg_mpeg_full_speed_ofsm  0xA501
+#define        reg_mpeg_full_speed_ofsm_pos 6
+#define        reg_mpeg_full_speed_ofsm_len 1
+#define        reg_mpeg_full_speed_ofsm_lsb 0
+#define xd_p_mp2if_mpeg_ser_mode_ofsm  0xA501
+#define        mp2if_mpeg_ser_mode_ofsm_pos 7
+#define        mp2if_mpeg_ser_mode_ofsm_len 1
+#define        mp2if_mpeg_ser_mode_ofsm_lsb 0
+#define xd_p_reg_sw_mon51      0xA600
+#define        reg_sw_mon51_pos 0
+#define        reg_sw_mon51_len 8
+#define        reg_sw_mon51_lsb 0
+#define xd_p_reg_top_pcsel     0xA601
+#define        reg_top_pcsel_pos 0
+#define        reg_top_pcsel_len 1
+#define        reg_top_pcsel_lsb 0
+#define xd_p_reg_top_rs232     0xA601
+#define        reg_top_rs232_pos 1
+#define        reg_top_rs232_len 1
+#define        reg_top_rs232_lsb 0
+#define xd_p_reg_top_pcout     0xA601
+#define        reg_top_pcout_pos 2
+#define        reg_top_pcout_len 1
+#define        reg_top_pcout_lsb 0
+#define xd_p_reg_top_debug     0xA601
+#define        reg_top_debug_pos 3
+#define        reg_top_debug_len 1
+#define        reg_top_debug_lsb 0
+#define xd_p_reg_top_adcdly    0xA601
+#define        reg_top_adcdly_pos 4
+#define        reg_top_adcdly_len 2
+#define        reg_top_adcdly_lsb 0
+#define xd_p_reg_top_pwrdw     0xA601
+#define        reg_top_pwrdw_pos 6
+#define        reg_top_pwrdw_len 1
+#define        reg_top_pwrdw_lsb 0
+#define xd_p_reg_top_pwrdw_inv 0xA601
+#define        reg_top_pwrdw_inv_pos 7
+#define        reg_top_pwrdw_inv_len 1
+#define        reg_top_pwrdw_inv_lsb 0
+#define xd_p_reg_top_int_inv   0xA602
+#define        reg_top_int_inv_pos 0
+#define        reg_top_int_inv_len 1
+#define        reg_top_int_inv_lsb 0
+#define xd_p_reg_top_dio_sel   0xA602
+#define        reg_top_dio_sel_pos 1
+#define        reg_top_dio_sel_len 1
+#define        reg_top_dio_sel_lsb 0
+#define xd_p_reg_top_gpioon0   0xA603
+#define        reg_top_gpioon0_pos 0
+#define        reg_top_gpioon0_len 1
+#define        reg_top_gpioon0_lsb 0
+#define xd_p_reg_top_gpioon1   0xA603
+#define        reg_top_gpioon1_pos 1
+#define        reg_top_gpioon1_len 1
+#define        reg_top_gpioon1_lsb 0
+#define xd_p_reg_top_gpioon2   0xA603
+#define        reg_top_gpioon2_pos 2
+#define        reg_top_gpioon2_len 1
+#define        reg_top_gpioon2_lsb 0
+#define xd_p_reg_top_gpioon3   0xA603
+#define        reg_top_gpioon3_pos 3
+#define        reg_top_gpioon3_len 1
+#define        reg_top_gpioon3_lsb 0
+#define xd_p_reg_top_lockon1   0xA603
+#define        reg_top_lockon1_pos 4
+#define        reg_top_lockon1_len 1
+#define        reg_top_lockon1_lsb 0
+#define xd_p_reg_top_lockon2   0xA603
+#define        reg_top_lockon2_pos 5
+#define        reg_top_lockon2_len 1
+#define        reg_top_lockon2_lsb 0
+#define xd_p_reg_top_gpioo0    0xA604
+#define        reg_top_gpioo0_pos 0
+#define        reg_top_gpioo0_len 1
+#define        reg_top_gpioo0_lsb 0
+#define xd_p_reg_top_gpioo1    0xA604
+#define        reg_top_gpioo1_pos 1
+#define        reg_top_gpioo1_len 1
+#define        reg_top_gpioo1_lsb 0
+#define xd_p_reg_top_gpioo2    0xA604
+#define        reg_top_gpioo2_pos 2
+#define        reg_top_gpioo2_len 1
+#define        reg_top_gpioo2_lsb 0
+#define xd_p_reg_top_gpioo3    0xA604
+#define        reg_top_gpioo3_pos 3
+#define        reg_top_gpioo3_len 1
+#define        reg_top_gpioo3_lsb 0
+#define xd_p_reg_top_lock1     0xA604
+#define        reg_top_lock1_pos 4
+#define        reg_top_lock1_len 1
+#define        reg_top_lock1_lsb 0
+#define xd_p_reg_top_lock2     0xA604
+#define        reg_top_lock2_pos 5
+#define        reg_top_lock2_len 1
+#define        reg_top_lock2_lsb 0
+#define xd_p_reg_top_gpioen0   0xA605
+#define        reg_top_gpioen0_pos 0
+#define        reg_top_gpioen0_len 1
+#define        reg_top_gpioen0_lsb 0
+#define xd_p_reg_top_gpioen1   0xA605
+#define        reg_top_gpioen1_pos 1
+#define        reg_top_gpioen1_len 1
+#define        reg_top_gpioen1_lsb 0
+#define xd_p_reg_top_gpioen2   0xA605
+#define        reg_top_gpioen2_pos 2
+#define        reg_top_gpioen2_len 1
+#define        reg_top_gpioen2_lsb 0
+#define xd_p_reg_top_gpioen3   0xA605
+#define        reg_top_gpioen3_pos 3
+#define        reg_top_gpioen3_len 1
+#define        reg_top_gpioen3_lsb 0
+#define xd_p_reg_top_locken1   0xA605
+#define        reg_top_locken1_pos 4
+#define        reg_top_locken1_len 1
+#define        reg_top_locken1_lsb 0
+#define xd_p_reg_top_locken2   0xA605
+#define        reg_top_locken2_pos 5
+#define        reg_top_locken2_len 1
+#define        reg_top_locken2_lsb 0
+#define xd_r_reg_top_gpioi0    0xA606
+#define        reg_top_gpioi0_pos 0
+#define        reg_top_gpioi0_len 1
+#define        reg_top_gpioi0_lsb 0
+#define xd_r_reg_top_gpioi1    0xA606
+#define        reg_top_gpioi1_pos 1
+#define        reg_top_gpioi1_len 1
+#define        reg_top_gpioi1_lsb 0
+#define xd_r_reg_top_gpioi2    0xA606
+#define        reg_top_gpioi2_pos 2
+#define        reg_top_gpioi2_len 1
+#define        reg_top_gpioi2_lsb 0
+#define xd_r_reg_top_gpioi3    0xA606
+#define        reg_top_gpioi3_pos 3
+#define        reg_top_gpioi3_len 1
+#define        reg_top_gpioi3_lsb 0
+#define xd_r_reg_top_locki1    0xA606
+#define        reg_top_locki1_pos 4
+#define        reg_top_locki1_len 1
+#define        reg_top_locki1_lsb 0
+#define xd_r_reg_top_locki2    0xA606
+#define        reg_top_locki2_pos 5
+#define        reg_top_locki2_len 1
+#define        reg_top_locki2_lsb 0
+#define xd_p_reg_dummy_7_0     0xA608
+#define        reg_dummy_7_0_pos 0
+#define        reg_dummy_7_0_len 8
+#define        reg_dummy_7_0_lsb 0
+#define xd_p_reg_dummy_15_8    0xA609
+#define        reg_dummy_15_8_pos 0
+#define        reg_dummy_15_8_len 8
+#define        reg_dummy_15_8_lsb 8
+#define xd_p_reg_dummy_23_16   0xA60A
+#define        reg_dummy_23_16_pos 0
+#define        reg_dummy_23_16_len 8
+#define        reg_dummy_23_16_lsb 16
+#define xd_p_reg_dummy_31_24   0xA60B
+#define        reg_dummy_31_24_pos 0
+#define        reg_dummy_31_24_len 8
+#define        reg_dummy_31_24_lsb 24
+#define xd_p_reg_dummy_39_32   0xA60C
+#define        reg_dummy_39_32_pos 0
+#define        reg_dummy_39_32_len 8
+#define        reg_dummy_39_32_lsb 32
+#define xd_p_reg_dummy_47_40   0xA60D
+#define        reg_dummy_47_40_pos 0
+#define        reg_dummy_47_40_len 8
+#define        reg_dummy_47_40_lsb 40
+#define xd_p_reg_dummy_55_48   0xA60E
+#define        reg_dummy_55_48_pos 0
+#define        reg_dummy_55_48_len 8
+#define        reg_dummy_55_48_lsb 48
+#define xd_p_reg_dummy_63_56   0xA60F
+#define        reg_dummy_63_56_pos 0
+#define        reg_dummy_63_56_len 8
+#define        reg_dummy_63_56_lsb 56
+#define xd_p_reg_dummy_71_64   0xA610
+#define        reg_dummy_71_64_pos 0
+#define        reg_dummy_71_64_len 8
+#define        reg_dummy_71_64_lsb 64
+#define xd_p_reg_dummy_79_72   0xA611
+#define        reg_dummy_79_72_pos 0
+#define        reg_dummy_79_72_len 8
+#define        reg_dummy_79_72_lsb 72
+#define xd_p_reg_dummy_87_80   0xA612
+#define        reg_dummy_87_80_pos 0
+#define        reg_dummy_87_80_len 8
+#define        reg_dummy_87_80_lsb 80
+#define xd_p_reg_dummy_95_88   0xA613
+#define        reg_dummy_95_88_pos 0
+#define        reg_dummy_95_88_len 8
+#define        reg_dummy_95_88_lsb 88
+#define xd_p_reg_dummy_103_96  0xA614
+#define        reg_dummy_103_96_pos 0
+#define        reg_dummy_103_96_len 8
+#define        reg_dummy_103_96_lsb 96
+
+#define xd_p_reg_unplug_flag   0xA615
+#define        reg_unplug_flag_pos 0
+#define        reg_unplug_flag_len 1
+#define        reg_unplug_flag_lsb 104
+
+#define xd_p_reg_api_dca_stes_request   0xA615
+#define reg_api_dca_stes_request_pos 1
+#define reg_api_dca_stes_request_len 1
+#define reg_api_dca_stes_request_lsb 0
+
+#define xd_p_reg_back_to_dca_flag      0xA615
+#define        reg_back_to_dca_flag_pos 2
+#define        reg_back_to_dca_flag_len 1
+#define        reg_back_to_dca_flag_lsb 106
+
+#define xd_p_reg_api_retrain_request    0xA615
+#define reg_api_retrain_request_pos 3
+#define reg_api_retrain_request_len 1
+#define reg_api_retrain_request_lsb 0
+
+#define xd_p_reg_Dyn_Top_Try_flag      0xA615
+#define        reg_Dyn_Top_Try_flag_pos 3
+#define        reg_Dyn_Top_Try_flag_len 1
+#define        reg_Dyn_Top_Try_flag_lsb 107
+
+#define xd_p_reg_API_retrain_freeze_flag       0xA615
+#define        reg_API_retrain_freeze_flag_pos 4
+#define        reg_API_retrain_freeze_flag_len 1
+#define        reg_API_retrain_freeze_flag_lsb 108
+
+#define xd_p_reg_dummy_111_104 0xA615
+#define        reg_dummy_111_104_pos 0
+#define        reg_dummy_111_104_len 8
+#define        reg_dummy_111_104_lsb 104
+#define xd_p_reg_dummy_119_112 0xA616
+#define        reg_dummy_119_112_pos 0
+#define        reg_dummy_119_112_len 8
+#define        reg_dummy_119_112_lsb 112
+#define xd_p_reg_dummy_127_120 0xA617
+#define        reg_dummy_127_120_pos 0
+#define        reg_dummy_127_120_len 8
+#define        reg_dummy_127_120_lsb 120
+#define xd_p_reg_dummy_135_128 0xA618
+#define        reg_dummy_135_128_pos 0
+#define        reg_dummy_135_128_len 8
+#define        reg_dummy_135_128_lsb 128
+
+#define xd_p_reg_dummy_143_136 0xA619
+#define        reg_dummy_143_136_pos 0
+#define        reg_dummy_143_136_len 8
+#define        reg_dummy_143_136_lsb 136
+
+#define xd_p_reg_CCIR_dis      0xA619
+#define        reg_CCIR_dis_pos 0
+#define        reg_CCIR_dis_len 1
+#define        reg_CCIR_dis_lsb 0
+
+#define xd_p_reg_dummy_151_144 0xA61A
+#define        reg_dummy_151_144_pos 0
+#define        reg_dummy_151_144_len 8
+#define        reg_dummy_151_144_lsb 144
+
+#define xd_p_reg_dummy_159_152 0xA61B
+#define        reg_dummy_159_152_pos 0
+#define        reg_dummy_159_152_len 8
+#define        reg_dummy_159_152_lsb 152
+
+#define xd_p_reg_dummy_167_160 0xA61C
+#define        reg_dummy_167_160_pos 0
+#define        reg_dummy_167_160_len 8
+#define        reg_dummy_167_160_lsb 160
+
+#define xd_p_reg_dummy_175_168 0xA61D
+#define        reg_dummy_175_168_pos 0
+#define        reg_dummy_175_168_len 8
+#define        reg_dummy_175_168_lsb 168
+
+#define xd_p_reg_dummy_183_176 0xA61E
+#define        reg_dummy_183_176_pos 0
+#define        reg_dummy_183_176_len 8
+#define        reg_dummy_183_176_lsb 176
+
+#define xd_p_reg_ofsm_read_rbc_en  0xA61E
+#define reg_ofsm_read_rbc_en_pos 2
+#define reg_ofsm_read_rbc_en_len 1
+#define reg_ofsm_read_rbc_en_lsb 0
+
+#define xd_p_reg_ce_filter_selection_dis  0xA61E
+#define reg_ce_filter_selection_dis_pos 1
+#define reg_ce_filter_selection_dis_len 1
+#define reg_ce_filter_selection_dis_lsb 0
+
+#define xd_p_reg_OFSM_version_control_7_0  0xA611
+#define reg_OFSM_version_control_7_0_pos 0
+#define reg_OFSM_version_control_7_0_len 8
+#define reg_OFSM_version_control_7_0_lsb 0
+
+#define xd_p_reg_OFSM_version_control_15_8  0xA61F
+#define reg_OFSM_version_control_15_8_pos 0
+#define reg_OFSM_version_control_15_8_len 8
+#define reg_OFSM_version_control_15_8_lsb 0
+
+#define xd_p_reg_OFSM_version_control_23_16  0xA620
+#define reg_OFSM_version_control_23_16_pos 0
+#define reg_OFSM_version_control_23_16_len 8
+#define reg_OFSM_version_control_23_16_lsb 0
+
+#define xd_p_reg_dummy_191_184 0xA61F
+#define        reg_dummy_191_184_pos 0
+#define        reg_dummy_191_184_len 8
+#define        reg_dummy_191_184_lsb 184
+
+#define xd_p_reg_dummy_199_192 0xA620
+#define        reg_dummy_199_192_pos 0
+#define        reg_dummy_199_192_len 8
+#define        reg_dummy_199_192_lsb 192
+
+#define xd_p_reg_ce_en 0xABC0
+#define        reg_ce_en_pos 0
+#define        reg_ce_en_len 1
+#define        reg_ce_en_lsb 0
+#define xd_p_reg_ce_fctrl_en   0xABC0
+#define        reg_ce_fctrl_en_pos 1
+#define        reg_ce_fctrl_en_len 1
+#define        reg_ce_fctrl_en_lsb 0
+#define xd_p_reg_ce_fste_tdi   0xABC0
+#define        reg_ce_fste_tdi_pos 2
+#define        reg_ce_fste_tdi_len 1
+#define        reg_ce_fste_tdi_lsb 0
+#define xd_p_reg_ce_dynamic    0xABC0
+#define        reg_ce_dynamic_pos 3
+#define        reg_ce_dynamic_len 1
+#define        reg_ce_dynamic_lsb 0
+#define xd_p_reg_ce_conf       0xABC0
+#define        reg_ce_conf_pos 4
+#define        reg_ce_conf_len 2
+#define        reg_ce_conf_lsb 0
+#define xd_p_reg_ce_dyn12      0xABC0
+#define        reg_ce_dyn12_pos 6
+#define        reg_ce_dyn12_len 1
+#define        reg_ce_dyn12_lsb 0
+#define xd_p_reg_ce_derot_en   0xABC0
+#define        reg_ce_derot_en_pos 7
+#define        reg_ce_derot_en_len 1
+#define        reg_ce_derot_en_lsb 0
+#define xd_p_reg_ce_dynamic_th_7_0     0xABC1
+#define        reg_ce_dynamic_th_7_0_pos 0
+#define        reg_ce_dynamic_th_7_0_len 8
+#define        reg_ce_dynamic_th_7_0_lsb 0
+#define xd_p_reg_ce_dynamic_th_15_8    0xABC2
+#define        reg_ce_dynamic_th_15_8_pos 0
+#define        reg_ce_dynamic_th_15_8_len 8
+#define        reg_ce_dynamic_th_15_8_lsb 8
+#define xd_p_reg_ce_s1 0xABC3
+#define        reg_ce_s1_pos 0
+#define        reg_ce_s1_len 5
+#define        reg_ce_s1_lsb 0
+#define xd_p_reg_ce_var_forced_value   0xABC3
+#define        reg_ce_var_forced_value_pos 5
+#define        reg_ce_var_forced_value_len 3
+#define        reg_ce_var_forced_value_lsb 0
+#define xd_p_reg_ce_data_im_7_0        0xABC4
+#define        reg_ce_data_im_7_0_pos 0
+#define        reg_ce_data_im_7_0_len 8
+#define        reg_ce_data_im_7_0_lsb 0
+#define xd_p_reg_ce_data_im_8  0xABC5
+#define        reg_ce_data_im_8_pos 0
+#define        reg_ce_data_im_8_len 1
+#define        reg_ce_data_im_8_lsb 0
+#define xd_p_reg_ce_data_re_6_0        0xABC5
+#define        reg_ce_data_re_6_0_pos 1
+#define        reg_ce_data_re_6_0_len 7
+#define        reg_ce_data_re_6_0_lsb 0
+#define xd_p_reg_ce_data_re_8_7        0xABC6
+#define        reg_ce_data_re_8_7_pos 0
+#define        reg_ce_data_re_8_7_len 2
+#define        reg_ce_data_re_8_7_lsb 7
+#define xd_p_reg_ce_tone_5_0   0xABC6
+#define        reg_ce_tone_5_0_pos 2
+#define        reg_ce_tone_5_0_len 6
+#define        reg_ce_tone_5_0_lsb 0
+#define xd_p_reg_ce_tone_12_6  0xABC7
+#define        reg_ce_tone_12_6_pos 0
+#define        reg_ce_tone_12_6_len 7
+#define        reg_ce_tone_12_6_lsb 6
+#define xd_p_reg_ce_centroid_drift_th  0xABC8
+#define        reg_ce_centroid_drift_th_pos 0
+#define        reg_ce_centroid_drift_th_len 8
+#define        reg_ce_centroid_drift_th_lsb 0
+#define xd_p_reg_ce_centroid_count_max 0xABC9
+#define        reg_ce_centroid_count_max_pos 0
+#define        reg_ce_centroid_count_max_len 4
+#define        reg_ce_centroid_count_max_lsb 0
+#define xd_p_reg_ce_centroid_bias_inc_7_0      0xABCA
+#define        reg_ce_centroid_bias_inc_7_0_pos 0
+#define        reg_ce_centroid_bias_inc_7_0_len 8
+#define        reg_ce_centroid_bias_inc_7_0_lsb 0
+#define xd_p_reg_ce_centroid_bias_inc_8        0xABCB
+#define        reg_ce_centroid_bias_inc_8_pos 0
+#define        reg_ce_centroid_bias_inc_8_len 1
+#define        reg_ce_centroid_bias_inc_8_lsb 0
+#define xd_p_reg_ce_var_th0_7_0        0xABCC
+#define        reg_ce_var_th0_7_0_pos 0
+#define        reg_ce_var_th0_7_0_len 8
+#define        reg_ce_var_th0_7_0_lsb 0
+#define xd_p_reg_ce_var_th0_15_8       0xABCD
+#define        reg_ce_var_th0_15_8_pos 0
+#define        reg_ce_var_th0_15_8_len 8
+#define        reg_ce_var_th0_15_8_lsb 8
+#define xd_p_reg_ce_var_th1_7_0        0xABCE
+#define        reg_ce_var_th1_7_0_pos 0
+#define        reg_ce_var_th1_7_0_len 8
+#define        reg_ce_var_th1_7_0_lsb 0
+#define xd_p_reg_ce_var_th1_15_8       0xABCF
+#define        reg_ce_var_th1_15_8_pos 0
+#define        reg_ce_var_th1_15_8_len 8
+#define        reg_ce_var_th1_15_8_lsb 8
+#define xd_p_reg_ce_var_th2_7_0        0xABD0
+#define        reg_ce_var_th2_7_0_pos 0
+#define        reg_ce_var_th2_7_0_len 8
+#define        reg_ce_var_th2_7_0_lsb 0
+#define xd_p_reg_ce_var_th2_15_8       0xABD1
+#define        reg_ce_var_th2_15_8_pos 0
+#define        reg_ce_var_th2_15_8_len 8
+#define        reg_ce_var_th2_15_8_lsb 8
+#define xd_p_reg_ce_var_th3_7_0        0xABD2
+#define        reg_ce_var_th3_7_0_pos 0
+#define        reg_ce_var_th3_7_0_len 8
+#define        reg_ce_var_th3_7_0_lsb 0
+#define xd_p_reg_ce_var_th3_15_8       0xABD3
+#define        reg_ce_var_th3_15_8_pos 0
+#define        reg_ce_var_th3_15_8_len 8
+#define        reg_ce_var_th3_15_8_lsb 8
+#define xd_p_reg_ce_var_th4_7_0        0xABD4
+#define        reg_ce_var_th4_7_0_pos 0
+#define        reg_ce_var_th4_7_0_len 8
+#define        reg_ce_var_th4_7_0_lsb 0
+#define xd_p_reg_ce_var_th4_15_8       0xABD5
+#define        reg_ce_var_th4_15_8_pos 0
+#define        reg_ce_var_th4_15_8_len 8
+#define        reg_ce_var_th4_15_8_lsb 8
+#define xd_p_reg_ce_var_th5_7_0        0xABD6
+#define        reg_ce_var_th5_7_0_pos 0
+#define        reg_ce_var_th5_7_0_len 8
+#define        reg_ce_var_th5_7_0_lsb 0
+#define xd_p_reg_ce_var_th5_15_8       0xABD7
+#define        reg_ce_var_th5_15_8_pos 0
+#define        reg_ce_var_th5_15_8_len 8
+#define        reg_ce_var_th5_15_8_lsb 8
+#define xd_p_reg_ce_var_th6_7_0        0xABD8
+#define        reg_ce_var_th6_7_0_pos 0
+#define        reg_ce_var_th6_7_0_len 8
+#define        reg_ce_var_th6_7_0_lsb 0
+#define xd_p_reg_ce_var_th6_15_8       0xABD9
+#define        reg_ce_var_th6_15_8_pos 0
+#define        reg_ce_var_th6_15_8_len 8
+#define        reg_ce_var_th6_15_8_lsb 8
+#define xd_p_reg_ce_fctrl_reset        0xABDA
+#define        reg_ce_fctrl_reset_pos 0
+#define        reg_ce_fctrl_reset_len 1
+#define        reg_ce_fctrl_reset_lsb 0
+#define xd_p_reg_ce_cent_auto_clr_en   0xABDA
+#define        reg_ce_cent_auto_clr_en_pos 1
+#define        reg_ce_cent_auto_clr_en_len 1
+#define        reg_ce_cent_auto_clr_en_lsb 0
+#define xd_p_reg_ce_fctrl_auto_reset_en        0xABDA
+#define        reg_ce_fctrl_auto_reset_en_pos 2
+#define        reg_ce_fctrl_auto_reset_en_len 1
+#define        reg_ce_fctrl_auto_reset_en_lsb 0
+#define xd_p_reg_ce_var_forced_en      0xABDA
+#define        reg_ce_var_forced_en_pos 3
+#define        reg_ce_var_forced_en_len 1
+#define        reg_ce_var_forced_en_lsb 0
+#define xd_p_reg_ce_cent_forced_en     0xABDA
+#define        reg_ce_cent_forced_en_pos 4
+#define        reg_ce_cent_forced_en_len 1
+#define        reg_ce_cent_forced_en_lsb 0
+#define xd_p_reg_ce_var_max    0xABDA
+#define        reg_ce_var_max_pos 5
+#define        reg_ce_var_max_len 3
+#define        reg_ce_var_max_lsb 0
+#define xd_p_reg_ce_cent_forced_value_7_0      0xABDB
+#define        reg_ce_cent_forced_value_7_0_pos 0
+#define        reg_ce_cent_forced_value_7_0_len 8
+#define        reg_ce_cent_forced_value_7_0_lsb 0
+#define xd_p_reg_ce_cent_forced_value_11_8     0xABDC
+#define        reg_ce_cent_forced_value_11_8_pos 0
+#define        reg_ce_cent_forced_value_11_8_len 4
+#define        reg_ce_cent_forced_value_11_8_lsb 8
+#define xd_p_reg_ce_fctrl_rd   0xABDD
+#define        reg_ce_fctrl_rd_pos 0
+#define        reg_ce_fctrl_rd_len 1
+#define        reg_ce_fctrl_rd_lsb 0
+#define xd_p_reg_ce_centroid_max_6_0   0xABDD
+#define        reg_ce_centroid_max_6_0_pos 1
+#define        reg_ce_centroid_max_6_0_len 7
+#define        reg_ce_centroid_max_6_0_lsb 0
+#define xd_p_reg_ce_centroid_max_11_7  0xABDE
+#define        reg_ce_centroid_max_11_7_pos 0
+#define        reg_ce_centroid_max_11_7_len 5
+#define        reg_ce_centroid_max_11_7_lsb 7
+#define xd_p_reg_ce_var        0xABDF
+#define        reg_ce_var_pos 0
+#define        reg_ce_var_len 3
+#define        reg_ce_var_lsb 0
+#define xd_p_reg_ce_fctrl_rdy  0xABDF
+#define        reg_ce_fctrl_rdy_pos 3
+#define        reg_ce_fctrl_rdy_len 1
+#define        reg_ce_fctrl_rdy_lsb 0
+#define xd_p_reg_ce_centroid_out_3_0   0xABDF
+#define        reg_ce_centroid_out_3_0_pos 4
+#define        reg_ce_centroid_out_3_0_len 4
+#define        reg_ce_centroid_out_3_0_lsb 0
+#define xd_p_reg_ce_centroid_out_11_4  0xABE0
+#define        reg_ce_centroid_out_11_4_pos 0
+#define        reg_ce_centroid_out_11_4_len 8
+#define        reg_ce_centroid_out_11_4_lsb 4
+#define xd_p_reg_ce_bias_7_0   0xABE1
+#define        reg_ce_bias_7_0_pos 0
+#define        reg_ce_bias_7_0_len 8
+#define        reg_ce_bias_7_0_lsb 0
+#define xd_p_reg_ce_bias_11_8  0xABE2
+#define        reg_ce_bias_11_8_pos 0
+#define        reg_ce_bias_11_8_len 4
+#define        reg_ce_bias_11_8_lsb 8
+#define xd_p_reg_ce_m1_3_0     0xABE2
+#define        reg_ce_m1_3_0_pos 4
+#define        reg_ce_m1_3_0_len 4
+#define        reg_ce_m1_3_0_lsb 0
+#define xd_p_reg_ce_m1_11_4    0xABE3
+#define        reg_ce_m1_11_4_pos 0
+#define        reg_ce_m1_11_4_len 8
+#define        reg_ce_m1_11_4_lsb 4
+#define xd_p_reg_ce_rh0_7_0    0xABE4
+#define        reg_ce_rh0_7_0_pos 0
+#define        reg_ce_rh0_7_0_len 8
+#define        reg_ce_rh0_7_0_lsb 0
+#define xd_p_reg_ce_rh0_15_8   0xABE5
+#define        reg_ce_rh0_15_8_pos 0
+#define        reg_ce_rh0_15_8_len 8
+#define        reg_ce_rh0_15_8_lsb 8
+#define xd_p_reg_ce_rh0_23_16  0xABE6
+#define        reg_ce_rh0_23_16_pos 0
+#define        reg_ce_rh0_23_16_len 8
+#define        reg_ce_rh0_23_16_lsb 16
+#define xd_p_reg_ce_rh0_31_24  0xABE7
+#define        reg_ce_rh0_31_24_pos 0
+#define        reg_ce_rh0_31_24_len 8
+#define        reg_ce_rh0_31_24_lsb 24
+#define xd_p_reg_ce_rh3_real_7_0       0xABE8
+#define        reg_ce_rh3_real_7_0_pos 0
+#define        reg_ce_rh3_real_7_0_len 8
+#define        reg_ce_rh3_real_7_0_lsb 0
+#define xd_p_reg_ce_rh3_real_15_8      0xABE9
+#define        reg_ce_rh3_real_15_8_pos 0
+#define        reg_ce_rh3_real_15_8_len 8
+#define        reg_ce_rh3_real_15_8_lsb 8
+#define xd_p_reg_ce_rh3_real_23_16     0xABEA
+#define        reg_ce_rh3_real_23_16_pos 0
+#define        reg_ce_rh3_real_23_16_len 8
+#define        reg_ce_rh3_real_23_16_lsb 16
+#define xd_p_reg_ce_rh3_real_31_24     0xABEB
+#define        reg_ce_rh3_real_31_24_pos 0
+#define        reg_ce_rh3_real_31_24_len 8
+#define        reg_ce_rh3_real_31_24_lsb 24
+#define xd_p_reg_ce_rh3_imag_7_0       0xABEC
+#define        reg_ce_rh3_imag_7_0_pos 0
+#define        reg_ce_rh3_imag_7_0_len 8
+#define        reg_ce_rh3_imag_7_0_lsb 0
+#define xd_p_reg_ce_rh3_imag_15_8      0xABED
+#define        reg_ce_rh3_imag_15_8_pos 0
+#define        reg_ce_rh3_imag_15_8_len 8
+#define        reg_ce_rh3_imag_15_8_lsb 8
+#define xd_p_reg_ce_rh3_imag_23_16     0xABEE
+#define        reg_ce_rh3_imag_23_16_pos 0
+#define        reg_ce_rh3_imag_23_16_len 8
+#define        reg_ce_rh3_imag_23_16_lsb 16
+#define xd_p_reg_ce_rh3_imag_31_24     0xABEF
+#define        reg_ce_rh3_imag_31_24_pos 0
+#define        reg_ce_rh3_imag_31_24_len 8
+#define        reg_ce_rh3_imag_31_24_lsb 24
+#define xd_p_reg_feq_fix_eh2_7_0       0xABF0
+#define        reg_feq_fix_eh2_7_0_pos 0
+#define        reg_feq_fix_eh2_7_0_len 8
+#define        reg_feq_fix_eh2_7_0_lsb 0
+#define xd_p_reg_feq_fix_eh2_15_8      0xABF1
+#define        reg_feq_fix_eh2_15_8_pos 0
+#define        reg_feq_fix_eh2_15_8_len 8
+#define        reg_feq_fix_eh2_15_8_lsb 8
+#define xd_p_reg_feq_fix_eh2_23_16     0xABF2
+#define        reg_feq_fix_eh2_23_16_pos 0
+#define        reg_feq_fix_eh2_23_16_len 8
+#define        reg_feq_fix_eh2_23_16_lsb 16
+#define xd_p_reg_feq_fix_eh2_31_24     0xABF3
+#define        reg_feq_fix_eh2_31_24_pos 0
+#define        reg_feq_fix_eh2_31_24_len 8
+#define        reg_feq_fix_eh2_31_24_lsb 24
+#define xd_p_reg_ce_m2_central_7_0     0xABF4
+#define        reg_ce_m2_central_7_0_pos 0
+#define        reg_ce_m2_central_7_0_len 8
+#define        reg_ce_m2_central_7_0_lsb 0
+#define xd_p_reg_ce_m2_central_15_8    0xABF5
+#define        reg_ce_m2_central_15_8_pos 0
+#define        reg_ce_m2_central_15_8_len 8
+#define        reg_ce_m2_central_15_8_lsb 8
+#define xd_p_reg_ce_fftshift   0xABF6
+#define        reg_ce_fftshift_pos 0
+#define        reg_ce_fftshift_len 4
+#define        reg_ce_fftshift_lsb 0
+#define xd_p_reg_ce_fftshift1  0xABF6
+#define        reg_ce_fftshift1_pos 4
+#define        reg_ce_fftshift1_len 4
+#define        reg_ce_fftshift1_lsb 0
+#define xd_p_reg_ce_fftshift2  0xABF7
+#define        reg_ce_fftshift2_pos 0
+#define        reg_ce_fftshift2_len 4
+#define        reg_ce_fftshift2_lsb 0
+#define xd_p_reg_ce_top_mobile 0xABF7
+#define        reg_ce_top_mobile_pos 4
+#define        reg_ce_top_mobile_len 1
+#define        reg_ce_top_mobile_lsb 0
+#define xd_p_reg_strong_sginal_detected 0xA2BC
+#define reg_strong_sginal_detected_pos 2
+#define reg_strong_sginal_detected_len 1
+#define reg_strong_sginal_detected_lsb 0
+
+#define XD_MP2IF_BASE                           0xB000
+#define XD_MP2IF_CSR                        (0x00 + XD_MP2IF_BASE)
+#define XD_MP2IF_DMX_CTRL                       (0x03 + XD_MP2IF_BASE)
+#define XD_MP2IF_PID_IDX                        (0x04 + XD_MP2IF_BASE)
+#define XD_MP2IF_PID_DATA_L                     (0x05 + XD_MP2IF_BASE)
+#define XD_MP2IF_PID_DATA_H                     (0x06 + XD_MP2IF_BASE)
+#define XD_MP2IF_MISC                       (0x07 + XD_MP2IF_BASE)
+
+extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d);
+extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg,
+                                    u8 * value);
+extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
+                                     u8 * values, int len);
+extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg,
+                                     u8 value);
+extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
+                                      u8 * values, int len);
+extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg,
+                                      u8 addr, u8 * values, int len);
+extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
+                                       u8 * values, int len);
+extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg,
+                                    u8 pos, u8 len, u8 * value);
+extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg,
+                                     u8 pos, u8 len, u8 value);
+extern int af9005_send_command(struct dvb_usb_device *d, u8 command,
+                              u8 * wbuf, int wlen, u8 * rbuf, int rlen);
+extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address,
+                             u8 * values, int len);
+extern int af9005_tuner_attach(struct dvb_usb_adapter *adap);
+extern int af9005_led_control(struct dvb_usb_device *d, int onoff);
+
+extern u8 regmask[8];
+
+/* remote control decoder */
+extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
+                           u32 * event, int *state);
+extern struct rc_map_table rc_map_af9005_table[];
+extern int rc_map_af9005_table_size;
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
new file mode 100644 (file)
index 0000000..5e45ae6
--- /dev/null
@@ -0,0 +1,1182 @@
+/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
+ * receiver.
+ *
+ * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "az6027.h"
+
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+
+#include "stb6100.h"
+#include "stb6100_cfg.h"
+#include "dvb_ca_en50221.h"
+
+int dvb_usb_az6027_debug;
+module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct az6027_device_state {
+       struct dvb_ca_en50221 ca;
+       struct mutex ca_mutex;
+       u8 power_state;
+};
+
+static const struct stb0899_s1_reg az6027_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 az6027_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 az6027_stb0899_config = {
+       .init_dev               = az6027_stb0899_s1_init_1,
+       .init_s2_demod          = stb0899_s2_init_2,
+       .init_s1_demod          = az6027_stb0899_s1_init_3,
+       .init_s2_fec            = stb0899_s2_init_4,
+       .init_tst               = stb0899_s1_init_5,
+
+       .demod_address          = 0xd0, /* 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 az6027_stb6100_config = {
+       .tuner_address  = 0xc0,
+       .refclock       = 27000000,
+};
+
+
+/* check for mutex FIXME */
+int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+       int ret = -1;
+       if (mutex_lock_interruptible(&d->usb_mutex))
+               return -EAGAIN;
+
+       ret = usb_control_msg(d->udev,
+                             usb_rcvctrlpipe(d->udev, 0),
+                             req,
+                             USB_TYPE_VENDOR | USB_DIR_IN,
+                             value,
+                             index,
+                             b,
+                             blen,
+                             2000);
+
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
+       debug_dump(b, blen, deb_xfer);
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+static int az6027_usb_out_op(struct dvb_usb_device *d,
+                            u8 req,
+                            u16 value,
+                            u16 index,
+                            u8 *b,
+                            int blen)
+{
+       int ret;
+
+       deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
+       debug_dump(b, blen, deb_xfer);
+
+       if (mutex_lock_interruptible(&d->usb_mutex))
+               return -EAGAIN;
+
+       ret = usb_control_msg(d->udev,
+                             usb_sndctrlpipe(d->udev, 0),
+                             req,
+                             USB_TYPE_VENDOR | USB_DIR_OUT,
+                             value,
+                             index,
+                             b,
+                             blen,
+                             2000);
+
+       if (ret != blen) {
+               warn("usb out operation failed. (%d)", ret);
+               mutex_unlock(&d->usb_mutex);
+               return -EIO;
+       } else{
+               mutex_unlock(&d->usb_mutex);
+               return 0;
+       }
+}
+
+static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       deb_info("%s %d", __func__, onoff);
+
+       req = 0xBC;
+       value = onoff;
+       index = 0;
+       blen = 0;
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               warn("usb out operation failed. (%d)", ret);
+
+       return ret;
+}
+
+/* keys for the enclosed remote control */
+static struct rc_map_table rc_map_az6027_table[] = {
+       { 0x01, KEY_1 },
+       { 0x02, KEY_2 },
+};
+
+/* remote control stuff (does not work with my box) */
+static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       return 0;
+}
+
+/*
+int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 v = onoff;
+       return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
+}
+*/
+
+static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
+                                       int slot,
+                                       int address)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC1;
+       value = address;
+       index = 0;
+       blen = 1;
+
+       ret = az6027_usb_in_op(d, req, value, index, b, blen);
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EINVAL;
+       } else {
+               ret = b[0];
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
+                                        int slot,
+                                        int address,
+                                        u8 value)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret;
+       u8 req;
+       u16 value1;
+       u16 index;
+       int blen;
+
+       deb_info("%s %d", __func__, slot);
+       if (slot != 0)
+               return -EINVAL;
+
+       mutex_lock(&state->ca_mutex);
+       req = 0xC2;
+       value1 = address;
+       index = value;
+       blen = 0;
+
+       ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
+       if (ret != 0)
+               warn("usb out operation failed. (%d)", ret);
+
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
+                                     int slot,
+                                     u8 address)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC3;
+       value = address;
+       index = 0;
+       blen = 2;
+
+       ret = az6027_usb_in_op(d, req, value, index, b, blen);
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EINVAL;
+       } else {
+               if (b[0] == 0)
+                       warn("Read CI IO error");
+
+               ret = b[1];
+               deb_info("read cam data = %x from 0x%x", b[1], value);
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
+                                      int slot,
+                                      u8 address,
+                                      u8 value)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret;
+       u8 req;
+       u16 value1;
+       u16 index;
+       int blen;
+
+       if (slot != 0)
+               return -EINVAL;
+
+       mutex_lock(&state->ca_mutex);
+       req = 0xC4;
+       value1 = address;
+       index = value;
+       blen = 0;
+
+       ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
+       if (ret != 0) {
+               warn("usb out operation failed. (%d)", ret);
+               goto failed;
+       }
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       req = 0xC8;
+       value = 0;
+       index = 0;
+       blen = 1;
+
+       ret = az6027_usb_in_op(d, req, value, index, b, blen);
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EIO;
+       } else{
+               ret = b[0];
+       }
+       kfree(b);
+       return ret;
+}
+
+static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret, i;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC6;
+       value = 1;
+       index = 0;
+       blen = 0;
+
+       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               warn("usb out operation failed. (%d)", ret);
+               goto failed;
+       }
+
+       msleep(500);
+       req = 0xC6;
+       value = 0;
+       index = 0;
+       blen = 0;
+
+       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               warn("usb out operation failed. (%d)", ret);
+               goto failed;
+       }
+
+       for (i = 0; i < 15; i++) {
+               msleep(100);
+
+               if (CI_CamReady(ca, slot)) {
+                       deb_info("CAM Ready");
+                       break;
+               }
+       }
+       msleep(5000);
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       return 0;
+}
+
+static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       deb_info("%s", __func__);
+       mutex_lock(&state->ca_mutex);
+       req = 0xC7;
+       value = 1;
+       index = 0;
+       blen = 0;
+
+       ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
+       if (ret != 0) {
+               warn("usb out operation failed. (%d)", ret);
+               goto failed;
+       }
+
+failed:
+       mutex_unlock(&state->ca_mutex);
+       return ret;
+}
+
+static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+       u8 *b;
+
+       b = kmalloc(12, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+       mutex_lock(&state->ca_mutex);
+
+       req = 0xC5;
+       value = 0;
+       index = 0;
+       blen = 1;
+
+       ret = az6027_usb_in_op(d, req, value, index, b, blen);
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       if (!ret && b[0] == 1) {
+               ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
+                     DVB_CA_EN50221_POLL_CAM_READY;
+       }
+
+       mutex_unlock(&state->ca_mutex);
+       kfree(b);
+       return ret;
+}
+
+
+static void az6027_ci_uninit(struct dvb_usb_device *d)
+{
+       struct az6027_device_state *state;
+
+       deb_info("%s", __func__);
+
+       if (NULL == d)
+               return;
+
+       state = (struct az6027_device_state *)d->priv;
+       if (NULL == state)
+               return;
+
+       if (NULL == state->ca.data)
+               return;
+
+       dvb_ca_en50221_release(&state->ca);
+
+       memset(&state->ca, 0, sizeof(state->ca));
+}
+
+
+static int az6027_ci_init(struct dvb_usb_adapter *a)
+{
+       struct dvb_usb_device *d = a->dev;
+       struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
+       int ret;
+
+       deb_info("%s", __func__);
+
+       mutex_init(&state->ca_mutex);
+
+       state->ca.owner                 = THIS_MODULE;
+       state->ca.read_attribute_mem    = az6027_ci_read_attribute_mem;
+       state->ca.write_attribute_mem   = az6027_ci_write_attribute_mem;
+       state->ca.read_cam_control      = az6027_ci_read_cam_control;
+       state->ca.write_cam_control     = az6027_ci_write_cam_control;
+       state->ca.slot_reset            = az6027_ci_slot_reset;
+       state->ca.slot_shutdown         = az6027_ci_slot_shutdown;
+       state->ca.slot_ts_enable        = az6027_ci_slot_ts_enable;
+       state->ca.poll_slot_status      = az6027_ci_poll_slot_status;
+       state->ca.data                  = d;
+
+       ret = dvb_ca_en50221_init(&a->dvb_adap,
+                                 &state->ca,
+                                 0, /* flags */
+                                 1);/* n_slots */
+       if (ret != 0) {
+               err("Cannot initialize CI: Error %d.", ret);
+               memset(&state->ca, 0, sizeof(state->ca));
+               return ret;
+       }
+
+       deb_info("CI initialized.");
+
+       return 0;
+}
+
+/*
+static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
+{
+       az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
+       return 0;
+}
+*/
+
+static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+
+       u8 buf;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+       struct i2c_msg i2c_msg = {
+               .addr   = 0x99,
+               .flags  = 0,
+               .buf    = &buf,
+               .len    = 1
+       };
+
+       /*
+        * 2   --18v
+        * 1   --13v
+        * 0   --off
+        */
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               buf = 1;
+               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+               break;
+
+       case SEC_VOLTAGE_18:
+               buf = 2;
+               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+               break;
+
+       case SEC_VOLTAGE_OFF:
+               buf = 0;
+               i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       req = 0xBC;
+       value = 1; /* power on */
+       index = 3;
+       blen = 0;
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               return -EIO;
+
+       return 0;
+}
+static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       /* reset demodulator */
+       req = 0xC0;
+       value = 1; /* high */
+       index = 3;
+       blen = 0;
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               return -EIO;
+
+       req = 0xC0;
+       value = 0; /* low */
+       index = 3;
+       blen = 0;
+       msleep_interruptible(200);
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               return -EIO;
+
+       msleep_interruptible(200);
+
+       req = 0xC0;
+       value = 1; /*high */
+       index = 3;
+       blen = 0;
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               return -EIO;
+
+       msleep_interruptible(200);
+       return 0;
+}
+
+static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+       u8 req;
+       u16 value;
+       u16 index;
+       int blen;
+
+       /* TS passthrough */
+       req = 0xC7;
+       value = onoff;
+       index = 0;
+       blen = 0;
+
+       ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
+       if (ret != 0)
+               return -EIO;
+
+       return 0;
+}
+
+static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
+{
+
+       az6027_frontend_poweron(adap);
+       az6027_frontend_reset(adap);
+
+       deb_info("adap = %p, dev = %p\n", adap, adap->dev);
+       adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
+
+       if (adap->fe_adap[0].fe) {
+               deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
+               if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
+                       deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
+                       adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage;
+                       az6027_ci_init(adap);
+               } else {
+                       adap->fe_adap[0].fe = NULL;
+               }
+       } else
+               warn("no front-end attached\n");
+
+       az6027_frontend_tsbypass(adap, 0);
+
+       return 0;
+}
+
+static struct dvb_usb_device_properties az6027_properties;
+
+static void az6027_usb_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       az6027_ci_uninit(d);
+       dvb_usb_device_exit(intf);
+}
+
+
+static int az6027_usb_probe(struct usb_interface *intf,
+                           const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf,
+                                  &az6027_properties,
+                                  THIS_MODULE,
+                                  NULL,
+                                  adapter_nr);
+}
+
+/* I2C */
+static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i = 0, j = 0, len = 0;
+       u16 index;
+       u16 value;
+       int length;
+       u8 req;
+       u8 *data;
+
+       data = kmalloc(256, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
+               kfree(data);
+               return -EAGAIN;
+       }
+
+       if (num > 2)
+               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+       for (i = 0; i < num; i++) {
+
+               if (msg[i].addr == 0x99) {
+                       req = 0xBE;
+                       index = 0;
+                       value = msg[i].buf[0] & 0x00ff;
+                       length = 1;
+                       az6027_usb_out_op(d, req, value, index, data, length);
+               }
+
+               if (msg[i].addr == 0xd0) {
+                       /* write/read request */
+                       if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
+                               req = 0xB9;
+                               index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
+                               value = msg[i].addr + (msg[i].len << 8);
+                               length = msg[i + 1].len + 6;
+                               az6027_usb_in_op(d, req, value, index, data, length);
+                               len = msg[i + 1].len;
+                               for (j = 0; j < len; j++)
+                                       msg[i + 1].buf[j] = data[j + 5];
+
+                               i++;
+                       } else {
+
+                               /* demod 16bit addr */
+                               req = 0xBD;
+                               index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
+                               value = msg[i].addr + (2 << 8);
+                               length = msg[i].len - 2;
+                               len = msg[i].len - 2;
+                               for (j = 0; j < len; j++)
+                                       data[j] = msg[i].buf[j + 2];
+                               az6027_usb_out_op(d, req, value, index, data, length);
+                       }
+               }
+
+               if (msg[i].addr == 0xc0) {
+                       if (msg[i].flags & I2C_M_RD) {
+
+                               req = 0xB9;
+                               index = 0x0;
+                               value = msg[i].addr;
+                               length = msg[i].len + 6;
+                               az6027_usb_in_op(d, req, value, index, data, length);
+                               len = msg[i].len;
+                               for (j = 0; j < len; j++)
+                                       msg[i].buf[j] = data[j + 5];
+
+                       } else {
+
+                               req = 0xBD;
+                               index = msg[i].buf[0] & 0x00FF;
+                               value = msg[i].addr + (1 << 8);
+                               length = msg[i].len - 1;
+                               len = msg[i].len - 1;
+
+                               for (j = 0; j < len; j++)
+                                       data[j] = msg[i].buf[j + 1];
+
+                               az6027_usb_out_op(d, req, value, index, data, length);
+                       }
+               }
+       }
+       mutex_unlock(&d->i2c_mutex);
+       kfree(data);
+
+       return i;
+}
+
+
+static u32 az6027_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm az6027_i2c_algo = {
+       .master_xfer   = az6027_i2c_xfer,
+       .functionality = az6027_i2c_func,
+};
+
+int az6027_identify_state(struct usb_device *udev,
+                         struct dvb_usb_device_properties *props,
+                         struct dvb_usb_device_description **desc,
+                         int *cold)
+{
+       u8 *b;
+       s16 ret;
+
+       b = kmalloc(16, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       ret = usb_control_msg(udev,
+                                 usb_rcvctrlpipe(udev, 0),
+                                 0xb7,
+                                 USB_TYPE_VENDOR | USB_DIR_IN,
+                                 6,
+                                 0,
+                                 b,
+                                 6,
+                                 USB_CTRL_GET_TIMEOUT);
+
+       *cold = ret <= 0;
+       kfree(b);
+       deb_info("cold: %d\n", *cold);
+       return 0;
+}
+
+
+static struct usb_device_id az6027_usb_table[] = {
+       { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V1) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_DVBS2CI_V2) },
+       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
+       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
+       { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
+       { },
+};
+
+MODULE_DEVICE_TABLE(usb, az6027_usb_table);
+
+static struct dvb_usb_device_properties az6027_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware            = "dvb-usb-az6027-03.fw",
+       .no_reconnect        = 1,
+
+       .size_of_priv     = sizeof(struct az6027_device_state),
+       .identify_state         = az6027_identify_state,
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = az6027_streaming_ctrl,
+                       .frontend_attach  = az6027_frontend_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 10,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+/*
+       .power_ctrl       = az6027_power_ctrl,
+       .read_mac_address = az6027_read_mac_addr,
+ */
+       .rc.legacy = {
+               .rc_map_table     = rc_map_az6027_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_az6027_table),
+               .rc_interval      = 400,
+               .rc_query         = az6027_rc_query,
+       },
+
+       .i2c_algo         = &az6027_i2c_algo,
+
+       .num_device_descs = 6,
+       .devices = {
+               {
+                       .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
+                       .cold_ids = { &az6027_usb_table[0], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "TERRATEC S7",
+                       .cold_ids = { &az6027_usb_table[1], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "TERRATEC S7 MKII",
+                       .cold_ids = { &az6027_usb_table[2], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "Technisat SkyStar USB 2 HD CI",
+                       .cold_ids = { &az6027_usb_table[3], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "Technisat SkyStar USB 2 HD CI",
+                       .cold_ids = { &az6027_usb_table[4], NULL },
+                       .warm_ids = { NULL },
+               }, {
+                       .name = "Elgato EyeTV Sat",
+                       .cold_ids = { &az6027_usb_table[5], NULL },
+                       .warm_ids = { NULL },
+               },
+               { NULL },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver az6027_usb_driver = {
+       .name           = "dvb_usb_az6027",
+       .probe          = az6027_usb_probe,
+       .disconnect     = az6027_usb_disconnect,
+       .id_table       = az6027_usb_table,
+};
+
+module_usb_driver(az6027_usb_driver);
+
+MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
+MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/az6027.h b/drivers/media/usb/dvb-usb/az6027.h
new file mode 100644 (file)
index 0000000..f3afe17
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _DVB_USB_VP6027_H_
+#define _DVB_USB_VP6027_H_
+
+#define DVB_USB_LOG_PREFIX "az6027"
+#include "dvb-usb.h"
+
+
+extern int dvb_usb_az6027_debug;
+#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_az6027_debug, 0x04, args)
+#define deb_fe(args...)   dprintk(dvb_usb_az6027_debug, 0x08, args)
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
new file mode 100644 (file)
index 0000000..0a98548
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
+ *
+ * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
+ *
+ * Based on the dvb-usb-framework code and the
+ * original Terratec Cinergy T2 driver by:
+ *
+ * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
+ *                 Holger Waechtler <holger@qanu.de>
+ *
+ *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
+ *
+ * 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 "cinergyT2.h"
+
+
+/* debug */
+int dvb_usb_cinergyt2_debug;
+
+module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
+               "(or-able)).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct cinergyt2_state {
+       u8 rc_counter;
+};
+
+/* We are missing a release hook with usb_device data */
+static struct dvb_usb_device *cinergyt2_usb_device;
+
+static struct dvb_usb_device_properties cinergyt2_properties;
+
+static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
+{
+       char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
+       char result[64];
+       return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
+                               sizeof(result), 0);
+}
+
+static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
+{
+       char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
+       char state[3];
+       return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
+}
+
+static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
+       char state[3];
+       int ret;
+
+       adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
+
+       ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
+                               sizeof(state), 0);
+       if (ret < 0) {
+               deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
+                       "state info\n");
+       }
+
+       /* Copy this pointer as we are gonna need it in the release phase */
+       cinergyt2_usb_device = adap->dev;
+
+       return 0;
+}
+
+static struct rc_map_table rc_map_cinergyt2_table[] = {
+       { 0x0401, KEY_POWER },
+       { 0x0402, KEY_1 },
+       { 0x0403, KEY_2 },
+       { 0x0404, KEY_3 },
+       { 0x0405, KEY_4 },
+       { 0x0406, KEY_5 },
+       { 0x0407, KEY_6 },
+       { 0x0408, KEY_7 },
+       { 0x0409, KEY_8 },
+       { 0x040a, KEY_9 },
+       { 0x040c, KEY_0 },
+       { 0x040b, KEY_VIDEO },
+       { 0x040d, KEY_REFRESH },
+       { 0x040e, KEY_SELECT },
+       { 0x040f, KEY_EPG },
+       { 0x0410, KEY_UP },
+       { 0x0414, KEY_DOWN },
+       { 0x0411, KEY_LEFT },
+       { 0x0413, KEY_RIGHT },
+       { 0x0412, KEY_OK },
+       { 0x0415, KEY_TEXT },
+       { 0x0416, KEY_INFO },
+       { 0x0417, KEY_RED },
+       { 0x0418, KEY_GREEN },
+       { 0x0419, KEY_YELLOW },
+       { 0x041a, KEY_BLUE },
+       { 0x041c, KEY_VOLUMEUP },
+       { 0x041e, KEY_VOLUMEDOWN },
+       { 0x041d, KEY_MUTE },
+       { 0x041b, KEY_CHANNELUP },
+       { 0x041f, KEY_CHANNELDOWN },
+       { 0x0440, KEY_PAUSE },
+       { 0x044c, KEY_PLAY },
+       { 0x0458, KEY_RECORD },
+       { 0x0454, KEY_PREVIOUS },
+       { 0x0448, KEY_STOP },
+       { 0x045c, KEY_NEXT }
+};
+
+/* Number of keypresses to ignore before detect repeating */
+#define RC_REPEAT_DELAY 3
+
+static int repeatable_keys[] = {
+       KEY_UP,
+       KEY_DOWN,
+       KEY_LEFT,
+       KEY_RIGHT,
+       KEY_VOLUMEUP,
+       KEY_VOLUMEDOWN,
+       KEY_CHANNELUP,
+       KEY_CHANNELDOWN
+};
+
+static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       struct cinergyt2_state *st = d->priv;
+       u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
+       int i;
+
+       *state = REMOTE_NO_KEY_PRESSED;
+
+       dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
+       if (key[4] == 0xff) {
+               /* key repeat */
+               st->rc_counter++;
+               if (st->rc_counter > RC_REPEAT_DELAY) {
+                       for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
+                               if (d->last_event == repeatable_keys[i]) {
+                                       *state = REMOTE_KEY_REPEAT;
+                                       *event = d->last_event;
+                                       deb_rc("repeat key, event %x\n",
+                                                  *event);
+                                       return 0;
+                               }
+                       }
+                       deb_rc("repeated key (non repeatable)\n");
+               }
+               return 0;
+       }
+
+       /* hack to pass checksum on the custom field */
+       key[2] = ~key[1];
+       dvb_usb_nec_rc_key_to_event(d, key, event, state);
+       if (key[0] != 0) {
+               if (*event != d->last_event)
+                       st->rc_counter = 0;
+
+               deb_rc("key: %x %x %x %x %x\n",
+                      key[0], key[1], key[2], key[3], key[4]);
+       }
+       return 0;
+}
+
+static int cinergyt2_usb_probe(struct usb_interface *intf,
+                               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &cinergyt2_properties,
+                                       THIS_MODULE, NULL, adapter_nr);
+}
+
+
+static struct usb_device_id cinergyt2_usb_table[] = {
+       { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
+
+static struct dvb_usb_device_properties cinergyt2_properties = {
+       .size_of_priv = sizeof(struct cinergyt2_state),
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cinergyt2_streaming_ctrl,
+                       .frontend_attach  = cinergyt2_frontend_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 512,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+
+       .power_ctrl       = cinergyt2_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = 50,
+               .rc_map_table     = rc_map_cinergyt2_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_cinergyt2_table),
+               .rc_query         = cinergyt2_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 1,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
+                 .cold_ids = {NULL},
+                 .warm_ids = { &cinergyt2_usb_table[0], NULL },
+               },
+               { NULL },
+       }
+};
+
+
+static struct usb_driver cinergyt2_driver = {
+       .name           = "cinergyT2",
+       .probe          = cinergyt2_usb_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = cinergyt2_usb_table
+};
+
+module_usb_driver(cinergyt2_driver);
+
+MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
new file mode 100644 (file)
index 0000000..1efc028
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
+ *
+ * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
+ *
+ * Based on the dvb-usb-framework code and the
+ * original Terratec Cinergy T2 driver by:
+ *
+ * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
+ *                  Holger Waechtler <holger@qanu.de>
+ *
+ *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
+ *
+ * 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 "cinergyT2.h"
+
+
+/**
+ *  convert linux-dvb frontend parameter set into TPS.
+ *  See ETSI ETS-300744, section 4.6.2, table 9 for details.
+ *
+ *  This function is probably reusable and may better get placed in a support
+ *  library.
+ *
+ *  We replace errornous fields by default TPS fields (the ones with value 0).
+ */
+
+static uint16_t compute_tps(struct dtv_frontend_properties *op)
+{
+       uint16_t tps = 0;
+
+       switch (op->code_rate_HP) {
+       case FEC_2_3:
+               tps |= (1 << 7);
+               break;
+       case FEC_3_4:
+               tps |= (2 << 7);
+               break;
+       case FEC_5_6:
+               tps |= (3 << 7);
+               break;
+       case FEC_7_8:
+               tps |= (4 << 7);
+               break;
+       case FEC_1_2:
+       case FEC_AUTO:
+       default:
+               /* tps |= (0 << 7) */;
+       }
+
+       switch (op->code_rate_LP) {
+       case FEC_2_3:
+               tps |= (1 << 4);
+               break;
+       case FEC_3_4:
+               tps |= (2 << 4);
+               break;
+       case FEC_5_6:
+               tps |= (3 << 4);
+               break;
+       case FEC_7_8:
+               tps |= (4 << 4);
+               break;
+       case FEC_1_2:
+       case FEC_AUTO:
+       default:
+               /* tps |= (0 << 4) */;
+       }
+
+       switch (op->modulation) {
+       case QAM_16:
+               tps |= (1 << 13);
+               break;
+       case QAM_64:
+               tps |= (2 << 13);
+               break;
+       case QPSK:
+       default:
+               /* tps |= (0 << 13) */;
+       }
+
+       switch (op->transmission_mode) {
+       case TRANSMISSION_MODE_8K:
+               tps |= (1 << 0);
+               break;
+       case TRANSMISSION_MODE_2K:
+       default:
+               /* tps |= (0 << 0) */;
+       }
+
+       switch (op->guard_interval) {
+       case GUARD_INTERVAL_1_16:
+               tps |= (1 << 2);
+               break;
+       case GUARD_INTERVAL_1_8:
+               tps |= (2 << 2);
+               break;
+       case GUARD_INTERVAL_1_4:
+               tps |= (3 << 2);
+               break;
+       case GUARD_INTERVAL_1_32:
+       default:
+               /* tps |= (0 << 2) */;
+       }
+
+       switch (op->hierarchy) {
+       case HIERARCHY_1:
+               tps |= (1 << 10);
+               break;
+       case HIERARCHY_2:
+               tps |= (2 << 10);
+               break;
+       case HIERARCHY_4:
+               tps |= (3 << 10);
+               break;
+       case HIERARCHY_NONE:
+       default:
+               /* tps |= (0 << 10) */;
+       }
+
+       return tps;
+}
+
+struct cinergyt2_fe_state {
+       struct dvb_frontend fe;
+       struct dvb_usb_device *d;
+};
+
+static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
+                                       fe_status_t *status)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_get_status_msg result;
+       u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
+       int ret;
+
+       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
+                       sizeof(result), 0);
+       if (ret < 0)
+               return ret;
+
+       *status = 0;
+
+       if (0xffff - le16_to_cpu(result.gain) > 30)
+               *status |= FE_HAS_SIGNAL;
+       if (result.lock_bits & (1 << 6))
+               *status |= FE_HAS_LOCK;
+       if (result.lock_bits & (1 << 5))
+               *status |= FE_HAS_SYNC;
+       if (result.lock_bits & (1 << 4))
+               *status |= FE_HAS_CARRIER;
+       if (result.lock_bits & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+                       (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_get_status_msg status;
+       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
+       int ret;
+
+       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+                               sizeof(status), 0);
+       if (ret < 0)
+               return ret;
+
+       *ber = le32_to_cpu(status.viterbi_error_rate);
+       return 0;
+}
+
+static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_get_status_msg status;
+       u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
+       int ret;
+
+       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
+                               sizeof(status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
+                       ret);
+               return ret;
+       }
+       *unc = le32_to_cpu(status.uncorrected_block_count);
+       return 0;
+}
+
+static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
+                                               u16 *strength)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_get_status_msg status;
+       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
+       int ret;
+
+       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+                               sizeof(status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_signal_strength() Failed!"
+                       " (Error=%d)\n", ret);
+               return ret;
+       }
+       *strength = (0xffff - le16_to_cpu(status.gain));
+       return 0;
+}
+
+static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_get_status_msg status;
+       char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
+       int ret;
+
+       ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+                               sizeof(status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
+               return ret;
+       }
+       *snr = (status.snr << 8) | status.snr;
+       return 0;
+}
+
+static int cinergyt2_fe_init(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
+{
+       deb_info("cinergyt2_fe_sleep() Called\n");
+       return 0;
+}
+
+static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
+                               struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 800;
+       return 0;
+}
+
+static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       struct dvbt_set_parameters_msg param;
+       char result[2];
+       int err;
+
+       param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
+       param.tps = cpu_to_le16(compute_tps(fep));
+       param.freq = cpu_to_le32(fep->frequency / 1000);
+       param.flags = 0;
+
+       switch (fep->bandwidth_hz) {
+       default:
+       case 8000000:
+               param.bandwidth = 8;
+               break;
+       case 7000000:
+               param.bandwidth = 7;
+               break;
+       case 6000000:
+               param.bandwidth = 6;
+               break;
+       }
+
+       err = dvb_usb_generic_rw(state->d,
+                       (char *)&param, sizeof(param),
+                       result, sizeof(result), 0);
+       if (err < 0)
+               err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
+
+       return (err < 0) ? err : 0;
+}
+
+static void cinergyt2_fe_release(struct dvb_frontend *fe)
+{
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+       if (state != NULL)
+               kfree(state);
+}
+
+static struct dvb_frontend_ops cinergyt2_fe_ops;
+
+struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
+{
+       struct cinergyt2_fe_state *s = kzalloc(sizeof(
+                                       struct cinergyt2_fe_state), GFP_KERNEL);
+       if (s == NULL)
+               return NULL;
+
+       s->d = d;
+       memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.demodulator_priv = s;
+       return &s->fe;
+}
+
+
+static struct dvb_frontend_ops cinergyt2_fe_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = DRIVER_NAME,
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
+                       | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
+                       | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
+                       | FE_CAN_FEC_AUTO | FE_CAN_QPSK
+                       | FE_CAN_QAM_16 | FE_CAN_QAM_64
+                       | FE_CAN_QAM_AUTO
+                       | FE_CAN_TRANSMISSION_MODE_AUTO
+                       | FE_CAN_GUARD_INTERVAL_AUTO
+                       | FE_CAN_HIERARCHY_AUTO
+                       | FE_CAN_RECOVER
+                       | FE_CAN_MUTE_TS
+       },
+
+       .release                = cinergyt2_fe_release,
+
+       .init                   = cinergyt2_fe_init,
+       .sleep                  = cinergyt2_fe_sleep,
+
+       .set_frontend           = cinergyt2_fe_set_frontend,
+       .get_tune_settings      = cinergyt2_fe_get_tune_settings,
+
+       .read_status            = cinergyt2_fe_read_status,
+       .read_ber               = cinergyt2_fe_read_ber,
+       .read_signal_strength   = cinergyt2_fe_read_signal_strength,
+       .read_snr               = cinergyt2_fe_read_snr,
+       .read_ucblocks          = cinergyt2_fe_read_unc_blocks,
+};
diff --git a/drivers/media/usb/dvb-usb/cinergyT2.h b/drivers/media/usb/dvb-usb/cinergyT2.h
new file mode 100644 (file)
index 0000000..84efe03
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
+ *
+ * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
+ *
+ * Based on the dvb-usb-framework code and the
+ * original Terratec Cinergy T2 driver by:
+ *
+ * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
+ *                  Holger Waechtler <holger@qanu.de>
+ *
+ *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
+ *
+ * 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_USB_CINERGYT2_H_
+#define _DVB_USB_CINERGYT2_H_
+
+#include <linux/usb/input.h>
+
+#define DVB_USB_LOG_PREFIX "cinergyT2"
+#include "dvb-usb.h"
+
+#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
+
+extern int dvb_usb_cinergyt2_debug;
+
+#define deb_info(args...)  dprintk(dvb_usb_cinergyt2_debug,  0x001, args)
+#define deb_xfer(args...)  dprintk(dvb_usb_cinergyt2_debug,  0x002, args)
+#define deb_pll(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x004, args)
+#define deb_ts(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x008, args)
+#define deb_err(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x010, args)
+#define deb_rc(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x020, args)
+#define deb_fw(args...)    dprintk(dvb_usb_cinergyt2_debug,  0x040, args)
+#define deb_mem(args...)   dprintk(dvb_usb_cinergyt2_debug,  0x080, args)
+#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug,  0x100, args)
+
+
+
+enum cinergyt2_ep1_cmd {
+       CINERGYT2_EP1_PID_TABLE_RESET           = 0x01,
+       CINERGYT2_EP1_PID_SETUP                 = 0x02,
+       CINERGYT2_EP1_CONTROL_STREAM_TRANSFER   = 0x03,
+       CINERGYT2_EP1_SET_TUNER_PARAMETERS      = 0x04,
+       CINERGYT2_EP1_GET_TUNER_STATUS          = 0x05,
+       CINERGYT2_EP1_START_SCAN                = 0x06,
+       CINERGYT2_EP1_CONTINUE_SCAN             = 0x07,
+       CINERGYT2_EP1_GET_RC_EVENTS             = 0x08,
+       CINERGYT2_EP1_SLEEP_MODE                = 0x09,
+       CINERGYT2_EP1_GET_FIRMWARE_VERSION      = 0x0A
+};
+
+
+struct dvbt_get_status_msg {
+       uint32_t freq;
+       uint8_t bandwidth;
+       uint16_t tps;
+       uint8_t flags;
+       __le16 gain;
+       uint8_t snr;
+       __le32 viterbi_error_rate;
+       uint32_t rs_error_rate;
+       __le32 uncorrected_block_count;
+       uint8_t lock_bits;
+       uint8_t prev_lock_bits;
+} __attribute__((packed));
+
+
+struct dvbt_set_parameters_msg {
+       uint8_t cmd;
+       __le32 freq;
+       uint8_t bandwidth;
+       __le16 tps;
+       uint8_t flags;
+} __attribute__((packed));
+
+
+extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
+
+#endif /* _DVB_USB_CINERGYT2_H_ */
+
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
new file mode 100644 (file)
index 0000000..3940bb0
--- /dev/null
@@ -0,0 +1,2043 @@
+/* DVB USB compliant linux driver for Conexant USB reference design.
+ *
+ * The Conexant reference design I saw on their website was only for analogue
+ * capturing (using the cx25842). The box I took to write this driver (reverse
+ * engineered) is the one labeled Medion MD95700. In addition to the cx25842
+ * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
+ * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
+ *
+ * Maybe it is a little bit premature to call this driver cxusb, but I assume
+ * the USB protocol is identical or at least inherited from the reference
+ * design, so it can be reused for the "analogue-only" device (if it will
+ * appear at all).
+ *
+ * TODO: Use the cx25840-driver for the analogue part
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
+ * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
+ *
+ *   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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include <media/tuner.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include "cxusb.h"
+
+#include "cx22702.h"
+#include "lgdt330x.h"
+#include "mt352.h"
+#include "mt352_priv.h"
+#include "zl10353.h"
+#include "tuner-xc2028.h"
+#include "tuner-simple.h"
+#include "mxl5005s.h"
+#include "max2165.h"
+#include "dib7000p.h"
+#include "dib0070.h"
+#include "lgs8gxx.h"
+#include "atbm8830.h"
+
+/* debug */
+static int dvb_usb_cxusb_debug;
+module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_info(args...)   dprintk(dvb_usb_cxusb_debug, 0x03, args)
+#define deb_i2c(args...)    dprintk(dvb_usb_cxusb_debug, 0x02, args)
+
+static int cxusb_ctrl_msg(struct dvb_usb_device *d,
+                         u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       int wo = (rbuf == NULL || rlen == 0); /* write-only */
+       u8 sndbuf[1+wlen];
+       memset(sndbuf, 0, 1+wlen);
+
+       sndbuf[0] = cmd;
+       memcpy(&sndbuf[1], wbuf, wlen);
+       if (wo)
+               return dvb_usb_generic_write(d, sndbuf, 1+wlen);
+       else
+               return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
+}
+
+/* GPIO */
+static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
+{
+       struct cxusb_state *st = d->priv;
+       u8 o[2], i;
+
+       if (st->gpio_write_state[GPIO_TUNER] == onoff)
+               return;
+
+       o[0] = GPIO_TUNER;
+       o[1] = onoff;
+       cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
+
+       if (i != 0x01)
+               deb_info("gpio_write failed.\n");
+
+       st->gpio_write_state[GPIO_TUNER] = onoff;
+}
+
+static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
+                                u8 newval)
+{
+       u8 o[2], gpio_state;
+       int rc;
+
+       o[0] = 0xff & ~changemask;      /* mask of bits to keep */
+       o[1] = newval & changemask;     /* new values for bits  */
+
+       rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
+       if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
+               deb_info("bluebird_gpio_write failed.\n");
+
+       return rc < 0 ? rc : gpio_state;
+}
+
+static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
+{
+       cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
+       msleep(5);
+       cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
+}
+
+static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
+{
+       cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
+}
+
+static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
+               u8 addr, int onoff)
+{
+       u8  o[2] = {addr, onoff};
+       u8  i;
+       int rc;
+
+       rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
+
+       if (rc < 0)
+               return rc;
+       if (i == 0x01)
+               return 0;
+       else {
+               deb_info("gpio_write failed.\n");
+               return -EIO;
+       }
+}
+
+/* I2C */
+static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                         int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+
+               if (d->udev->descriptor.idVendor == USB_VID_MEDION)
+                       switch (msg[i].addr) {
+                       case 0x63:
+                               cxusb_gpio_tuner(d, 0);
+                               break;
+                       default:
+                               cxusb_gpio_tuner(d, 1);
+                               break;
+                       }
+
+               if (msg[i].flags & I2C_M_RD) {
+                       /* read only */
+                       u8 obuf[3], ibuf[1+msg[i].len];
+                       obuf[0] = 0;
+                       obuf[1] = msg[i].len;
+                       obuf[2] = msg[i].addr;
+                       if (cxusb_ctrl_msg(d, CMD_I2C_READ,
+                                          obuf, 3,
+                                          ibuf, 1+msg[i].len) < 0) {
+                               warn("i2c read failed");
+                               break;
+                       }
+                       memcpy(msg[i].buf, &ibuf[1], msg[i].len);
+               } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
+                          msg[i].addr == msg[i+1].addr) {
+                       /* write to then read from same address */
+                       u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
+                       obuf[0] = msg[i].len;
+                       obuf[1] = msg[i+1].len;
+                       obuf[2] = msg[i].addr;
+                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
+
+                       if (cxusb_ctrl_msg(d, CMD_I2C_READ,
+                                          obuf, 3+msg[i].len,
+                                          ibuf, 1+msg[i+1].len) < 0)
+                               break;
+
+                       if (ibuf[0] != 0x08)
+                               deb_i2c("i2c read may have failed\n");
+
+                       memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
+
+                       i++;
+               } else {
+                       /* write only */
+                       u8 obuf[2+msg[i].len], ibuf;
+                       obuf[0] = msg[i].addr;
+                       obuf[1] = msg[i].len;
+                       memcpy(&obuf[2], msg[i].buf, msg[i].len);
+
+                       if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
+                                          2+msg[i].len, &ibuf,1) < 0)
+                               break;
+                       if (ibuf != 0x08)
+                               deb_i2c("i2c write may have failed\n");
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i == num ? num : -EREMOTEIO;
+}
+
+static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cxusb_i2c_algo = {
+       .master_xfer   = cxusb_i2c_xfer,
+       .functionality = cxusb_i2c_func,
+};
+
+static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b = 0;
+       if (onoff)
+               return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
+       else
+               return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
+}
+
+static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+       if (!onoff)
+               return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
+       if (d->state == DVB_USB_STATE_INIT &&
+           usb_set_interface(d->udev, 0, 0) < 0)
+               err("set interface failed");
+       do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
+                  !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
+                  !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
+       if (!ret) {
+               /* FIXME: We don't know why, but we need to configure the
+                * lgdt3303 with the register settings below on resume */
+               int i;
+               u8 buf, bufs[] = {
+                       0x0e, 0x2, 0x00, 0x7f,
+                       0x0e, 0x2, 0x02, 0xfe,
+                       0x0e, 0x2, 0x02, 0x01,
+                       0x0e, 0x2, 0x00, 0x03,
+                       0x0e, 0x2, 0x0d, 0x40,
+                       0x0e, 0x2, 0x0e, 0x87,
+                       0x0e, 0x2, 0x0f, 0x8e,
+                       0x0e, 0x2, 0x10, 0x01,
+                       0x0e, 0x2, 0x14, 0xd7,
+                       0x0e, 0x2, 0x47, 0x88,
+               };
+               msleep(20);
+               for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
+                       ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
+                                            bufs+i, 4, &buf, 1);
+                       if (ret)
+                               break;
+                       if (buf != 0x8)
+                               return -EREMOTEIO;
+               }
+       }
+       return ret;
+}
+
+static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b = 0;
+       if (onoff)
+               return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
+       else
+               return 0;
+}
+
+static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int rc = 0;
+
+       rc = cxusb_power_ctrl(d, onoff);
+       if (!onoff)
+               cxusb_nano2_led(d, 0);
+
+       return rc;
+}
+
+static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+       u8  b;
+       ret = cxusb_power_ctrl(d, onoff);
+       if (!onoff)
+               return ret;
+
+       msleep(128);
+       cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
+       msleep(100);
+       return ret;
+}
+
+static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       u8 buf[2] = { 0x03, 0x00 };
+       if (onoff)
+               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
+       else
+               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
+
+       return 0;
+}
+
+static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       if (onoff)
+               cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
+       else
+               cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
+                              NULL, 0, NULL, 0);
+       return 0;
+}
+
+static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
+{
+       int       ep = d->props.generic_bulk_ctrl_endpoint;
+       const int timeout = 100;
+       const int junk_len = 32;
+       u8        *junk;
+       int       rd_count;
+
+       /* Discard remaining data in video pipe */
+       junk = kmalloc(junk_len, GFP_KERNEL);
+       if (!junk)
+               return;
+       while (1) {
+               if (usb_bulk_msg(d->udev,
+                       usb_rcvbulkpipe(d->udev, ep),
+                       junk, junk_len, &rd_count, timeout) < 0)
+                       break;
+               if (!rd_count)
+                       break;
+       }
+       kfree(junk);
+}
+
+static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
+{
+       struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
+       const int timeout = 100;
+       const int junk_len = p->u.bulk.buffersize;
+       u8        *junk;
+       int       rd_count;
+
+       /* Discard remaining data in video pipe */
+       junk = kmalloc(junk_len, GFP_KERNEL);
+       if (!junk)
+               return;
+       while (1) {
+               if (usb_bulk_msg(d->udev,
+                       usb_rcvbulkpipe(d->udev, p->endpoint),
+                       junk, junk_len, &rd_count, timeout) < 0)
+                       break;
+               if (!rd_count)
+                       break;
+       }
+       kfree(junk);
+}
+
+static int cxusb_d680_dmb_streaming_ctrl(
+               struct dvb_usb_adapter *adap, int onoff)
+{
+       if (onoff) {
+               u8 buf[2] = { 0x03, 0x00 };
+               cxusb_d680_dmb_drain_video(adap->dev);
+               return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
+                       buf, sizeof(buf), NULL, 0);
+       } else {
+               int ret = cxusb_ctrl_msg(adap->dev,
+                       CMD_STREAMING_OFF, NULL, 0, NULL, 0);
+               return ret;
+       }
+}
+
+static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       u8 ircode[4];
+       int i;
+
+       cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
+
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+
+       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+               if (rc5_custom(&keymap[i]) == ircode[2] &&
+                   rc5_data(&keymap[i]) == ircode[3]) {
+                       *event = keymap[i].keycode;
+                       *state = REMOTE_KEY_PRESSED;
+
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
+                                   int *state)
+{
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       u8 ircode[4];
+       int i;
+       struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
+                              .buf = ircode, .len = 4 };
+
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+
+       if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
+               return 0;
+
+       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+               if (rc5_custom(&keymap[i]) == ircode[1] &&
+                   rc5_data(&keymap[i]) == ircode[2]) {
+                       *event = keymap[i].keycode;
+                       *state = REMOTE_KEY_PRESSED;
+
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
+               int *state)
+{
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       u8 ircode[2];
+       int i;
+
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+
+       if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
+               return 0;
+
+       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+               if (rc5_custom(&keymap[i]) == ircode[0] &&
+                   rc5_data(&keymap[i]) == ircode[1]) {
+                       *event = keymap[i].keycode;
+                       *state = REMOTE_KEY_PRESSED;
+
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static struct rc_map_table rc_map_dvico_mce_table[] = {
+       { 0xfe02, KEY_TV },
+       { 0xfe0e, KEY_MP3 },
+       { 0xfe1a, KEY_DVD },
+       { 0xfe1e, KEY_FAVORITES },
+       { 0xfe16, KEY_SETUP },
+       { 0xfe46, KEY_POWER2 },
+       { 0xfe0a, KEY_EPG },
+       { 0xfe49, KEY_BACK },
+       { 0xfe4d, KEY_MENU },
+       { 0xfe51, KEY_UP },
+       { 0xfe5b, KEY_LEFT },
+       { 0xfe5f, KEY_RIGHT },
+       { 0xfe53, KEY_DOWN },
+       { 0xfe5e, KEY_OK },
+       { 0xfe59, KEY_INFO },
+       { 0xfe55, KEY_TAB },
+       { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
+       { 0xfe12, KEY_NEXTSONG },       /* Skip */
+       { 0xfe42, KEY_ENTER      },     /* Windows/Start */
+       { 0xfe15, KEY_VOLUMEUP },
+       { 0xfe05, KEY_VOLUMEDOWN },
+       { 0xfe11, KEY_CHANNELUP },
+       { 0xfe09, KEY_CHANNELDOWN },
+       { 0xfe52, KEY_CAMERA },
+       { 0xfe5a, KEY_TUNER },  /* Live */
+       { 0xfe19, KEY_OPEN },
+       { 0xfe0b, KEY_1 },
+       { 0xfe17, KEY_2 },
+       { 0xfe1b, KEY_3 },
+       { 0xfe07, KEY_4 },
+       { 0xfe50, KEY_5 },
+       { 0xfe54, KEY_6 },
+       { 0xfe48, KEY_7 },
+       { 0xfe4c, KEY_8 },
+       { 0xfe58, KEY_9 },
+       { 0xfe13, KEY_ANGLE },  /* Aspect */
+       { 0xfe03, KEY_0 },
+       { 0xfe1f, KEY_ZOOM },
+       { 0xfe43, KEY_REWIND },
+       { 0xfe47, KEY_PLAYPAUSE },
+       { 0xfe4f, KEY_FASTFORWARD },
+       { 0xfe57, KEY_MUTE },
+       { 0xfe0d, KEY_STOP },
+       { 0xfe01, KEY_RECORD },
+       { 0xfe4e, KEY_POWER },
+};
+
+static struct rc_map_table rc_map_dvico_portable_table[] = {
+       { 0xfc02, KEY_SETUP },       /* Profile */
+       { 0xfc43, KEY_POWER2 },
+       { 0xfc06, KEY_EPG },
+       { 0xfc5a, KEY_BACK },
+       { 0xfc05, KEY_MENU },
+       { 0xfc47, KEY_INFO },
+       { 0xfc01, KEY_TAB },
+       { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
+       { 0xfc49, KEY_VOLUMEUP },
+       { 0xfc09, KEY_VOLUMEDOWN },
+       { 0xfc54, KEY_CHANNELUP },
+       { 0xfc0b, KEY_CHANNELDOWN },
+       { 0xfc16, KEY_CAMERA },
+       { 0xfc40, KEY_TUNER },  /* ATV/DTV */
+       { 0xfc45, KEY_OPEN },
+       { 0xfc19, KEY_1 },
+       { 0xfc18, KEY_2 },
+       { 0xfc1b, KEY_3 },
+       { 0xfc1a, KEY_4 },
+       { 0xfc58, KEY_5 },
+       { 0xfc59, KEY_6 },
+       { 0xfc15, KEY_7 },
+       { 0xfc14, KEY_8 },
+       { 0xfc17, KEY_9 },
+       { 0xfc44, KEY_ANGLE },  /* Aspect */
+       { 0xfc55, KEY_0 },
+       { 0xfc07, KEY_ZOOM },
+       { 0xfc0a, KEY_REWIND },
+       { 0xfc08, KEY_PLAYPAUSE },
+       { 0xfc4b, KEY_FASTFORWARD },
+       { 0xfc5b, KEY_MUTE },
+       { 0xfc04, KEY_STOP },
+       { 0xfc56, KEY_RECORD },
+       { 0xfc57, KEY_POWER },
+       { 0xfc41, KEY_UNKNOWN },    /* INPUT */
+       { 0xfc00, KEY_UNKNOWN },    /* HD */
+};
+
+static struct rc_map_table rc_map_d680_dmb_table[] = {
+       { 0x0038, KEY_UNKNOWN },        /* TV/AV */
+       { 0x080c, KEY_ZOOM },
+       { 0x0800, KEY_0 },
+       { 0x0001, KEY_1 },
+       { 0x0802, KEY_2 },
+       { 0x0003, KEY_3 },
+       { 0x0804, KEY_4 },
+       { 0x0005, KEY_5 },
+       { 0x0806, KEY_6 },
+       { 0x0007, KEY_7 },
+       { 0x0808, KEY_8 },
+       { 0x0009, KEY_9 },
+       { 0x000a, KEY_MUTE },
+       { 0x0829, KEY_BACK },
+       { 0x0012, KEY_CHANNELUP },
+       { 0x0813, KEY_CHANNELDOWN },
+       { 0x002b, KEY_VOLUMEUP },
+       { 0x082c, KEY_VOLUMEDOWN },
+       { 0x0020, KEY_UP },
+       { 0x0821, KEY_DOWN },
+       { 0x0011, KEY_LEFT },
+       { 0x0810, KEY_RIGHT },
+       { 0x000d, KEY_OK },
+       { 0x081f, KEY_RECORD },
+       { 0x0017, KEY_PLAYPAUSE },
+       { 0x0816, KEY_PLAYPAUSE },
+       { 0x000b, KEY_STOP },
+       { 0x0827, KEY_FASTFORWARD },
+       { 0x0026, KEY_REWIND },
+       { 0x081e, KEY_UNKNOWN },    /* Time Shift */
+       { 0x000e, KEY_UNKNOWN },    /* Snapshot */
+       { 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
+       { 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
+       { 0x0814, KEY_UNKNOWN },    /* Shuffle */
+       { 0x0025, KEY_POWER },
+};
+
+static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
+{
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
+       static u8 reset []         = { RESET,      0x80 };
+       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
+       static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
+       static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
+       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+       mt352_write(fe, clock_config,   sizeof(clock_config));
+       udelay(200);
+       mt352_write(fe, reset,          sizeof(reset));
+       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+       return 0;
+}
+
+static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
+{      /* used in both lgz201 and th7579 */
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
+       static u8 reset []         = { RESET,      0x80 };
+       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
+       static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
+       static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
+       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+       mt352_write(fe, clock_config,   sizeof(clock_config));
+       udelay(200);
+       mt352_write(fe, reset,          sizeof(reset));
+       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+       return 0;
+}
+
+static struct cx22702_config cxusb_cx22702_config = {
+       .demod_address = 0x63,
+       .output_mode = CX22702_PARALLEL_OUTPUT,
+};
+
+static struct lgdt330x_config cxusb_lgdt3303_config = {
+       .demod_address = 0x0e,
+       .demod_chip    = LGDT3303,
+};
+
+static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
+       .demod_address       = 0x0e,
+       .demod_chip          = LGDT3303,
+       .clock_polarity_flip = 2,
+};
+
+static struct mt352_config cxusb_dee1601_config = {
+       .demod_address = 0x0f,
+       .demod_init    = cxusb_dee1601_demod_init,
+};
+
+static struct zl10353_config cxusb_zl10353_dee1601_config = {
+       .demod_address = 0x0f,
+       .parallel_ts = 1,
+};
+
+static struct mt352_config cxusb_mt352_config = {
+       /* used in both lgz201 and th7579 */
+       .demod_address = 0x0f,
+       .demod_init    = cxusb_mt352_demod_init,
+};
+
+static struct zl10353_config cxusb_zl10353_xc3028_config = {
+       .demod_address = 0x0f,
+       .if2 = 45600,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
+       .demod_address = 0x0f,
+       .if2 = 45600,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+};
+
+static struct mt352_config cxusb_mt352_xc3028_config = {
+       .demod_address = 0x0f,
+       .if2 = 4560,
+       .no_tuner = 1,
+       .demod_init = cxusb_mt352_demod_init,
+};
+
+/* FIXME: needs tweaking */
+static struct mxl5005s_config aver_a868r_tuner = {
+       .i2c_address     = 0x63,
+       .if_freq         = 6000000UL,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_C,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+/* FIXME: needs tweaking */
+static struct mxl5005s_config d680_dmb_tuner = {
+       .i2c_address     = 0x63,
+       .if_freq         = 36125000UL,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_C,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static struct max2165_config mygica_d689_max2165_cfg = {
+       .i2c_address = 0x60,
+       .osc_clk = 20
+};
+
+/* Callbacks for DVB USB */
+static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
+                  &adap->dev->i2c_adap, 0x61,
+                  TUNER_PHILIPS_FMD1216ME_MK3);
+       return 0;
+}
+
+static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
+                  NULL, DVB_PLL_THOMSON_DTT7579);
+       return 0;
+}
+
+static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
+       return 0;
+}
+
+static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
+                  NULL, DVB_PLL_THOMSON_DTT7579);
+       return 0;
+}
+
+static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
+                  &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
+       return 0;
+}
+
+static int dvico_bluebird_xc2028_callback(void *ptr, int component,
+                                         int command, int arg)
+{
+       struct dvb_usb_adapter *adap = ptr;
+       struct dvb_usb_device *d = adap->dev;
+
+       switch (command) {
+       case XC2028_TUNER_RESET:
+               deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
+               cxusb_bluebird_gpio_pulse(d, 0x01, 1);
+               break;
+       case XC2028_RESET_CLK:
+               deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
+               break;
+       default:
+               deb_info("%s: unknown command %d, arg %d\n", __func__,
+                        command, arg);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_frontend      *fe;
+       struct xc2028_config      cfg = {
+               .i2c_adap  = &adap->dev->i2c_adap,
+               .i2c_addr  = 0x61,
+       };
+       static struct xc2028_ctrl ctl = {
+               .fname       = XC2028_DEFAULT_FIRMWARE,
+               .max_len     = 64,
+               .demod       = XC3028_FE_ZARLINK456,
+       };
+
+       /* FIXME: generalize & move to common area */
+       adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
+
+       fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
+       if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
+               return -EIO;
+
+       fe->ops.tuner_ops.set_config(fe, &ctl);
+
+       return 0;
+}
+
+static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
+                  &adap->dev->i2c_adap, &aver_a868r_tuner);
+       return 0;
+}
+
+static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_frontend *fe;
+       fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
+                       &adap->dev->i2c_adap, &d680_dmb_tuner);
+       return (fe == NULL) ? -EIO : 0;
+}
+
+static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_frontend *fe;
+       fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
+                       &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
+       return (fe == NULL) ? -EIO : 0;
+}
+
+static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       u8 b;
+       if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
+
+       adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
+                                        &cxusb_lgdt3303_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
+                             &adap->dev->i2c_adap);
+       if (adap->fe_adap[0].fe != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       /* used in both lgz201 and th7579 */
+       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
+                                        &cxusb_zl10353_dee1601_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       u8 ircode[4];
+       int i;
+       struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
+                              .buf = ircode, .len = 4 };
+
+       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       /* reset the tuner and demodulator */
+       cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
+       cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
+       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
+
+       adap->fe_adap[0].fe =
+               dvb_attach(zl10353_attach,
+                          &cxusb_zl10353_xc3028_config_no_i2c_gate,
+                          &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) == NULL)
+               return -EIO;
+
+       /* try to determine if there is no IR decoder on the I2C bus */
+       for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
+               msleep(20);
+               if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
+                       goto no_IR;
+               if (ircode[0] == 0 && ircode[1] == 0)
+                       continue;
+               if (ircode[2] + ircode[3] != 0xff) {
+no_IR:
+                       adap->dev->props.rc.legacy.rc_map_table = NULL;
+                       info("No IR receiver detected on this device.");
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static struct dibx000_agc_config dib7070_agc_config = {
+       .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+
+       /*
+        * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
+        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
+        */
+       .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
+                (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+       .inv_gain = 600,
+       .time_stabiliz = 10,
+       .alpha_level = 0,
+       .thlock = 118,
+       .wbd_inv = 0,
+       .wbd_ref = 3530,
+       .wbd_sel = 1,
+       .wbd_alpha = 5,
+       .agc1_max = 65535,
+       .agc1_min = 0,
+       .agc2_max = 65535,
+       .agc2_min = 0,
+       .agc1_pt1 = 0,
+       .agc1_pt2 = 40,
+       .agc1_pt3 = 183,
+       .agc1_slope1 = 206,
+       .agc1_slope2 = 255,
+       .agc2_pt1 = 72,
+       .agc2_pt2 = 152,
+       .agc2_slope1 = 88,
+       .agc2_slope2 = 90,
+       .alpha_mant = 17,
+       .alpha_exp = 27,
+       .beta_mant = 23,
+       .beta_exp = 51,
+       .perform_agc_softsplit = 0,
+};
+
+static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
+       .internal = 60000,
+       .sampling = 15000,
+       .pll_prediv = 1,
+       .pll_ratio = 20,
+       .pll_range = 3,
+       .pll_reset = 1,
+       .pll_bypass = 0,
+       .enable_refdiv = 0,
+       .bypclk_div = 0,
+       .IO_CLK_en_core = 1,
+       .ADClkSrc = 1,
+       .modulo = 2,
+       /* refsel, sel, freq_15k */
+       .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
+       .ifreq = (0 << 25) | 0,
+       .timf = 20452225,
+       .xtal_hz = 12000000,
+};
+
+static struct dib7000p_config cxusb_dualdig4_rev2_config = {
+       .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &dib7070_agc_config,
+       .bw  = &dib7070_bw_config_12_mhz,
+       .tuner_is_baseband = 1,
+       .spur_protect = 1,
+
+       .gpio_dir = 0xfcef,
+       .gpio_val = 0x0110,
+
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+};
+
+static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                    &cxusb_dualdig4_rev2_config) < 0) {
+               printk(KERN_WARNING "Unable to enumerate dib7000p\n");
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+                             &cxusb_dualdig4_rev2_config);
+       if (adap->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+       return dib7000p_set_gpio(fe, 8, 0, !onoff);
+}
+
+static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       return 0;
+}
+
+static struct dib0070_config dib7070p_dib0070_config = {
+       .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+       .reset = dib7070_tuner_reset,
+       .sleep = dib7070_tuner_sleep,
+       .clock_khz = 12000,
+};
+
+struct dib0700_adapter_state {
+       int (*set_param_save) (struct dvb_frontend *);
+};
+
+static int dib7070_set_param_override(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+
+       u16 offset;
+       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
+       switch (band) {
+       case BAND_VHF: offset = 950; break;
+       default:
+       case BAND_UHF: offset = 550; break;
+       }
+
+       dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+
+       return state->set_param_save(fe);
+}
+
+static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c =
+               dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+                                       DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
+           &dib7070p_dib0070_config) == NULL)
+               return -ENODEV;
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
+       return 0;
+}
+
+static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
+               err("set interface failed");
+
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
+
+       /* reset the tuner and demodulator */
+       cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
+       cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
+       cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
+
+       adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
+                                        &cxusb_zl10353_xc3028_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach,
+                                        &cxusb_mt352_xc3028_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL)
+               return 0;
+
+       return -EIO;
+}
+
+static struct lgs8gxx_config d680_lgs8gl5_cfg = {
+       .prod = LGS8GXX_PROD_LGS8GL5,
+       .demod_address = 0x19,
+       .serial_ts = 0,
+       .ts_clk_pol = 0,
+       .ts_clk_gated = 1,
+       .if_clk_freq = 30400, /* 30.4 MHz */
+       .if_freq = 5725, /* 5.725 MHz */
+       .if_neg_center = 0,
+       .ext_adc = 0,
+       .adc_signed = 0,
+       .if_neg_edge = 0,
+};
+
+static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap->dev;
+       int n;
+
+       /* Select required USB configuration */
+       if (usb_set_interface(d->udev, 0, 0) < 0)
+               err("set interface failed");
+
+       /* Unblock all USB pipes */
+       usb_clear_halt(d->udev,
+               usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+       usb_clear_halt(d->udev,
+               usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+       usb_clear_halt(d->udev,
+               usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
+
+       /* Drain USB pipes to avoid hang after reboot */
+       for (n = 0;  n < 5;  n++) {
+               cxusb_d680_dmb_drain_message(d);
+               cxusb_d680_dmb_drain_video(d);
+               msleep(200);
+       }
+
+       /* Reset the tuner */
+       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
+               err("clear tuner gpio failed");
+               return -EIO;
+       }
+       msleep(100);
+       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
+               err("set tuner gpio failed");
+               return -EIO;
+       }
+       msleep(100);
+
+       /* Attach frontend */
+       adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
+       if (adap->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static struct atbm8830_config mygica_d689_atbm8830_cfg = {
+       .prod = ATBM8830_PROD_8830,
+       .demod_address = 0x40,
+       .serial_ts = 0,
+       .ts_sampling_edge = 1,
+       .ts_clk_gated = 0,
+       .osc_clk_freq = 30400, /* in kHz */
+       .if_freq = 0, /* zero IF */
+       .zif_swap_iq = 1,
+       .agc_min = 0x2E,
+       .agc_max = 0x90,
+       .agc_hold_loop = 0,
+};
+
+static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap->dev;
+
+       /* Select required USB configuration */
+       if (usb_set_interface(d->udev, 0, 0) < 0)
+               err("set interface failed");
+
+       /* Unblock all USB pipes */
+       usb_clear_halt(d->udev,
+               usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+       usb_clear_halt(d->udev,
+               usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+       usb_clear_halt(d->udev,
+               usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
+
+
+       /* Reset the tuner */
+       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
+               err("clear tuner gpio failed");
+               return -EIO;
+       }
+       msleep(100);
+       if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
+               err("set tuner gpio failed");
+               return -EIO;
+       }
+       msleep(100);
+
+       /* Attach frontend */
+       adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
+               &d->i2c_adap);
+       if (adap->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+/*
+ * DViCO has shipped two devices with the same USB ID, but only one of them
+ * needs a firmware download.  Check the device class details to see if they
+ * have non-default values to decide whether the device is actually cold or
+ * not, and forget a match if it turns out we selected the wrong device.
+ */
+static int bluebird_fx2_identify_state(struct usb_device *udev,
+                                      struct dvb_usb_device_properties *props,
+                                      struct dvb_usb_device_description **desc,
+                                      int *cold)
+{
+       int wascold = *cold;
+
+       *cold = udev->descriptor.bDeviceClass == 0xff &&
+               udev->descriptor.bDeviceSubClass == 0xff &&
+               udev->descriptor.bDeviceProtocol == 0xff;
+
+       if (*cold && !wascold)
+               *desc = NULL;
+
+       return 0;
+}
+
+/*
+ * DViCO bluebird firmware needs the "warm" product ID to be patched into the
+ * firmware file before download.
+ */
+
+static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
+static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
+                                                 const struct firmware *fw)
+{
+       int pos;
+
+       for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
+               int idoff = dvico_firmware_id_offsets[pos];
+
+               if (fw->size < idoff + 4)
+                       continue;
+
+               if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
+                   fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
+                       struct firmware new_fw;
+                       u8 *new_fw_data = vmalloc(fw->size);
+                       int ret;
+
+                       if (!new_fw_data)
+                               return -ENOMEM;
+
+                       memcpy(new_fw_data, fw->data, fw->size);
+                       new_fw.size = fw->size;
+                       new_fw.data = new_fw_data;
+
+                       new_fw_data[idoff + 2] =
+                               le16_to_cpu(udev->descriptor.idProduct) + 1;
+                       new_fw_data[idoff + 3] =
+                               le16_to_cpu(udev->descriptor.idProduct) >> 8;
+
+                       ret = usb_cypress_load_firmware(udev, &new_fw,
+                                                       CYPRESS_FX2);
+                       vfree(new_fw_data);
+                       return ret;
+               }
+       }
+
+       return -EINVAL;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties cxusb_medion_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
+static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
+static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
+
+static int cxusb_probe(struct usb_interface *intf,
+                      const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf,
+                               &cxusb_bluebird_nano2_needsfirmware_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf,
+                                    &cxusb_bluebird_dualdig4_rev2_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0)
+               return 0;
+
+       return -EINVAL;
+}
+
+static struct usb_device_id cxusb_table [] = {
+       { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
+       { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
+       { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
+       { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
+       { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
+       {}              /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, cxusb_table);
+
+static struct dvb_usb_device_properties cxusb_medion_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_cx22702_frontend_attach,
+                       .tuner_attach     = cxusb_fmd1216me_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                                       .stream = {
+                                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+       .power_ctrl       = cxusb_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Medion MD95700 (MDUSBTV-HYBRID)",
+                       { NULL },
+                       { &cxusb_table[0], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-01.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       /* use usb alt setting 0 for EP4 transfer (dvb-t),
+          use usb alt setting 7 for EP2 transfer (atsc) */
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_lgdt3303_frontend_attach,
+                       .tuner_attach     = cxusb_lgh064f_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                                       .stream = {
+                                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_portable_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV5 USB Gold",
+                       { &cxusb_table[1], NULL },
+                       { &cxusb_table[2], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-01.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       /* use usb alt setting 0 for EP4 transfer (dvb-t),
+          use usb alt setting 7 for EP2 transfer (atsc) */
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_dee1601_frontend_attach,
+                       .tuner_attach     = cxusb_dee1601_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x04,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc.legacy = {
+               .rc_interval      = 150,
+               .rc_map_table     = rc_map_dvico_mce_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 3,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T Dual USB",
+                       { &cxusb_table[3], NULL },
+                       { &cxusb_table[4], NULL },
+               },
+               {   "DigitalNow DVB-T Dual USB",
+                       { &cxusb_table[9],  NULL },
+                       { &cxusb_table[10], NULL },
+               },
+               {   "DViCO FusionHDTV DVB-T Dual Digital 2",
+                       { &cxusb_table[11], NULL },
+                       { &cxusb_table[12], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-01.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       /* use usb alt setting 0 for EP4 transfer (dvb-t),
+          use usb alt setting 7 for EP2 transfer (atsc) */
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 2,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_mt352_frontend_attach,
+                       .tuner_attach     = cxusb_lgz201_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x04,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_portable_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
+                       { &cxusb_table[5], NULL },
+                       { &cxusb_table[6], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-01.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       /* use usb alt setting 0 for EP4 transfer (dvb-t),
+          use usb alt setting 7 for EP2 transfer (atsc) */
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_mt352_frontend_attach,
+                       .tuner_attach     = cxusb_dtt7579_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x04,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_portable_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T USB (TH7579)",
+                       { &cxusb_table[7], NULL },
+                       { &cxusb_table[8], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_dualdig4_frontend_attach,
+                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_mce_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
+               .rc_query         = cxusb_bluebird2_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T Dual Digital 4",
+                       { NULL },
+                       { &cxusb_table[13], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+       .identify_state   = bluebird_fx2_identify_state,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_nano2_frontend_attach,
+                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_nano2_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_portable_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_query         = cxusb_bluebird2_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T NANO2",
+                       { NULL },
+                       { &cxusb_table[14], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-02.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       .identify_state    = bluebird_fx2_identify_state,
+
+       .size_of_priv      = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_nano2_frontend_attach,
+                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_nano2_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_portable_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
+                       { &cxusb_table[14], NULL },
+                       { &cxusb_table[15], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_aver_streaming_ctrl,
+                       .frontend_attach  = cxusb_aver_lgdt3303_frontend_attach,
+                       .tuner_attach     = cxusb_mxl5003s_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x04,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+       .power_ctrl       = cxusb_aver_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "AVerMedia AVerTVHD Volar (A868R)",
+                       { NULL },
+                       { &cxusb_table[16], NULL },
+               },
+       }
+};
+
+static
+struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .size_of_priv    = sizeof(struct dib0700_adapter_state),
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl  = cxusb_streaming_ctrl,
+                       .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
+                       .tuner_attach    = cxusb_dualdig4_rev2_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_dvico_mce_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
+               .rc_query         = cxusb_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
+                       { NULL },
+                       { &cxusb_table[17], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
+                       .frontend_attach  = cxusb_d680_dmb_frontend_attach,
+                       .tuner_attach     = cxusb_d680_dmb_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_d680_dmb_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_d680_dmb_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
+               .rc_query         = cxusb_d680_dmb_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {
+                       "Conexant DMB-TH Stick",
+                       { NULL },
+                       { &cxusb_table[18], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl         = CYPRESS_FX2,
+
+       .size_of_priv     = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
+                       .frontend_attach  = cxusb_mygica_d689_frontend_attach,
+                       .tuner_attach     = cxusb_mygica_d689_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               },
+       },
+
+       .power_ctrl       = cxusb_d680_dmb_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_d680_dmb_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
+               .rc_query         = cxusb_d680_dmb_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {
+                       "Mygica D689 DMB-TH",
+                       { NULL },
+                       { &cxusb_table[19], NULL },
+               },
+       }
+};
+
+static struct usb_driver cxusb_driver = {
+       .name           = "dvb_usb_cxusb",
+       .probe          = cxusb_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = cxusb_table,
+};
+
+module_usb_driver(cxusb_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
+MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
new file mode 100644 (file)
index 0000000..1a51eaf
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _DVB_USB_CXUSB_H_
+#define _DVB_USB_CXUSB_H_
+
+#define DVB_USB_LOG_PREFIX "cxusb"
+#include "dvb-usb.h"
+
+/* usb commands - some of it are guesses, don't have a reference yet */
+#define CMD_BLUEBIRD_GPIO_RW 0x05
+
+#define CMD_I2C_WRITE     0x08
+#define CMD_I2C_READ      0x09
+
+#define CMD_GPIO_READ     0x0d
+#define CMD_GPIO_WRITE    0x0e
+#define     GPIO_TUNER         0x02
+
+#define CMD_POWER_OFF     0xdc
+#define CMD_POWER_ON      0xde
+
+#define CMD_STREAMING_ON  0x36
+#define CMD_STREAMING_OFF 0x37
+
+#define CMD_AVER_STREAM_ON  0x18
+#define CMD_AVER_STREAM_OFF 0x19
+
+#define CMD_GET_IR_CODE   0x47
+
+#define CMD_ANALOG        0x50
+#define CMD_DIGITAL       0x51
+
+struct cxusb_state {
+       u8 gpio_write_state[3];
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
new file mode 100644 (file)
index 0000000..7de125c
--- /dev/null
@@ -0,0 +1,75 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     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, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#ifndef _DIB0700_H_
+#define _DIB0700_H_
+
+#define DVB_USB_LOG_PREFIX "dib0700"
+#include "dvb-usb.h"
+
+#include "dib07x0.h"
+
+extern int dvb_usb_dib0700_debug;
+#define deb_info(args...)   dprintk(dvb_usb_dib0700_debug,0x01,args)
+#define deb_fw(args...)     dprintk(dvb_usb_dib0700_debug,0x02,args)
+#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
+#define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
+
+#define REQUEST_SET_USB_XFER_LEN    0x0 /* valid only for firmware version */
+                                       /* higher than 1.21 */
+#define REQUEST_I2C_READ            0x2
+#define REQUEST_I2C_WRITE           0x3
+#define REQUEST_POLL_RC             0x4 /* deprecated in firmware v1.20 */
+#define REQUEST_JUMPRAM             0x8
+#define REQUEST_SET_CLOCK           0xB
+#define REQUEST_SET_GPIO            0xC
+#define REQUEST_ENABLE_VIDEO        0xF
+       // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
+       // 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
+       // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
+#define REQUEST_SET_I2C_PARAM       0x10
+#define REQUEST_SET_RC              0x11
+#define REQUEST_NEW_I2C_READ        0x12
+#define REQUEST_NEW_I2C_WRITE       0x13
+#define REQUEST_GET_VERSION         0x15
+
+struct dib0700_state {
+       u8 channel_state;
+       u16 mt2060_if1[2];
+       u8 rc_toggle;
+       u8 rc_counter;
+       u8 is_dib7000pc;
+       u8 fw_use_new_i2c_api;
+       u8 disable_streaming_master_mode;
+       u32 fw_version;
+       u32 nb_packet_buffer_size;
+       int (*read_status)(struct dvb_frontend *, fe_status_t *);
+       int (*sleep)(struct dvb_frontend* fe);
+       u8 buf[255];
+};
+
+extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
+                              u32 *romversion, u32 *ramversion, u32 *fwtype);
+extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
+extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
+extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
+extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
+extern int dib0700_rc_setup(struct dvb_usb_device *d);
+extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
+extern struct i2c_algorithm dib0700_i2c_algo;
+extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+                       struct dvb_usb_device_description **desc, int *cold);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
+extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
+
+extern int dib0700_device_count;
+extern int dvb_usb_dib0700_ir_proto;
+extern struct dvb_usb_device_properties dib0700_devices[];
+extern struct usb_device_id dib0700_usb_id_table[];
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
new file mode 100644 (file)
index 0000000..ef87229
--- /dev/null
@@ -0,0 +1,845 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     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, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#include "dib0700.h"
+
+/* debug */
+int dvb_usb_dib0700_debug;
+module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int nb_packet_buffer_size = 21;
+module_param(nb_packet_buffer_size, int, 0644);
+MODULE_PARM_DESC(nb_packet_buffer_size,
+       "Set the dib0700 driver data buffer size. This parameter "
+       "corresponds to the number of TS packets. The actual size of "
+       "the data buffer corresponds to this parameter "
+       "multiplied by 188 (default: 21)");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+
+int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
+                       u32 *romversion, u32 *ramversion, u32 *fwtype)
+{
+       struct dib0700_state *st = d->priv;
+       int ret;
+
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+                                 REQUEST_GET_VERSION,
+                                 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                                 st->buf, 16, USB_CTRL_GET_TIMEOUT);
+       if (hwversion != NULL)
+               *hwversion  = (st->buf[0] << 24)  | (st->buf[1] << 16)  |
+                       (st->buf[2] << 8)  | st->buf[3];
+       if (romversion != NULL)
+               *romversion = (st->buf[4] << 24)  | (st->buf[5] << 16)  |
+                       (st->buf[6] << 8)  | st->buf[7];
+       if (ramversion != NULL)
+               *ramversion = (st->buf[8] << 24)  | (st->buf[9] << 16)  |
+                       (st->buf[10] << 8) | st->buf[11];
+       if (fwtype != NULL)
+               *fwtype     = (st->buf[12] << 24) | (st->buf[13] << 16) |
+                       (st->buf[14] << 8) | st->buf[15];
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+/* expecting rx buffer: request data[0] data[1] ... data[2] */
+static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
+{
+       int status;
+
+       deb_data(">>> ");
+       debug_dump(tx, txlen, deb_data);
+
+       status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
+               tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
+               USB_CTRL_GET_TIMEOUT);
+
+       if (status != txlen)
+               deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
+
+       return status < 0 ? status : 0;
+}
+
+/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
+int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+       u16 index, value;
+       int status;
+
+       if (txlen < 2) {
+               err("tx buffer length is smaller than 2. Makes no sense.");
+               return -EINVAL;
+       }
+       if (txlen > 4) {
+               err("tx buffer length is larger than 4. Not supported.");
+               return -EINVAL;
+       }
+
+       deb_data(">>> ");
+       debug_dump(tx,txlen,deb_data);
+
+       value = ((txlen - 2) << 8) | tx[1];
+       index = 0;
+       if (txlen > 2)
+               index |= (tx[2] << 8);
+       if (txlen > 3)
+               index |= tx[3];
+
+       status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
+                       USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
+                       USB_CTRL_GET_TIMEOUT);
+
+       if (status < 0)
+               deb_info("ep 0 read error (status = %d)\n",status);
+
+       deb_data("<<< ");
+       debug_dump(rx, rxlen, deb_data);
+
+       return status; /* length in case of success */
+}
+
+int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
+{
+       struct dib0700_state *st = d->priv;
+       int ret;
+
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       st->buf[0] = REQUEST_SET_GPIO;
+       st->buf[1] = gpio;
+       st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
+
+       ret = dib0700_ctrl_wr(d, st->buf, 3);
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
+{
+       struct dib0700_state *st = d->priv;
+       int ret;
+
+       if (st->fw_version >= 0x10201) {
+               if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+                       err("could not acquire lock");
+                       return -EINTR;
+               }
+
+               st->buf[0] = REQUEST_SET_USB_XFER_LEN;
+               st->buf[1] = (nb_ts_packets >> 8) & 0xff;
+               st->buf[2] = nb_ts_packets & 0xff;
+
+               deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
+
+               ret = dib0700_ctrl_wr(d, st->buf, 3);
+               mutex_unlock(&d->usb_mutex);
+       } else {
+               deb_info("this firmware does not allow to change the USB xfer len\n");
+               ret = -EIO;
+       }
+
+       return ret;
+}
+
+/*
+ * I2C master xfer function (supported in 1.20 firmware)
+ */
+static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
+                               int num)
+{
+       /* The new i2c firmware messages are more reliable and in particular
+          properly support i2c read calls not preceded by a write */
+
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct dib0700_state *st = d->priv;
+       uint8_t bus_mode = 1;  /* 0=eeprom bus, 1=frontend bus */
+       uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
+       uint8_t en_start = 0;
+       uint8_t en_stop = 0;
+       int result, i;
+
+       /* Ensure nobody else hits the i2c bus while we're sending our
+          sequence of messages, (such as the remote control thread) */
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EINTR;
+
+       for (i = 0; i < num; i++) {
+               if (i == 0) {
+                       /* First message in the transaction */
+                       en_start = 1;
+               } else if (!(msg[i].flags & I2C_M_NOSTART)) {
+                       /* Device supports repeated-start */
+                       en_start = 1;
+               } else {
+                       /* Not the first packet and device doesn't support
+                          repeated start */
+                       en_start = 0;
+               }
+               if (i == (num - 1)) {
+                       /* Last message in the transaction */
+                       en_stop = 1;
+               }
+
+               if (msg[i].flags & I2C_M_RD) {
+                       /* Read request */
+                       u16 index, value;
+                       uint8_t i2c_dest;
+
+                       i2c_dest = (msg[i].addr << 1);
+                       value = ((en_start << 7) | (en_stop << 6) |
+                                (msg[i].len & 0x3F)) << 8 | i2c_dest;
+                       /* I2C ctrl + FE bus; */
+                       index = ((gen_mode << 6) & 0xC0) |
+                               ((bus_mode << 4) & 0x30);
+
+                       result = usb_control_msg(d->udev,
+                                                usb_rcvctrlpipe(d->udev, 0),
+                                                REQUEST_NEW_I2C_READ,
+                                                USB_TYPE_VENDOR | USB_DIR_IN,
+                                                value, index, msg[i].buf,
+                                                msg[i].len,
+                                                USB_CTRL_GET_TIMEOUT);
+                       if (result < 0) {
+                               deb_info("i2c read error (status = %d)\n", result);
+                               break;
+                       }
+
+                       deb_data("<<< ");
+                       debug_dump(msg[i].buf, msg[i].len, deb_data);
+
+               } else {
+                       /* Write request */
+                       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+                               err("could not acquire lock");
+                               mutex_unlock(&d->i2c_mutex);
+                               return -EINTR;
+                       }
+                       st->buf[0] = REQUEST_NEW_I2C_WRITE;
+                       st->buf[1] = msg[i].addr << 1;
+                       st->buf[2] = (en_start << 7) | (en_stop << 6) |
+                               (msg[i].len & 0x3F);
+                       /* I2C ctrl + FE bus; */
+                       st->buf[3] = ((gen_mode << 6) & 0xC0) |
+                                ((bus_mode << 4) & 0x30);
+                       /* The Actual i2c payload */
+                       memcpy(&st->buf[4], msg[i].buf, msg[i].len);
+
+                       deb_data(">>> ");
+                       debug_dump(st->buf, msg[i].len + 4, deb_data);
+
+                       result = usb_control_msg(d->udev,
+                                                usb_sndctrlpipe(d->udev, 0),
+                                                REQUEST_NEW_I2C_WRITE,
+                                                USB_TYPE_VENDOR | USB_DIR_OUT,
+                                                0, 0, st->buf, msg[i].len + 4,
+                                                USB_CTRL_GET_TIMEOUT);
+                       mutex_unlock(&d->usb_mutex);
+                       if (result < 0) {
+                               deb_info("i2c write error (status = %d)\n", result);
+                               break;
+                       }
+               }
+       }
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+/*
+ * I2C master xfer function (pre-1.20 firmware)
+ */
+static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
+                                  struct i2c_msg *msg, int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct dib0700_state *st = d->priv;
+       int i,len;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EINTR;
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               mutex_unlock(&d->i2c_mutex);
+               return -EINTR;
+       }
+
+       for (i = 0; i < num; i++) {
+               /* fill in the address */
+               st->buf[1] = msg[i].addr << 1;
+               /* fill the buffer */
+               memcpy(&st->buf[2], msg[i].buf, msg[i].len);
+
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       st->buf[0] = REQUEST_I2C_READ;
+                       st->buf[1] |= 1;
+
+                       /* special thing in the current firmware: when length is zero the read-failed */
+                       len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
+                                       msg[i+1].buf, msg[i+1].len);
+                       if (len <= 0) {
+                               deb_info("I2C read failed on address 0x%02x\n",
+                                               msg[i].addr);
+                               break;
+                       }
+
+                       msg[i+1].len = len;
+
+                       i++;
+               } else {
+                       st->buf[0] = REQUEST_I2C_WRITE;
+                       if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
+                               break;
+               }
+       }
+       mutex_unlock(&d->usb_mutex);
+       mutex_unlock(&d->i2c_mutex);
+
+       return i;
+}
+
+static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+                           int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct dib0700_state *st = d->priv;
+
+       if (st->fw_use_new_i2c_api == 1) {
+               /* User running at least fw 1.20 */
+               return dib0700_i2c_xfer_new(adap, msg, num);
+       } else {
+               /* Use legacy calls */
+               return dib0700_i2c_xfer_legacy(adap, msg, num);
+       }
+}
+
+static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dib0700_i2c_algo = {
+       .master_xfer   = dib0700_i2c_xfer,
+       .functionality = dib0700_i2c_func,
+};
+
+int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+                       struct dvb_usb_device_description **desc, int *cold)
+{
+       s16 ret;
+       u8 *b;
+
+       b = kmalloc(16, GFP_KERNEL);
+       if (!b)
+               return  -ENOMEM;
+
+
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+               REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
+
+       deb_info("FW GET_VERSION length: %d\n",ret);
+
+       *cold = ret <= 0;
+       deb_info("cold: %d\n", *cold);
+
+       kfree(b);
+       return 0;
+}
+
+static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
+       u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
+       u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
+{
+       struct dib0700_state *st = d->priv;
+       int ret;
+
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       st->buf[0] = REQUEST_SET_CLOCK;
+       st->buf[1] = (en_pll << 7) | (pll_src << 6) |
+               (pll_range << 5) | (clock_gpio3 << 4);
+       st->buf[2] = (pll_prediv >> 8)  & 0xff; /* MSB */
+       st->buf[3] =  pll_prediv        & 0xff; /* LSB */
+       st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
+       st->buf[5] =  pll_loopdiv       & 0xff; /* LSB */
+       st->buf[6] = (free_div >> 8)    & 0xff; /* MSB */
+       st->buf[7] =  free_div          & 0xff; /* LSB */
+       st->buf[8] = (dsuScaler >> 8)   & 0xff; /* MSB */
+       st->buf[9] =  dsuScaler         & 0xff; /* LSB */
+
+       ret = dib0700_ctrl_wr(d, st->buf, 10);
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
+{
+       struct dib0700_state *st = d->priv;
+       u16 divider;
+       int ret;
+
+       if (scl_kHz == 0)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       st->buf[0] = REQUEST_SET_I2C_PARAM;
+       divider = (u16) (30000 / scl_kHz);
+       st->buf[1] = 0;
+       st->buf[2] = (u8) (divider >> 8);
+       st->buf[3] = (u8) (divider & 0xff);
+       divider = (u16) (72000 / scl_kHz);
+       st->buf[4] = (u8) (divider >> 8);
+       st->buf[5] = (u8) (divider & 0xff);
+       divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
+       st->buf[6] = (u8) (divider >> 8);
+       st->buf[7] = (u8) (divider & 0xff);
+
+       deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
+               (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
+               st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
+
+       ret = dib0700_ctrl_wr(d, st->buf, 8);
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+
+int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
+{
+       switch (clk_MHz) {
+               case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
+               default: return -EINVAL;
+       }
+       return 0;
+}
+
+static int dib0700_jumpram(struct usb_device *udev, u32 address)
+{
+       int ret = 0, actlen;
+       u8 *buf;
+
+       buf = kmalloc(8, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       buf[0] = REQUEST_JUMPRAM;
+       buf[1] = 0;
+       buf[2] = 0;
+       buf[3] = 0;
+       buf[4] = (address >> 24) & 0xff;
+       buf[5] = (address >> 16) & 0xff;
+       buf[6] = (address >> 8)  & 0xff;
+       buf[7] =  address        & 0xff;
+
+       if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
+               deb_fw("jumpram to 0x%x failed\n",address);
+               goto out;
+       }
+       if (actlen != 8) {
+               deb_fw("jumpram to 0x%x failed\n",address);
+               ret = -EIO;
+               goto out;
+       }
+out:
+       kfree(buf);
+       return ret;
+}
+
+int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
+{
+       struct hexline hx;
+       int pos = 0, ret, act_len, i, adap_num;
+       u8 *buf;
+       u32 fw_version;
+
+       buf = kmalloc(260, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
+               deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
+                               hx.addr, hx.len, hx.chk);
+
+               buf[0] = hx.len;
+               buf[1] = (hx.addr >> 8) & 0xff;
+               buf[2] =  hx.addr       & 0xff;
+               buf[3] = hx.type;
+               memcpy(&buf[4],hx.data,hx.len);
+               buf[4+hx.len] = hx.chk;
+
+               ret = usb_bulk_msg(udev,
+                       usb_sndbulkpipe(udev, 0x01),
+                       buf,
+                       hx.len + 5,
+                       &act_len,
+                       1000);
+
+               if (ret < 0) {
+                       err("firmware download failed at %d with %d",pos,ret);
+                       goto out;
+               }
+       }
+
+       if (ret == 0) {
+               /* start the firmware */
+               if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
+                       info("firmware started successfully.");
+                       msleep(500);
+               }
+       } else
+               ret = -EIO;
+
+       /* the number of ts packet has to be at least 1 */
+       if (nb_packet_buffer_size < 1)
+               nb_packet_buffer_size = 1;
+
+       /* get the fimware version */
+       usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                 REQUEST_GET_VERSION,
+                                 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                                 buf, 16, USB_CTRL_GET_TIMEOUT);
+       fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
+
+       /* set the buffer size - DVB-USB is allocating URB buffers
+        * only after the firwmare download was successful */
+       for (i = 0; i < dib0700_device_count; i++) {
+               for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
+                               adap_num++) {
+                       if (fw_version >= 0x10201) {
+                               dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
+                       } else {
+                               /* for fw version older than 1.20.1,
+                                * the buffersize has to be n times 512 */
+                               dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
+                               if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512)
+                                       dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512;
+                       }
+               }
+       }
+out:
+       kfree(buf);
+       return ret;
+}
+
+int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       int ret;
+
+       if ((onoff != 0) && (st->fw_version >= 0x10201)) {
+               /* for firmware later than 1.20.1,
+                * the USB xfer length can be set  */
+               ret = dib0700_set_usb_xfer_len(adap->dev,
+                       st->nb_packet_buffer_size);
+               if (ret < 0) {
+                       deb_info("can not set the USB xfer len\n");
+                       return ret;
+               }
+       }
+
+       if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       st->buf[0] = REQUEST_ENABLE_VIDEO;
+       /* this bit gives a kind of command,
+        * rather than enabling something or not */
+       st->buf[1] = (onoff << 4) | 0x00;
+
+       if (st->disable_streaming_master_mode == 1)
+               st->buf[2] = 0x00;
+       else
+               st->buf[2] = 0x01 << 4; /* Master mode */
+
+       st->buf[3] = 0x00;
+
+       deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
+
+       st->channel_state &= ~0x3;
+       if ((adap->fe_adap[0].stream.props.endpoint != 2)
+                       && (adap->fe_adap[0].stream.props.endpoint != 3)) {
+               deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
+               if (onoff)
+                       st->channel_state |=    1 << (adap->id);
+               else
+                       st->channel_state |=    1 << ~(adap->id);
+       } else {
+               if (onoff)
+                       st->channel_state |=    1 << (adap->fe_adap[0].stream.props.endpoint-2);
+               else
+                       st->channel_state |=    1 << (3-adap->fe_adap[0].stream.props.endpoint);
+       }
+
+       st->buf[2] |= st->channel_state;
+
+       deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
+
+       ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
+       mutex_unlock(&adap->dev->usb_mutex);
+
+       return ret;
+}
+
+int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
+{
+       struct dvb_usb_device *d = rc->priv;
+       struct dib0700_state *st = d->priv;
+       int new_proto, ret;
+
+       if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
+               err("could not acquire lock");
+               return -EINTR;
+       }
+
+       st->buf[0] = REQUEST_SET_RC;
+       st->buf[1] = 0;
+       st->buf[2] = 0;
+
+       /* Set the IR mode */
+       if (rc_type == RC_TYPE_RC5)
+               new_proto = 1;
+       else if (rc_type == RC_TYPE_NEC)
+               new_proto = 0;
+       else if (rc_type == RC_TYPE_RC6) {
+               if (st->fw_version < 0x10200) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               new_proto = 2;
+       } else {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       st->buf[1] = new_proto;
+
+       ret = dib0700_ctrl_wr(d, st->buf, 3);
+       if (ret < 0) {
+               err("ir protocol setup failed");
+               goto out;
+       }
+
+       d->props.rc.core.protocol = rc_type;
+
+out:
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+/* Number of keypresses to ignore before start repeating */
+#define RC_REPEAT_DELAY_V1_20 10
+
+/* This is the structure of the RC response packet starting in firmware 1.20 */
+struct dib0700_rc_response {
+       u8 report_id;
+       u8 data_state;
+       union {
+               u16 system16;
+               struct {
+                       u8 not_system;
+                       u8 system;
+               };
+       };
+       u8 data;
+       u8 not_data;
+};
+#define RC_MSG_SIZE_V1_20 6
+
+static void dib0700_rc_urb_completion(struct urb *purb)
+{
+       struct dvb_usb_device *d = purb->context;
+       struct dib0700_rc_response *poll_reply;
+       u32 uninitialized_var(keycode);
+       u8 toggle;
+
+       deb_info("%s()\n", __func__);
+       if (d->rc_dev == NULL) {
+               /* This will occur if disable_rc_polling=1 */
+               kfree(purb->transfer_buffer);
+               usb_free_urb(purb);
+               return;
+       }
+
+       poll_reply = purb->transfer_buffer;
+
+       if (purb->status < 0) {
+               deb_info("discontinuing polling\n");
+               kfree(purb->transfer_buffer);
+               usb_free_urb(purb);
+               return;
+       }
+
+       if (purb->actual_length != RC_MSG_SIZE_V1_20) {
+               deb_info("malformed rc msg size=%d\n", purb->actual_length);
+               goto resubmit;
+       }
+
+       deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
+                poll_reply->report_id, poll_reply->data_state,
+                poll_reply->system, poll_reply->not_system,
+                poll_reply->data, poll_reply->not_data,
+                purb->actual_length);
+
+       switch (d->props.rc.core.protocol) {
+       case RC_TYPE_NEC:
+               toggle = 0;
+
+               /* NEC protocol sends repeat code as 0 0 0 FF */
+               if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
+                   && (poll_reply->not_data == 0xff)) {
+                       poll_reply->data_state = 2;
+                       break;
+               }
+
+               if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
+                       deb_data("NEC extended protocol\n");
+                       /* NEC extended code - 24 bits */
+                       keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
+               } else {
+                       deb_data("NEC normal protocol\n");
+                       /* normal NEC code - 16 bits */
+                       keycode = poll_reply->system << 8 | poll_reply->data;
+               }
+
+               break;
+       default:
+               deb_data("RC5 protocol\n");
+               /* RC5 Protocol */
+               toggle = poll_reply->report_id;
+               keycode = poll_reply->system << 8 | poll_reply->data;
+
+               break;
+       }
+
+       if ((poll_reply->data + poll_reply->not_data) != 0xff) {
+               /* Key failed integrity check */
+               err("key failed integrity check: %04x %02x %02x",
+                   poll_reply->system,
+                   poll_reply->data, poll_reply->not_data);
+               goto resubmit;
+       }
+
+       rc_keydown(d->rc_dev, keycode, toggle);
+
+resubmit:
+       /* Clean the buffer before we requeue */
+       memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
+
+       /* Requeue URB */
+       usb_submit_urb(purb, GFP_ATOMIC);
+}
+
+int dib0700_rc_setup(struct dvb_usb_device *d)
+{
+       struct dib0700_state *st = d->priv;
+       struct urb *purb;
+       int ret;
+
+       /* Poll-based. Don't initialize bulk mode */
+       if (st->fw_version < 0x10200)
+               return 0;
+
+       /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
+       purb = usb_alloc_urb(0, GFP_KERNEL);
+       if (purb == NULL) {
+               err("rc usb alloc urb failed");
+               return -ENOMEM;
+       }
+
+       purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
+       if (purb->transfer_buffer == NULL) {
+               err("rc kzalloc failed");
+               usb_free_urb(purb);
+               return -ENOMEM;
+       }
+
+       purb->status = -EINPROGRESS;
+       usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
+                         purb->transfer_buffer, RC_MSG_SIZE_V1_20,
+                         dib0700_rc_urb_completion, d);
+
+       ret = usb_submit_urb(purb, GFP_ATOMIC);
+       if (ret) {
+               err("rc submit urb failed");
+               kfree(purb->transfer_buffer);
+               usb_free_urb(purb);
+       }
+
+       return ret;
+}
+
+static int dib0700_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       int i;
+       struct dvb_usb_device *dev;
+
+       for (i = 0; i < dib0700_device_count; i++)
+               if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
+                   &dev, adapter_nr) == 0) {
+                       struct dib0700_state *st = dev->priv;
+                       u32 hwversion, romversion, fw_version, fwtype;
+
+                       dib0700_get_version(dev, &hwversion, &romversion,
+                               &fw_version, &fwtype);
+
+                       deb_info("Firmware version: %x, %d, 0x%x, %d\n",
+                               hwversion, romversion, fw_version, fwtype);
+
+                       st->fw_version = fw_version;
+                       st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
+
+                       /* Disable polling mode on newer firmwares */
+                       if (st->fw_version >= 0x10200)
+                               dev->props.rc.core.bulk_mode = true;
+                       else
+                               dev->props.rc.core.bulk_mode = false;
+
+                       dib0700_rc_setup(dev);
+
+                       return 0;
+               }
+
+       return -ENODEV;
+}
+
+static struct usb_driver dib0700_driver = {
+       .name       = "dvb_usb_dib0700",
+       .probe      = dib0700_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table   = dib0700_usb_id_table,
+};
+
+module_usb_driver(dib0700_driver);
+
+MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
new file mode 100644 (file)
index 0000000..510001d
--- /dev/null
@@ -0,0 +1,4813 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     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, version 2.
+ *
+ *  Copyright (C) 2005-9 DiBcom, SA et al
+ */
+#include "dib0700.h"
+
+#include "dib3000mc.h"
+#include "dib7000m.h"
+#include "dib7000p.h"
+#include "dib8000.h"
+#include "dib9000.h"
+#include "mt2060.h"
+#include "mt2266.h"
+#include "tuner-xc2028.h"
+#include "xc5000.h"
+#include "xc4000.h"
+#include "s5h1411.h"
+#include "dib0070.h"
+#include "dib0090.h"
+#include "lgdt3305.h"
+#include "mxl5007t.h"
+
+static int force_lna_activation;
+module_param(force_lna_activation, int, 0644);
+MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
+               "if applicable for the device (default: 0=automatic/off).");
+
+struct dib0700_adapter_state {
+       int (*set_param_save) (struct dvb_frontend *);
+       const struct firmware *frontend_firmware;
+};
+
+/* Hauppauge Nova-T 500 (aka Bristol)
+ *  has a LNA on GPIO0 which is enabled by setting 1 */
+static struct mt2060_config bristol_mt2060_config[2] = {
+       {
+               .i2c_address = 0x60,
+               .clock_out   = 3,
+       }, {
+               .i2c_address = 0x61,
+       }
+};
+
+
+static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
+       .band_caps = BAND_VHF | BAND_UHF,
+       .setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
+
+       .agc1_max = 42598,
+       .agc1_min = 17694,
+       .agc2_max = 45875,
+       .agc2_min = 0,
+
+       .agc1_pt1 = 0,
+       .agc1_pt2 = 59,
+
+       .agc1_slope1 = 0,
+       .agc1_slope2 = 69,
+
+       .agc2_pt1 = 0,
+       .agc2_pt2 = 59,
+
+       .agc2_slope1 = 111,
+       .agc2_slope2 = 28,
+};
+
+static struct dib3000mc_config bristol_dib3000mc_config[2] = {
+       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
+               .max_time     = 0x196,
+               .ln_adc_level = 0x1cc7,
+               .output_mpeg2_in_188_bytes = 1,
+       },
+       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
+               .max_time     = 0x196,
+               .ln_adc_level = 0x1cc7,
+               .output_mpeg2_in_188_bytes = 1,
+       }
+};
+
+static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       if (adap->id == 0) {
+               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
+
+               if (force_lna_activation)
+                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+               else
+                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
+
+               if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
+                       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
+                       return -ENODEV;
+               }
+       }
+       st->mt2060_if1[adap->id] = 1220;
+       return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
+               (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
+}
+
+static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = 0x50, .flags = 0,        .buf = &adrs, .len = 1 },
+               { .addr = 0x50, .flags = I2C_M_RD, .buf = pval,  .len = 1 },
+       };
+       if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
+       return 0;
+}
+
+static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
+       struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
+       s8 a;
+       int if1=1220;
+       if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
+               adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
+               if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
+       }
+       return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c,
+                         &bristol_mt2060_config[adap->id], if1) == NULL ?
+                         -ENODEV : 0;
+}
+
+/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
+
+/* MT226x */
+static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
+       {
+               BAND_UHF,
+
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+           | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+               1130,
+               21,
+
+               0,
+               118,
+
+               0,
+               3530,
+               1,
+               0,
+
+               65535,
+               33770,
+               65535,
+               23592,
+
+               0,
+               62,
+               255,
+               64,
+               64,
+               132,
+               192,
+               80,
+               80,
+
+               17,
+               27,
+               23,
+               51,
+
+               1,
+       }, {
+               BAND_VHF | BAND_LBAND,
+
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+           | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+
+               2372,
+               21,
+
+               0,
+               118,
+
+               0,
+               3530,
+               1,
+               0,
+
+               65535,
+               0,
+               65535,
+               23592,
+
+               0,
+               128,
+               128,
+               128,
+               0,
+               128,
+               253,
+               81,
+               0,
+
+               17,
+               27,
+               23,
+               51,
+
+               1,
+       }
+};
+
+static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
+       60000, 30000,
+       1, 8, 3, 1, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       0,
+       20452225,
+};
+
+static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
+       {       .output_mpeg2_in_188_bytes = 1,
+               .hostbus_diversity = 1,
+               .tuner_is_baseband = 1,
+
+               .agc_config_count = 2,
+               .agc = stk7700d_7000p_mt2266_agc_config,
+               .bw  = &stk7700d_mt2266_pll_config,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+       },
+       {       .output_mpeg2_in_188_bytes = 1,
+               .hostbus_diversity = 1,
+               .tuner_is_baseband = 1,
+
+               .agc_config_count = 2,
+               .agc = stk7700d_7000p_mt2266_agc_config,
+               .bw  = &stk7700d_mt2266_pll_config,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+       }
+};
+
+static struct mt2266_config stk7700d_mt2266_config[2] = {
+       {       .i2c_address = 0x60
+       },
+       {       .i2c_address = 0x60
+       }
+};
+
+static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (adap->id == 0) {
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+               msleep(10);
+               if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                            stk7700d_dib7000p_mt2266_config)
+                   != 0) {
+                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+                       return -ENODEV;
+               }
+       }
+
+       adap->fe_adap[0].fe =
+               dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+                          0x80 + (adap->id << 1),
+                          &stk7700d_dib7000p_mt2266_config[adap->id]);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (adap->id == 0) {
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+               if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+                                            stk7700d_dib7000p_mt2266_config)
+                   != 0) {
+                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+                       return -ENODEV;
+               }
+       }
+
+       adap->fe_adap[0].fe =
+               dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+                          0x80 + (adap->id << 1),
+                          &stk7700d_dib7000p_mt2266_config[adap->id]);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *tun_i2c;
+       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+       return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
+               &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
+}
+
+/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
+static struct dibx000_agc_config xc3028_agc_config = {
+       BAND_VHF | BAND_UHF,       /* band_caps */
+
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
+        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
+       (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
+
+       712,    /* inv_gain */
+       21,     /* time_stabiliz */
+
+       0,      /* alpha_level */
+       118,    /* thlock */
+
+       0,      /* wbd_inv */
+       2867,   /* wbd_ref */
+       0,      /* wbd_sel */
+       2,      /* wbd_alpha */
+
+       0,      /* agc1_max */
+       0,      /* agc1_min */
+       39718,  /* agc2_max */
+       9930,   /* agc2_min */
+       0,      /* agc1_pt1 */
+       0,      /* agc1_pt2 */
+       0,      /* agc1_pt3 */
+       0,      /* agc1_slope1 */
+       0,      /* agc1_slope2 */
+       0,      /* agc2_pt1 */
+       128,    /* agc2_pt2 */
+       29,     /* agc2_slope1 */
+       29,     /* agc2_slope2 */
+
+       17,     /* alpha_mant */
+       27,     /* alpha_exp */
+       23,     /* beta_mant */
+       51,     /* beta_exp */
+
+       1,      /* perform_agc_softsplit */
+};
+
+/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
+static struct dibx000_bandwidth_config xc3028_bw_config = {
+       60000, 30000, /* internal, sampling */
+       1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
+       0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
+                         modulo */
+       (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
+       (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
+       20452225, /* timf */
+       30000000, /* xtal_hz */
+};
+
+static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
+       .output_mpeg2_in_188_bytes = 1,
+       .tuner_is_baseband = 1,
+
+       .agc_config_count = 1,
+       .agc = &xc3028_agc_config,
+       .bw  = &xc3028_bw_config,
+
+       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+};
+
+static int stk7700ph_xc3028_callback(void *ptr, int component,
+                                    int command, int arg)
+{
+       struct dvb_usb_adapter *adap = ptr;
+
+       switch (command) {
+       case XC2028_TUNER_RESET:
+               /* Send the tuner in then out of reset */
+               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
+               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+               break;
+       case XC2028_RESET_CLK:
+               break;
+       default:
+               err("%s: unknown command %d, arg %d\n", __func__,
+                       command, arg);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
+       .fname = XC2028_DEFAULT_FIRMWARE,
+       .max_len = 64,
+       .demod = XC3028_FE_DIBCOM52,
+};
+
+static struct xc2028_config stk7700ph_xc3028_config = {
+       .i2c_addr = 0x61,
+       .ctrl = &stk7700ph_xc3028_ctrl,
+};
+
+static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
+
+       if (desc->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
+           desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       else
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+       msleep(10);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                    &stk7700ph_dib7700_xc3028_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                   __func__);
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+               &stk7700ph_dib7700_xc3028_config);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *tun_i2c;
+
+       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+               DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       stk7700ph_xc3028_config.i2c_adap = tun_i2c;
+
+       /* FIXME: generalize & move to common area */
+       adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;
+
+       return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
+               == NULL ? -ENODEV : 0;
+}
+
+#define DEFAULT_RC_INTERVAL 50
+
+static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
+
+/* Number of keypresses to ignore before start repeating */
+#define RC_REPEAT_DELAY 6
+
+/*
+ * This function is used only when firmware is < 1.20 version. Newer
+ * firmwares use bulk mode, with functions implemented at dib0700_core,
+ * at dib0700_rc_urb_completion()
+ */
+static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
+{
+       u8 key[4];
+       u32 keycode;
+       u8 toggle;
+       int i;
+       struct dib0700_state *st = d->priv;
+
+       if (st->fw_version >= 0x10200) {
+               /* For 1.20 firmware , We need to keep the RC polling
+                  callback so we can reuse the input device setup in
+                  dvb-usb-remote.c.  However, the actual work is being done
+                  in the bulk URB completion handler. */
+               return 0;
+       }
+
+       i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
+       if (i <= 0) {
+               err("RC Query Failed");
+               return -1;
+       }
+
+       /* losing half of KEY_0 events from Philipps rc5 remotes.. */
+       if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
+               return 0;
+
+       /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */
+
+       dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
+
+       d->last_event = 0;
+       switch (d->props.rc.core.protocol) {
+       case RC_TYPE_NEC:
+               /* NEC protocol sends repeat code as 0 0 0 FF */
+               if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
+                   (key[3] == 0xff))
+                       keycode = d->last_event;
+               else {
+                       keycode = key[3-2] << 8 | key[3-3];
+                       d->last_event = keycode;
+               }
+
+               rc_keydown(d->rc_dev, keycode, 0);
+               break;
+       default:
+               /* RC-5 protocol changes toggle bit on new keypress */
+               keycode = key[3-2] << 8 | key[3-3];
+               toggle = key[3-1];
+               rc_keydown(d->rc_dev, keycode, toggle);
+
+               break;
+       }
+       return 0;
+}
+
+/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
+static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
+       BAND_UHF | BAND_VHF,
+
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+
+       712,
+       41,
+
+       0,
+       118,
+
+       0,
+       4095,
+       0,
+       0,
+
+       42598,
+       17694,
+       45875,
+       2621,
+       0,
+       76,
+       139,
+       52,
+       59,
+       107,
+       172,
+       57,
+       70,
+
+       21,
+       25,
+       28,
+       48,
+
+       1,
+       {  0,
+          107,
+          51800,
+          24700
+       },
+};
+
+static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
+       BAND_UHF | BAND_VHF,
+
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
+
+       712,
+       41,
+
+       0,
+       118,
+
+       0,
+       4095,
+       0,
+       0,
+
+       42598,
+       16384,
+       42598,
+           0,
+
+         0,
+       137,
+       255,
+
+         0,
+       255,
+
+       0,
+       0,
+
+        0,
+       41,
+
+       15,
+       25,
+
+       28,
+       48,
+
+       0,
+};
+
+static struct dibx000_bandwidth_config stk7700p_pll_config = {
+       60000, 30000,
+       1, 8, 3, 1, 0,
+       0, 0, 1, 1, 0,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       60258167,
+       20452225,
+       30000000,
+};
+
+static struct dib7000m_config stk7700p_dib7000m_config = {
+       .dvbt_mode = 1,
+       .output_mpeg2_in_188_bytes = 1,
+       .quartz_direct = 1,
+
+       .agc_config_count = 1,
+       .agc = &stk7700p_7000m_mt2060_agc_config,
+       .bw  = &stk7700p_pll_config,
+
+       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
+};
+
+static struct dib7000p_config stk7700p_dib7000p_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &stk7700p_7000p_mt2060_agc_config,
+       .bw  = &stk7700p_pll_config,
+
+       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
+};
+
+static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       /* unless there is no real power management in DVB - we leave the device on GPIO6 */
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);
+
+       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
+
+       dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);
+
+       st->mt2060_if1[0] = 1220;
+
+       if (dib7000pc_detection(&adap->dev->i2c_adap)) {
+               adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
+               st->is_dib7000pc = 1;
+       } else
+               adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static struct mt2060_config stk7700p_mt2060_config = {
+       0x60
+};
+
+static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
+       struct dib0700_state *st = adap->dev->priv;
+       struct i2c_adapter *tun_i2c;
+       s8 a;
+       int if1=1220;
+       if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
+               adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
+               if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
+       }
+       if (st->is_dib7000pc)
+               tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+       else
+               tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
+               if1) == NULL ? -ENODEV : 0;
+}
+
+/* DIB7070 generic */
+static struct dibx000_agc_config dib7070_agc_config = {
+       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       600,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       65535,
+               0,
+
+       65535,
+       0,
+
+       0,
+       40,
+       183,
+       206,
+       255,
+       72,
+       152,
+       88,
+       90,
+
+       17,
+       27,
+       23,
+       51,
+
+       0,
+};
+
+static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("reset: %d", onoff);
+       return dib7000p_set_gpio(fe, 8, 0, !onoff);
+}
+
+static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("sleep: %d", onoff);
+       return dib7000p_set_gpio(fe, 9, 0, onoff);
+}
+
+static struct dib0070_config dib7070p_dib0070_config[2] = {
+       {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib7070_tuner_reset,
+               .sleep = dib7070_tuner_sleep,
+               .clock_khz = 12000,
+               .clock_pad_drive = 4,
+               .charge_pump = 2,
+       }, {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib7070_tuner_reset,
+               .sleep = dib7070_tuner_sleep,
+               .clock_khz = 12000,
+               .charge_pump = 2,
+       }
+};
+
+static struct dib0070_config dib7770p_dib0070_config = {
+        .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+        .reset = dib7070_tuner_reset,
+        .sleep = dib7070_tuner_sleep,
+        .clock_khz = 12000,
+        .clock_pad_drive = 0,
+        .flip_chip = 1,
+        .charge_pump = 2,
+};
+
+static int dib7070_set_param_override(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+
+       u16 offset;
+       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
+       switch (band) {
+               case BAND_VHF: offset = 950; break;
+               case BAND_UHF:
+               default: offset = 550; break;
+       }
+       deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+       dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+       return state->set_param_save(fe);
+}
+
+static int dib7770_set_param_override(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+
+        u16 offset;
+        u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
+        switch (band) {
+        case BAND_VHF:
+                 dib7000p_set_gpio(fe, 0, 0, 1);
+                 offset = 850;
+                 break;
+        case BAND_UHF:
+        default:
+                 dib7000p_set_gpio(fe, 0, 0, 0);
+                 offset = 250;
+                 break;
+        }
+        deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+        dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+        return state->set_param_save(fe);
+}
+
+static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+        struct dib0700_adapter_state *st = adap->priv;
+        struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+                        DIBX000_I2C_INTERFACE_TUNER, 1);
+
+        if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
+                       &dib7770p_dib0070_config) == NULL)
+                return -ENODEV;
+
+        st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+        adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
+        return 0;
+}
+
+static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       if (adap->id == 0) {
+               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
+                       return -ENODEV;
+       } else {
+               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
+                       return -ENODEV;
+       }
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
+       return 0;
+}
+
+static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
+               u16 pid, int onoff)
+{
+       struct dib0700_state *st = adapter->dev->priv;
+       if (st->is_dib7000pc)
+               return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+       return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+}
+
+static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+       struct dib0700_state *st = adapter->dev->priv;
+       if (st->is_dib7000pc)
+               return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+       return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+}
+
+static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+{
+       return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+}
+
+static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+       return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+}
+
+static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
+       60000, 15000,
+       1, 20, 3, 1, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       (0 << 25) | 0,
+       20452225,
+       12000000,
+};
+
+static struct dib7000p_config dib7070p_dib7000p_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &dib7070_agc_config,
+       .bw  = &dib7070_bw_config_12_mhz,
+       .tuner_is_baseband = 1,
+       .spur_protect = 1,
+
+       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+};
+
+/* STK7070P */
+static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+       if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
+           p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       else
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                    &dib7070p_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                   __func__);
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+               &dib7070p_dib7000p_config);
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+/* STK7770P */
+static struct dib7000p_config dib7770p_dib7000p_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &dib7070_agc_config,
+       .bw  = &dib7070_bw_config_12_mhz,
+       .tuner_is_baseband = 1,
+       .spur_protect = 1,
+
+       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+       .enable_current_mirror = 1,
+       .disable_sample_and_hold = 0,
+};
+
+static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+       if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
+           p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       else
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                                    &dib7770p_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                   __func__);
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+               &dib7770p_dib7000p_config);
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+/* DIB807x generic */
+static struct dibx000_agc_config dib807x_agc_config[2] = {
+       {
+               BAND_VHF,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+                * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+                * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
+                * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+                * P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
+                       (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+                       (0 << 0), /* setup*/
+
+               600, /* inv_gain*/
+               10,  /* time_stabiliz*/
+
+               0,  /* alpha_level*/
+               118,  /* thlock*/
+
+               0,     /* wbd_inv*/
+               3530,  /* wbd_ref*/
+               1,     /* wbd_sel*/
+               5,     /* wbd_alpha*/
+
+               65535,  /* agc1_max*/
+               0,  /* agc1_min*/
+
+               65535,  /* agc2_max*/
+               0,      /* agc2_min*/
+
+               0,      /* agc1_pt1*/
+               40,     /* agc1_pt2*/
+               183,    /* agc1_pt3*/
+               206,    /* agc1_slope1*/
+               255,    /* agc1_slope2*/
+               72,     /* agc2_pt1*/
+               152,    /* agc2_pt2*/
+               88,     /* agc2_slope1*/
+               90,     /* agc2_slope2*/
+
+               17,  /* alpha_mant*/
+               27,  /* alpha_exp*/
+               23,  /* beta_mant*/
+               51,  /* beta_exp*/
+
+               0,  /* perform_agc_softsplit*/
+       }, {
+               BAND_UHF,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+                * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+                * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+                * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+                * P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
+                       (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+                       (0 << 0), /* setup */
+
+               600, /* inv_gain*/
+               10,  /* time_stabiliz*/
+
+               0,  /* alpha_level*/
+               118,  /* thlock*/
+
+               0,     /* wbd_inv*/
+               3530,  /* wbd_ref*/
+               1,     /* wbd_sel*/
+               5,     /* wbd_alpha*/
+
+               65535,  /* agc1_max*/
+               0,  /* agc1_min*/
+
+               65535,  /* agc2_max*/
+               0,      /* agc2_min*/
+
+               0,      /* agc1_pt1*/
+               40,     /* agc1_pt2*/
+               183,    /* agc1_pt3*/
+               206,    /* agc1_slope1*/
+               255,    /* agc1_slope2*/
+               72,     /* agc2_pt1*/
+               152,    /* agc2_pt2*/
+               88,     /* agc2_slope1*/
+               90,     /* agc2_slope2*/
+
+               17,  /* alpha_mant*/
+               27,  /* alpha_exp*/
+               23,  /* beta_mant*/
+               51,  /* beta_exp*/
+
+               0,  /* perform_agc_softsplit*/
+       }
+};
+
+static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
+       60000, 15000, /* internal, sampling*/
+       1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
+       0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
+                         ADClkSrc, modulo */
+       (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
+       (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
+       18179755, /* timf*/
+       12000000, /* xtal_hz*/
+};
+
+static struct dib8000_config dib807x_dib8000_config[2] = {
+       {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 2,
+               .agc = dib807x_agc_config,
+               .pll = &dib807x_bw_config_12_mhz,
+               .tuner_is_baseband = 1,
+
+               .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+               .div_cfg = 1,
+               .agc_control = &dib0070_ctrl_agc_filter,
+               .output_mode = OUTMODE_MPEG2_FIFO,
+               .drives = 0x2d98,
+       }, {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 2,
+               .agc = dib807x_agc_config,
+               .pll = &dib807x_bw_config_12_mhz,
+               .tuner_is_baseband = 1,
+
+               .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+               .agc_control = &dib0070_ctrl_agc_filter,
+               .output_mode = OUTMODE_MPEG2_FIFO,
+               .drives = 0x2d98,
+       }
+};
+
+static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+       return dib8000_set_gpio(fe, 5, 0, !onoff);
+}
+
+static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       return dib8000_set_gpio(fe, 0, 0, onoff);
+}
+
+static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
+    { 240,      7},
+    { 0xffff,   6},
+};
+
+static struct dib0070_config dib807x_dib0070_config[2] = {
+       {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib80xx_tuner_reset,
+               .sleep = dib80xx_tuner_sleep,
+               .clock_khz = 12000,
+               .clock_pad_drive = 4,
+               .vga_filter = 1,
+               .force_crystal_mode = 1,
+               .enable_third_order_filter = 1,
+               .charge_pump = 0,
+               .wbd_gain = dib8070_wbd_gain_cfg,
+               .osc_buffer_state = 0,
+               .freq_offset_khz_uhf = -100,
+               .freq_offset_khz_vhf = -100,
+       }, {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib80xx_tuner_reset,
+               .sleep = dib80xx_tuner_sleep,
+               .clock_khz = 12000,
+               .clock_pad_drive = 2,
+               .vga_filter = 1,
+               .force_crystal_mode = 1,
+               .enable_third_order_filter = 1,
+               .charge_pump = 0,
+               .wbd_gain = dib8070_wbd_gain_cfg,
+               .osc_buffer_state = 0,
+               .freq_offset_khz_uhf = -25,
+               .freq_offset_khz_vhf = -25,
+       }
+};
+
+static int dib807x_set_param_override(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+
+       u16 offset = dib0070_wbd_offset(fe);
+       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
+       switch (band) {
+       case BAND_VHF:
+               offset += 750;
+               break;
+       case BAND_UHF:  /* fall-thru wanted */
+       default:
+               offset += 250; break;
+       }
+       deb_info("WBD for DiB8000: %d\n", offset);
+       dib8000_set_wbd_ref(fe, offset);
+
+       return state->set_param_save(fe);
+}
+
+static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
+                       DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       if (adap->id == 0) {
+               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
+                               &dib807x_dib0070_config[0]) == NULL)
+                       return -ENODEV;
+       } else {
+               if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
+                               &dib807x_dib0070_config[1]) == NULL)
+                       return -ENODEV;
+       }
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override;
+       return 0;
+}
+
+static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
+       u16 pid, int onoff)
+{
+       return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+}
+
+static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
+               int onoff)
+{
+       return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+}
+
+/* STK807x */
+static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+                               0x80, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+                             &dib807x_dib8000_config[0]);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+/* STK807xPVR */
+static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       msleep(30);
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(500);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       /* initialize IC 0 */
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+                             &dib807x_dib8000_config[0]);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
+{
+       /* initialize IC 1 */
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
+                             &dib807x_dib8000_config[1]);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+/* STK8096GP */
+static struct dibx000_agc_config dib8090_agc_config[2] = {
+       {
+       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       787,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       65535,
+       0,
+
+       65535,
+       0,
+
+       0,
+       32,
+       114,
+       143,
+       144,
+       114,
+       227,
+       116,
+       117,
+
+       28,
+       26,
+       31,
+       51,
+
+       0,
+       },
+       {
+       BAND_CBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+        * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+        * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+       | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+       787,
+       10,
+
+       0,
+       118,
+
+       0,
+       3530,
+       1,
+       5,
+
+       0,
+       0,
+
+       65535,
+       0,
+
+       0,
+       32,
+       114,
+       143,
+       144,
+       114,
+       227,
+       116,
+       117,
+
+       28,
+       26,
+       31,
+       51,
+
+       0,
+       }
+};
+
+static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
+       54000, 13500,
+       1, 18, 3, 1, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (599 << 0),
+       (0 << 25) | 0,
+       20199727,
+       12000000,
+};
+
+static int dib8090_get_adc_power(struct dvb_frontend *fe)
+{
+       return dib8000_get_adc_power(fe, 1);
+}
+
+static struct dib8000_config dib809x_dib8000_config[2] = {
+       {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 2,
+       .agc = dib8090_agc_config,
+       .agc_control = dib0090_dcc_freq,
+       .pll = &dib8090_pll_config_12mhz,
+       .tuner_is_baseband = 1,
+
+       .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+       .div_cfg = 0x31,
+       .output_mode = OUTMODE_MPEG2_FIFO,
+       .drives = 0x2d98,
+       .diversity_delay = 48,
+       .refclksel = 3,
+       }, {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 2,
+       .agc = dib8090_agc_config,
+       .agc_control = dib0090_dcc_freq,
+       .pll = &dib8090_pll_config_12mhz,
+       .tuner_is_baseband = 1,
+
+       .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+       .div_cfg = 0x31,
+       .output_mode = OUTMODE_DIVERSITY,
+       .drives = 0x2d08,
+       .diversity_delay = 1,
+       .refclksel = 3,
+       }
+};
+
+static struct dib0090_wbd_slope dib8090_wbd_table[] = {
+       /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
+       { 120,     0, 500,  0,   500, 4 }, /* CBAND */
+       { 170,     0, 450,  0,   450, 4 }, /* CBAND */
+       { 380,    48, 373, 28,   259, 6 }, /* VHF */
+       { 860,    34, 700, 36,   616, 6 }, /* high UHF */
+       { 0xFFFF, 34, 700, 36,   616, 6 }, /* default */
+};
+
+static struct dib0090_config dib809x_dib0090_config = {
+       .io.pll_bypass = 1,
+       .io.pll_range = 1,
+       .io.pll_prediv = 1,
+       .io.pll_loopdiv = 20,
+       .io.adc_clock_ratio = 8,
+       .io.pll_int_loop_filt = 0,
+       .io.clock_khz = 12000,
+       .reset = dib80xx_tuner_reset,
+       .sleep = dib80xx_tuner_sleep,
+       .clkouttobamse = 1,
+       .analog_output = 1,
+       .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
+       .use_pwm_agc = 1,
+       .clkoutdrive = 1,
+       .get_adc_power = dib8090_get_adc_power,
+       .freq_offset_khz_uhf = -63,
+       .freq_offset_khz_vhf = -143,
+       .wbd = dib8090_wbd_table,
+       .fref_clock_ratio = 6,
+};
+
+static int dib8096_set_param_override(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+       u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
+       u16 target;
+       int ret = 0;
+       enum frontend_tune_state tune_state = CT_SHUTDOWN;
+       u16 ltgain, rf_gain_limit;
+
+       ret = state->set_param_save(fe);
+       if (ret < 0)
+               return ret;
+
+       target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
+       dib8000_set_wbd_ref(fe, target);
+
+
+       if (band == BAND_CBAND) {
+               deb_info("tuning in CBAND - soft-AGC startup\n");
+               dib0090_set_tune_state(fe, CT_AGC_START);
+               do {
+                       ret = dib0090_gain_control(fe);
+                       msleep(ret);
+                       tune_state = dib0090_get_tune_state(fe);
+                       if (tune_state == CT_AGC_STEP_0)
+                               dib8000_set_gpio(fe, 6, 0, 1);
+                       else if (tune_state == CT_AGC_STEP_1) {
+                               dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
+                               if (rf_gain_limit == 0)
+                                       dib8000_set_gpio(fe, 6, 0, 0);
+                       }
+               } while (tune_state < CT_AGC_STOP);
+               dib0090_pwm_gain_reset(fe);
+               dib8000_pwm_agc_reset(fe);
+               dib8000_set_tune_state(fe, CT_DEMOD_START);
+       } else {
+               deb_info("not tuning in CBAND - standard AGC startup\n");
+               dib0090_pwm_gain_reset(fe);
+       }
+
+       return 0;
+}
+
+static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+               return -ENODEV;
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
+       return 0;
+}
+
+static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c;
+       struct dvb_frontend *fe_slave  = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);
+
+       if (fe_slave) {
+               tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
+               if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
+                       return -ENODEV;
+               fe_slave->dvb = adap->fe_adap[0].fe->dvb;
+               fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
+       }
+       tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+               return -ENODEV;
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
+
+       return 0;
+}
+
+static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_frontend *fe_slave;
+
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(1000);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
+       if (adap->fe_adap[0].fe == NULL)
+               return -ENODEV;
+
+       fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
+       dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
+
+       return fe_slave == NULL ?  -ENODEV : 0;
+}
+
+/* TFE8096P */
+static struct dibx000_agc_config dib8096p_agc_config[2] = {
+       {
+               .band_caps              = BAND_UHF,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+                  P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+                  P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+                  P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+                  P_agc_write=0 */
+               .setup                  = (0 << 15) | (0 << 14) | (5 << 11)
+                       | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
+                       | (0 << 4) | (5 << 1) | (0 << 0),
+
+               .inv_gain               = 684,
+               .time_stabiliz  = 10,
+
+               .alpha_level    = 0,
+               .thlock                 = 118,
+
+               .wbd_inv                = 0,
+               .wbd_ref                = 1200,
+               .wbd_sel                = 3,
+               .wbd_alpha              = 5,
+
+               .agc1_max               = 65535,
+               .agc1_min               = 0,
+
+               .agc2_max               = 32767,
+               .agc2_min               = 0,
+
+               .agc1_pt1               = 0,
+               .agc1_pt2               = 0,
+               .agc1_pt3               = 105,
+               .agc1_slope1    = 0,
+               .agc1_slope2    = 156,
+               .agc2_pt1               = 105,
+               .agc2_pt2               = 255,
+               .agc2_slope1    = 54,
+               .agc2_slope2    = 0,
+
+               .alpha_mant             = 28,
+               .alpha_exp              = 26,
+               .beta_mant              = 31,
+               .beta_exp               = 51,
+
+               .perform_agc_softsplit = 0,
+       } , {
+               .band_caps              = BAND_FM | BAND_VHF | BAND_CBAND,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+                  P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+                  P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+                  P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+                  P_agc_write=0 */
+               .setup                  = (0 << 15) | (0 << 14) | (5 << 11)
+                       | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
+                       | (0 << 4) | (5 << 1) | (0 << 0),
+
+               .inv_gain               = 732,
+               .time_stabiliz  = 10,
+
+               .alpha_level    = 0,
+               .thlock                 = 118,
+
+               .wbd_inv                = 0,
+               .wbd_ref                = 1200,
+               .wbd_sel                = 3,
+               .wbd_alpha              = 5,
+
+               .agc1_max               = 65535,
+               .agc1_min               = 0,
+
+               .agc2_max               = 32767,
+               .agc2_min               = 0,
+
+               .agc1_pt1               = 0,
+               .agc1_pt2               = 0,
+               .agc1_pt3               = 98,
+               .agc1_slope1    = 0,
+               .agc1_slope2    = 167,
+               .agc2_pt1               = 98,
+               .agc2_pt2               = 255,
+               .agc2_slope1    = 52,
+               .agc2_slope2    = 0,
+
+               .alpha_mant             = 28,
+               .alpha_exp              = 26,
+               .beta_mant              = 31,
+               .beta_exp               = 51,
+
+               .perform_agc_softsplit = 0,
+       }
+};
+
+static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
+       108000, 13500,
+       1, 9, 1, 0, 0,
+       0, 0, 0, 0, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       (0 << 25) | 0,
+       20199729,
+       12000000,
+};
+
+static struct dib8000_config tfe8096p_dib8000_config = {
+       .output_mpeg2_in_188_bytes      = 1,
+       .hostbus_diversity                      = 1,
+       .update_lna                                     = NULL,
+
+       .agc_config_count                       = 2,
+       .agc                                            = dib8096p_agc_config,
+       .pll                                            = &dib8096p_clock_config_12_mhz,
+
+       .gpio_dir                                       = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val                                       = DIB8000_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos                           = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+       .agc_control                            = NULL,
+       .diversity_delay                        = 48,
+       .output_mode                            = OUTMODE_MPEG2_FIFO,
+       .enMpegOutput                           = 1,
+};
+
+static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
+       { 380, 81, 850, 64, 540, 4},
+       { 860, 51, 866, 21, 375, 4},
+       {1700, 0, 250, 0, 100, 6},
+       {2600, 0, 250, 0, 100, 6},
+       { 0xFFFF, 0, 0, 0, 0, 0},
+};
+
+static const struct dib0090_config tfe8096p_dib0090_config = {
+       .io.clock_khz                   = 12000,
+       .io.pll_bypass                  = 0,
+       .io.pll_range                   = 0,
+       .io.pll_prediv                  = 3,
+       .io.pll_loopdiv                 = 6,
+       .io.adc_clock_ratio             = 0,
+       .io.pll_int_loop_filt   = 0,
+       .reset                                  = dib8096p_tuner_sleep,
+       .sleep                                  = dib8096p_tuner_sleep,
+
+       .freq_offset_khz_uhf    = -143,
+       .freq_offset_khz_vhf    = -143,
+
+       .get_adc_power                  = dib8090_get_adc_power,
+
+       .clkouttobamse                  = 1,
+       .analog_output                  = 0,
+
+       .wbd_vhf_offset                 = 0,
+       .wbd_cband_offset               = 0,
+       .use_pwm_agc                    = 1,
+       .clkoutdrive                    = 0,
+
+       .fref_clock_ratio               = 1,
+
+       .wbd                                    = dib8096p_wbd_table,
+
+       .ls_cfg_pad_drv                 = 0,
+       .data_tx_drv                    = 0,
+       .low_if                                 = NULL,
+       .in_soc                                 = 1,
+       .force_cband_input              = 0,
+};
+
+struct dibx090p_adc {
+       u32 freq;                       /* RF freq MHz */
+       u32 timf;                       /* New Timf */
+       u32 pll_loopdiv;        /* New prediv */
+       u32 pll_prediv;         /* New loopdiv */
+};
+
+struct dibx090p_adc dib8090p_adc_tab[] = {
+       { 50000, 17043521, 16, 3}, /* 64 MHz */
+       {878000, 20199729, 9, 1}, /* 60 MHz */
+       {0xffffffff, 0, 0, 0}, /* 60 MHz */
+};
+
+static int dib8096p_agc_startup(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+       struct dibx000_bandwidth_config pll;
+       u16 target;
+       int better_sampling_freq = 0, ret;
+       struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
+
+       ret = state->set_param_save(fe);
+       if (ret < 0)
+               return ret;
+       memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
+
+       dib0090_pwm_gain_reset(fe);
+       /* dib0090_get_wbd_target is returning any possible
+          temperature compensated wbd-target */
+       target = (dib0090_get_wbd_target(fe) * 8  + 1) / 2;
+       dib8000_set_wbd_ref(fe, target);
+
+
+       while (p->frequency / 1000 > adc_table->freq) {
+               better_sampling_freq = 1;
+               adc_table++;
+       }
+
+       if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
+               pll.pll_ratio  = adc_table->pll_loopdiv;
+               pll.pll_prediv = adc_table->pll_prediv;
+               dib8000_update_pll(fe, &pll);
+               dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf);
+       }
+       return 0;
+}
+
+static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
+
+       adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
+                       &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+                               &tfe8096p_dib0090_config) == NULL)
+               return -ENODEV;
+
+       dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
+       return 0;
+}
+
+/* STK9090M */
+static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+{
+       return dib9000_fw_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+}
+
+static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+       return dib9000_fw_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+}
+
+static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+       return dib9000_set_gpio(fe, 5, 0, !onoff);
+}
+
+static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       return dib9000_set_gpio(fe, 0, 0, onoff);
+}
+
+static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
+{
+       u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
+       u8 rb[2];
+       struct i2c_msg msg[2] = {
+               {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
+               {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
+       };
+       u8 index_data;
+
+       dibx000_i2c_set_speed(i2c, 250);
+
+       if (i2c_transfer(i2c, msg, 2) != 2)
+               return -EIO;
+
+       switch (rb[0] << 8 | rb[1]) {
+       case 0:
+                       deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
+                       return -EIO;
+       case 1:
+                       deb_info("Found DiB0170 rev2");
+                       break;
+       case 2:
+                       deb_info("Found DiB0190 rev2");
+                       break;
+       default:
+                       deb_info("DiB01x0 not found");
+                       return -EIO;
+       }
+
+       for (index_data = 0; index_data < len; index_data += 2) {
+               wb[2] = (data[index_data + 1] >> 8) & 0xff;
+               wb[3] = (data[index_data + 1]) & 0xff;
+
+               if (data[index_data] == 0) {
+                       wb[0] = (data[index_data] >> 8) & 0xff;
+                       wb[1] = (data[index_data]) & 0xff;
+                       msg[0].len = 2;
+                       if (i2c_transfer(i2c, msg, 2) != 2)
+                               return -EIO;
+                       wb[2] |= rb[0];
+                       wb[3] |= rb[1] & ~(3 << 4);
+               }
+
+               wb[0] = (data[index_data] >> 8)&0xff;
+               wb[1] = (data[index_data])&0xff;
+               msg[0].len = 4;
+               if (i2c_transfer(i2c, &msg[0], 1) != 1)
+                       return -EIO;
+       }
+       return 0;
+}
+
+static struct dib9000_config stk9090m_config = {
+       .output_mpeg2_in_188_bytes = 1,
+       .output_mode = OUTMODE_MPEG2_FIFO,
+       .vcxo_timer = 279620,
+       .timing_frequency = 20452225,
+       .demod_clock_khz = 60000,
+       .xtal_clock_khz = 30000,
+       .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
+       .subband = {
+               2,
+               {
+                       { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
+                       { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
+                       { 0 },
+               },
+       },
+       .gpio_function = {
+               { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
+               { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
+       },
+};
+
+static struct dib9000_config nim9090md_config[2] = {
+       {
+               .output_mpeg2_in_188_bytes = 1,
+               .output_mode = OUTMODE_MPEG2_FIFO,
+               .vcxo_timer = 279620,
+               .timing_frequency = 20452225,
+               .demod_clock_khz = 60000,
+               .xtal_clock_khz = 30000,
+               .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
+       }, {
+               .output_mpeg2_in_188_bytes = 1,
+               .output_mode = OUTMODE_DIVERSITY,
+               .vcxo_timer = 279620,
+               .timing_frequency = 20452225,
+               .demod_clock_khz = 60000,
+               .xtal_clock_khz = 30000,
+               .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
+               .subband = {
+                       2,
+                       {
+                               { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
+                               { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
+                               { 0 },
+                       },
+               },
+               .gpio_function = {
+                       { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
+                       { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
+               },
+       }
+};
+
+static struct dib0090_config dib9090_dib0090_config = {
+       .io.pll_bypass = 0,
+       .io.pll_range = 1,
+       .io.pll_prediv = 1,
+       .io.pll_loopdiv = 8,
+       .io.adc_clock_ratio = 8,
+       .io.pll_int_loop_filt = 0,
+       .io.clock_khz = 30000,
+       .reset = dib90x0_tuner_reset,
+       .sleep = dib90x0_tuner_sleep,
+       .clkouttobamse = 0,
+       .analog_output = 0,
+       .use_pwm_agc = 0,
+       .clkoutdrive = 0,
+       .freq_offset_khz_uhf = 0,
+       .freq_offset_khz_vhf = 0,
+};
+
+static struct dib0090_config nim9090md_dib0090_config[2] = {
+       {
+               .io.pll_bypass = 0,
+               .io.pll_range = 1,
+               .io.pll_prediv = 1,
+               .io.pll_loopdiv = 8,
+               .io.adc_clock_ratio = 8,
+               .io.pll_int_loop_filt = 0,
+               .io.clock_khz = 30000,
+               .reset = dib90x0_tuner_reset,
+               .sleep = dib90x0_tuner_sleep,
+               .clkouttobamse = 1,
+               .analog_output = 0,
+               .use_pwm_agc = 0,
+               .clkoutdrive = 0,
+               .freq_offset_khz_uhf = 0,
+               .freq_offset_khz_vhf = 0,
+       }, {
+               .io.pll_bypass = 0,
+               .io.pll_range = 1,
+               .io.pll_prediv = 1,
+               .io.pll_loopdiv = 8,
+               .io.adc_clock_ratio = 8,
+               .io.pll_int_loop_filt = 0,
+               .io.clock_khz = 30000,
+               .reset = dib90x0_tuner_reset,
+               .sleep = dib90x0_tuner_sleep,
+               .clkouttobamse = 0,
+               .analog_output = 0,
+               .use_pwm_agc = 0,
+               .clkoutdrive = 0,
+               .freq_offset_khz_uhf = 0,
+               .freq_offset_khz_vhf = 0,
+       }
+};
+
+
+static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *state = adap->priv;
+       struct dib0700_state *st = adap->dev->priv;
+       u32 fw_version;
+
+       /* Make use of the new i2c functions from FW 1.20 */
+       dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
+       if (fw_version >= 0x10200)
+               st->fw_use_new_i2c_api = 1;
+       dib0700_set_i2c_speed(adap->dev, 340);
+
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
+
+       if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
+               deb_info("%s: Upload failed. (file not found?)\n", __func__);
+               return -ENODEV;
+       } else {
+               deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
+       }
+       stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
+       stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
+
+       adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *state = adap->priv;
+       struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
+       u16 data_dib190[10] = {
+               1, 0x1374,
+               2, 0x01a2,
+               7, 0x0020,
+               0, 0x00ef,
+               8, 0x0486,
+       };
+
+       if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
+               return -ENODEV;
+       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
+       if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
+               return -ENODEV;
+       dib0700_set_i2c_speed(adap->dev, 1500);
+       if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
+               return -ENODEV;
+       release_firmware(state->frontend_firmware);
+       return 0;
+}
+
+static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *state = adap->priv;
+       struct dib0700_state *st = adap->dev->priv;
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe_slave;
+       u32 fw_version;
+
+       /* Make use of the new i2c functions from FW 1.20 */
+       dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
+       if (fw_version >= 0x10200)
+               st->fw_use_new_i2c_api = 1;
+       dib0700_set_i2c_speed(adap->dev, 340);
+
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
+               deb_info("%s: Upload failed. (file not found?)\n", __func__);
+               return -EIO;
+       } else {
+               deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
+       }
+       nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
+       nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
+       nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
+       nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
+
+       dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
+       adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
+
+       if (adap->fe_adap[0].fe == NULL)
+               return -ENODEV;
+
+       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
+       dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
+
+       fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
+       dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
+
+       return fe_slave == NULL ?  -ENODEV : 0;
+}
+
+static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *state = adap->priv;
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe_slave;
+       u16 data_dib190[10] = {
+               1, 0x5374,
+               2, 0x01ae,
+               7, 0x0020,
+               0, 0x00ef,
+               8, 0x0406,
+       };
+       i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
+       if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
+               return -ENODEV;
+       i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
+       if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
+               return -ENODEV;
+
+       dib0700_set_i2c_speed(adap->dev, 1500);
+       if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
+               return -ENODEV;
+
+       fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1);
+       if (fe_slave != NULL) {
+               i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].fe);
+               dib9000_set_i2c_adapter(fe_slave, i2c);
+
+               i2c = dib9000_get_tuner_interface(fe_slave);
+               if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
+                       return -ENODEV;
+               fe_slave->dvb = adap->fe_adap[0].fe->dvb;
+               dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
+               if (dib9000_firmware_post_pll_init(fe_slave) < 0)
+                       return -ENODEV;
+       }
+       release_firmware(state->frontend_firmware);
+
+       return 0;
+}
+
+/* NIM7090 */
+struct dib7090p_best_adc {
+       u32 timf;
+       u32 pll_loopdiv;
+       u32 pll_prediv;
+};
+
+static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
+{
+       u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
+
+       u16 xtal = 12000;
+       u32 fcp_min = 1900;  /* PLL Minimum Frequency comparator KHz */
+       u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
+       u32 fdem_max = 76000;
+       u32 fdem_min = 69500;
+       u32 fcp = 0, fs = 0, fdem = 0;
+       u32 harmonic_id = 0;
+
+       adc->pll_loopdiv = loopdiv;
+       adc->pll_prediv = prediv;
+       adc->timf = 0;
+
+       deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
+
+       /* Find Min and Max prediv */
+       while ((xtal/max_prediv) >= fcp_min)
+               max_prediv++;
+
+       max_prediv--;
+       min_prediv = max_prediv;
+       while ((xtal/min_prediv) <= fcp_max) {
+               min_prediv--;
+               if (min_prediv == 1)
+                       break;
+       }
+       deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
+
+       min_prediv = 2;
+
+       for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
+               fcp = xtal / prediv;
+               if (fcp > fcp_min && fcp < fcp_max) {
+                       for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
+                               fdem = ((xtal/prediv) * loopdiv);
+                               fs   = fdem / 4;
+                               /* test min/max system restrictions */
+
+                               if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
+                                       spur = 0;
+                                       /* test fs harmonics positions */
+                                       for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ;  harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
+                                               if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) &&  ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
+                                                       spur = 1;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!spur) {
+                                               adc->pll_loopdiv = loopdiv;
+                                               adc->pll_prediv = prediv;
+                                               adc->timf = 2396745143UL/fdem*(1 << 9);
+                                               adc->timf += ((2396745143UL%fdem) << 9)/fdem;
+                                               deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               if (!spur)
+                       break;
+       }
+
+
+       if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
+               return -EINVAL;
+       else
+               return 0;
+}
+
+static int dib7090_agc_startup(struct dvb_frontend *fe)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+       struct dibx000_bandwidth_config pll;
+       u16 target;
+       struct dib7090p_best_adc adc;
+       int ret;
+
+       ret = state->set_param_save(fe);
+       if (ret < 0)
+               return ret;
+
+       memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
+       dib0090_pwm_gain_reset(fe);
+       target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
+       dib7000p_set_wbd_ref(fe, target);
+
+       if (dib7090p_get_best_sampling(fe, &adc) == 0) {
+               pll.pll_ratio  = adc.pll_loopdiv;
+               pll.pll_prediv = adc.pll_prediv;
+
+               dib7000p_update_pll(fe, &pll);
+               dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
+       }
+       return 0;
+}
+
+static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
+{
+       deb_info("AGC restart callback: %d", restart);
+       if (restart == 0) /* before AGC startup */
+               dib0090_set_dc_servo(fe, 1);
+       return 0;
+}
+
+static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global)
+{
+       u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1;
+       s16 wbd_delta;
+
+       if ((fe->dtv_property_cache.frequency) < 400000000)
+               threshold_agc1 = 25000;
+       else
+               threshold_agc1 = 30000;
+
+       wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2;
+       wbd_offset = dib0090_get_wbd_offset(fe);
+       dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd);
+       wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ;
+
+       deb_info("update lna, agc_global=%d agc1=%d agc2=%d",
+                       agc_global, agc1, agc2);
+       deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d",
+                       wbd, wbd_target, wbd_offset, wbd_delta);
+
+       if ((agc1 < threshold_agc1) && (wbd_delta > 0)) {
+               dib0090_set_switch(fe, 1, 1, 1);
+               dib0090_set_vga(fe, 0);
+               dib0090_update_rframp_7090(fe, 0);
+               dib0090_update_tuning_table_7090(fe, 0);
+       } else {
+               dib0090_set_vga(fe, 1);
+               dib0090_update_rframp_7090(fe, 1);
+               dib0090_update_tuning_table_7090(fe, 1);
+               dib0090_set_switch(fe, 0, 0, 0);
+       }
+
+       return 0;
+}
+
+static struct dib0090_wbd_slope dib7090_wbd_table[] = {
+       { 380,   81, 850, 64, 540,  4},
+       { 860,   51, 866, 21,  375, 4},
+       {1700,    0, 250, 0,   100, 6},
+       {2600,    0, 250, 0,   100, 6},
+       { 0xFFFF, 0,   0, 0,   0,   0},
+};
+
+static struct dib0090_wbd_slope dib7090e_wbd_table[] = {
+       { 380,   81, 850, 64, 540,      4},
+       { 700,   51, 866, 21,  320,     4},
+       { 860,   48, 666, 18,  330,     6},
+       {1700,    0, 250, 0,   100, 6},
+       {2600,    0, 250, 0,   100, 6},
+       { 0xFFFF, 0,   0, 0,   0,       0},
+};
+
+static struct dibx000_agc_config dib7090_agc_config[2] = {
+       {
+               .band_caps      = BAND_UHF,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+               .setup          = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+               .inv_gain       = 687,
+               .time_stabiliz  = 10,
+
+               .alpha_level    = 0,
+               .thlock         = 118,
+
+               .wbd_inv        = 0,
+               .wbd_ref        = 1200,
+               .wbd_sel        = 3,
+               .wbd_alpha      = 5,
+
+               .agc1_max       = 65535,
+               .agc1_min       = 0,
+
+               .agc2_max       = 65535,
+               .agc2_min       = 0,
+
+               .agc1_pt1       = 0,
+               .agc1_pt2       = 32,
+               .agc1_pt3       = 114,
+               .agc1_slope1    = 143,
+               .agc1_slope2    = 144,
+               .agc2_pt1       = 114,
+               .agc2_pt2       = 227,
+               .agc2_slope1    = 116,
+               .agc2_slope2    = 117,
+
+               .alpha_mant     = 18,
+               .alpha_exp      = 0,
+               .beta_mant      = 20,
+               .beta_exp       = 59,
+
+               .perform_agc_softsplit = 0,
+       } , {
+               .band_caps      = BAND_FM | BAND_VHF | BAND_CBAND,
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+               .setup          = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+               .inv_gain       = 732,
+               .time_stabiliz  = 10,
+
+               .alpha_level    = 0,
+               .thlock         = 118,
+
+               .wbd_inv        = 0,
+               .wbd_ref        = 1200,
+               .wbd_sel        = 3,
+               .wbd_alpha      = 5,
+
+               .agc1_max       = 65535,
+               .agc1_min       = 0,
+
+               .agc2_max       = 65535,
+               .agc2_min       = 0,
+
+               .agc1_pt1       = 0,
+               .agc1_pt2       = 0,
+               .agc1_pt3       = 98,
+               .agc1_slope1    = 0,
+               .agc1_slope2    = 167,
+               .agc2_pt1       = 98,
+               .agc2_pt2       = 255,
+               .agc2_slope1    = 104,
+               .agc2_slope2    = 0,
+
+               .alpha_mant     = 18,
+               .alpha_exp      = 0,
+               .beta_mant      = 20,
+               .beta_exp       = 59,
+
+               .perform_agc_softsplit = 0,
+       }
+};
+
+static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
+       60000, 15000,
+       1, 5, 0, 0, 0,
+       0, 0, 1, 1, 2,
+       (3 << 14) | (1 << 12) | (524 << 0),
+       (0 << 25) | 0,
+       20452225,
+       15000000,
+};
+
+static struct dib7000p_config nim7090_dib7000p_config = {
+       .output_mpeg2_in_188_bytes  = 1,
+       .hostbus_diversity                      = 1,
+       .tuner_is_baseband                      = 1,
+       .update_lna                                     = NULL,
+
+       .agc_config_count                       = 2,
+       .agc                                            = dib7090_agc_config,
+
+       .bw                                                     = &dib7090_clock_config_12_mhz,
+
+       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .pwm_freq_div                           = 0,
+
+       .agc_control                            = dib7090_agc_restart,
+
+       .spur_protect                           = 0,
+       .disable_sample_and_hold        = 0,
+       .enable_current_mirror          = 0,
+       .diversity_delay                        = 0,
+
+       .output_mode                            = OUTMODE_MPEG2_FIFO,
+       .enMpegOutput                           = 1,
+};
+
+static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
+       {
+               .output_mpeg2_in_188_bytes  = 1,
+               .hostbus_diversity                      = 1,
+               .tuner_is_baseband                      = 1,
+               .update_lna                                     = NULL,
+
+               .agc_config_count                       = 2,
+               .agc                                            = dib7090_agc_config,
+
+               .bw                                                     = &dib7090_clock_config_12_mhz,
+
+               .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .pwm_freq_div                           = 0,
+
+               .agc_control                            = dib7090_agc_restart,
+
+               .spur_protect                           = 0,
+               .disable_sample_and_hold        = 0,
+               .enable_current_mirror          = 0,
+               .diversity_delay                        = 0,
+
+               .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
+               .default_i2c_addr                       = 0x90,
+               .enMpegOutput                           = 1,
+       }, {
+               .output_mpeg2_in_188_bytes  = 1,
+               .hostbus_diversity                      = 1,
+               .tuner_is_baseband                      = 1,
+               .update_lna                                     = NULL,
+
+               .agc_config_count                       = 2,
+               .agc                                            = dib7090_agc_config,
+
+               .bw                                                     = &dib7090_clock_config_12_mhz,
+
+               .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .pwm_freq_div                           = 0,
+
+               .agc_control                            = dib7090_agc_restart,
+
+               .spur_protect                           = 0,
+               .disable_sample_and_hold        = 0,
+               .enable_current_mirror          = 0,
+               .diversity_delay                        = 0,
+
+               .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
+               .default_i2c_addr                       = 0x92,
+               .enMpegOutput                           = 0,
+       }
+};
+
+static struct dib7000p_config tfe7090e_dib7000p_config = {
+       .output_mpeg2_in_188_bytes  = 1,
+       .hostbus_diversity                      = 1,
+       .tuner_is_baseband                      = 1,
+       .update_lna                                     = dib7090e_update_lna,
+
+       .agc_config_count                       = 2,
+       .agc                                            = dib7090_agc_config,
+
+       .bw                                                     = &dib7090_clock_config_12_mhz,
+
+       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .pwm_freq_div                           = 0,
+
+       .agc_control                            = dib7090_agc_restart,
+
+       .spur_protect                           = 0,
+       .disable_sample_and_hold        = 0,
+       .enable_current_mirror          = 0,
+       .diversity_delay                        = 0,
+
+       .output_mode                            = OUTMODE_MPEG2_FIFO,
+       .enMpegOutput                           = 1,
+};
+
+static const struct dib0090_config nim7090_dib0090_config = {
+       .io.clock_khz = 12000,
+       .io.pll_bypass = 0,
+       .io.pll_range = 0,
+       .io.pll_prediv = 3,
+       .io.pll_loopdiv = 6,
+       .io.adc_clock_ratio = 0,
+       .io.pll_int_loop_filt = 0,
+       .reset = dib7090_tuner_sleep,
+       .sleep = dib7090_tuner_sleep,
+
+       .freq_offset_khz_uhf = 0,
+       .freq_offset_khz_vhf = 0,
+
+       .get_adc_power = dib7090_get_adc_power,
+
+       .clkouttobamse = 1,
+       .analog_output = 0,
+
+       .wbd_vhf_offset = 0,
+       .wbd_cband_offset = 0,
+       .use_pwm_agc = 1,
+       .clkoutdrive = 0,
+
+       .fref_clock_ratio = 0,
+
+       .wbd = dib7090_wbd_table,
+
+       .ls_cfg_pad_drv = 0,
+       .data_tx_drv = 0,
+       .low_if = NULL,
+       .in_soc = 1,
+};
+
+static const struct dib0090_config tfe7090e_dib0090_config = {
+       .io.clock_khz = 12000,
+       .io.pll_bypass = 0,
+       .io.pll_range = 0,
+       .io.pll_prediv = 3,
+       .io.pll_loopdiv = 6,
+       .io.adc_clock_ratio = 0,
+       .io.pll_int_loop_filt = 0,
+       .reset = dib7090_tuner_sleep,
+       .sleep = dib7090_tuner_sleep,
+
+       .freq_offset_khz_uhf = 0,
+       .freq_offset_khz_vhf = 0,
+
+       .get_adc_power = dib7090_get_adc_power,
+
+       .clkouttobamse = 1,
+       .analog_output = 0,
+
+       .wbd_vhf_offset = 0,
+       .wbd_cband_offset = 0,
+       .use_pwm_agc = 1,
+       .clkoutdrive = 0,
+
+       .fref_clock_ratio = 0,
+
+       .wbd = dib7090e_wbd_table,
+
+       .ls_cfg_pad_drv = 0,
+       .data_tx_drv = 0,
+       .low_if = NULL,
+       .in_soc = 1,
+       .force_cband_input = 1,
+       .is_dib7090e = 1,
+};
+
+static struct dib7000p_config tfe7790e_dib7000p_config = {
+       .output_mpeg2_in_188_bytes  = 1,
+       .hostbus_diversity                      = 1,
+       .tuner_is_baseband                      = 1,
+       .update_lna                                     = dib7090e_update_lna,
+
+       .agc_config_count                       = 2,
+       .agc                                            = dib7090_agc_config,
+
+       .bw                                                     = &dib7090_clock_config_12_mhz,
+
+       .gpio_dir                                       = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val                                       = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos                           = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .pwm_freq_div                           = 0,
+
+       .agc_control                            = dib7090_agc_restart,
+
+       .spur_protect                           = 0,
+       .disable_sample_and_hold        = 0,
+       .enable_current_mirror          = 0,
+       .diversity_delay                        = 0,
+
+       .output_mode                            = OUTMODE_MPEG2_PAR_GATED_CLK,
+       .enMpegOutput                           = 1,
+};
+
+static const struct dib0090_config tfe7790e_dib0090_config = {
+       .io.clock_khz = 12000,
+       .io.pll_bypass = 0,
+       .io.pll_range = 0,
+       .io.pll_prediv = 3,
+       .io.pll_loopdiv = 6,
+       .io.adc_clock_ratio = 0,
+       .io.pll_int_loop_filt = 0,
+       .reset = dib7090_tuner_sleep,
+       .sleep = dib7090_tuner_sleep,
+
+       .freq_offset_khz_uhf = 0,
+       .freq_offset_khz_vhf = 0,
+
+       .get_adc_power = dib7090_get_adc_power,
+
+       .clkouttobamse = 1,
+       .analog_output = 0,
+
+       .wbd_vhf_offset = 0,
+       .wbd_cband_offset = 0,
+       .use_pwm_agc = 1,
+       .clkoutdrive = 0,
+
+       .fref_clock_ratio = 0,
+
+       .wbd = dib7090e_wbd_table,
+
+       .ls_cfg_pad_drv = 0,
+       .data_tx_drv = 0,
+       .low_if = NULL,
+       .in_soc = 1,
+       .force_cband_input = 1,
+       .is_dib7090e = 1,
+       .force_crystal_mode = 1,
+};
+
+static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
+       {
+               .io.clock_khz = 12000,
+               .io.pll_bypass = 0,
+               .io.pll_range = 0,
+               .io.pll_prediv = 3,
+               .io.pll_loopdiv = 6,
+               .io.adc_clock_ratio = 0,
+               .io.pll_int_loop_filt = 0,
+               .reset = dib7090_tuner_sleep,
+               .sleep = dib7090_tuner_sleep,
+
+               .freq_offset_khz_uhf = 50,
+               .freq_offset_khz_vhf = 70,
+
+               .get_adc_power = dib7090_get_adc_power,
+
+               .clkouttobamse = 1,
+               .analog_output = 0,
+
+               .wbd_vhf_offset = 0,
+               .wbd_cband_offset = 0,
+               .use_pwm_agc = 1,
+               .clkoutdrive = 0,
+
+               .fref_clock_ratio = 0,
+
+               .wbd = dib7090_wbd_table,
+
+               .ls_cfg_pad_drv = 0,
+               .data_tx_drv = 0,
+               .low_if = NULL,
+               .in_soc = 1,
+       }, {
+               .io.clock_khz = 12000,
+               .io.pll_bypass = 0,
+               .io.pll_range = 0,
+               .io.pll_prediv = 3,
+               .io.pll_loopdiv = 6,
+               .io.adc_clock_ratio = 0,
+               .io.pll_int_loop_filt = 0,
+               .reset = dib7090_tuner_sleep,
+               .sleep = dib7090_tuner_sleep,
+
+               .freq_offset_khz_uhf = -50,
+               .freq_offset_khz_vhf = -70,
+
+               .get_adc_power = dib7090_get_adc_power,
+
+               .clkouttobamse = 1,
+               .analog_output = 0,
+
+               .wbd_vhf_offset = 0,
+               .wbd_cband_offset = 0,
+               .use_pwm_agc = 1,
+               .clkoutdrive = 0,
+
+               .fref_clock_ratio = 0,
+
+               .wbd = dib7090_wbd_table,
+
+               .ls_cfg_pad_drv = 0,
+               .data_tx_drv = 0,
+               .low_if = NULL,
+               .in_soc = 1,
+       }
+};
+
+static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+               return -ENODEV;
+       }
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
+               return -ENODEV;
+
+       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+       return 0;
+}
+
+static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+
+       /* The TFE7090 requires the dib0700 to not be in master mode */
+       st->disable_streaming_master_mode = 1;
+
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       /* initialize IC 0 */
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+               return -ENODEV;
+       }
+
+       dib0700_set_i2c_speed(adap->dev, 340);
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
+       if (adap->fe_adap[0].fe == NULL)
+               return -ENODEV;
+
+       dib7090_slave_reset(adap->fe_adap[0].fe);
+
+       return 0;
+}
+
+static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *i2c;
+
+       if (adap->dev->adapter[0].fe_adap[0].fe == NULL) {
+               err("the master dib7090 has to be initialized first");
+               return -ENODEV; /* the master device has not been initialized */
+       }
+
+       i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
+       if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
+       dib0700_set_i2c_speed(adap->dev, 200);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
+               return -ENODEV;
+
+       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+       return 0;
+}
+
+static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
+               return -ENODEV;
+
+       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+       return 0;
+}
+
+static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
+                               1, 0x10, &tfe7090e_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                               __func__);
+               return -ENODEV;
+       }
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+                       0x80, &tfe7090e_dib7000p_config);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+
+       /* The TFE7790E requires the dib0700 to not be in master mode */
+       st->disable_streaming_master_mode = 1;
+
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+       msleep(20);
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(20);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
+                               1, 0x10, &tfe7790e_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                               __func__);
+               return -ENODEV;
+       }
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+                       0x80, &tfe7790e_dib7000p_config);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c =
+               dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+                               &tfe7790e_dib0090_config) == NULL)
+               return -ENODEV;
+
+       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+       return 0;
+}
+
+static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c =
+               dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+                               &tfe7090e_dib0090_config) == NULL)
+               return -ENODEV;
+
+       dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+       st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+       adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+       return 0;
+}
+
+/* STK7070PD */
+static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
+       {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 1,
+               .agc = &dib7070_agc_config,
+               .bw  = &dib7070_bw_config_12_mhz,
+               .tuner_is_baseband = 1,
+               .spur_protect = 1,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+       }, {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 1,
+               .agc = &dib7070_agc_config,
+               .bw  = &dib7070_bw_config_12_mhz,
+               .tuner_is_baseband = 1,
+               .spur_protect = 1,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+       }
+};
+
+static void stk7070pd_init(struct dvb_usb_device *dev)
+{
+       dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
+}
+
+static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
+{
+       stk7070pd_init(adap->dev);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+                                    stk7070pd_dib7000p_config) != 0) {
+               err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                   __func__);
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
+{
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int novatd_read_status_override(struct dvb_frontend *fe,
+               fe_status_t *stat)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *dev = adap->dev;
+       struct dib0700_state *state = dev->priv;
+       int ret;
+
+       ret = state->read_status(fe, stat);
+
+       if (!ret)
+               dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
+                               !!(*stat & FE_HAS_LOCK));
+
+       return ret;
+}
+
+static int novatd_sleep_override(struct dvb_frontend* fe)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *dev = adap->dev;
+       struct dib0700_state *state = dev->priv;
+
+       /* turn off LED */
+       dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
+
+       return state->sleep(fe);
+}
+
+/**
+ * novatd_frontend_attach - Nova-TD specific attach
+ *
+ * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
+ * information purposes.
+ */
+static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *dev = adap->dev;
+       struct dib0700_state *st = dev->priv;
+
+       if (adap->id == 0) {
+               stk7070pd_init(dev);
+
+               /* turn the power LED on, the other two off (just in case) */
+               dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
+               dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
+               dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
+
+               if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
+                                            stk7070pd_dib7000p_config) != 0) {
+                       err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+                           __func__);
+                       return -ENODEV;
+               }
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
+                       adap->id == 0 ? 0x80 : 0x82,
+                       &stk7070pd_dib7000p_config[adap->id]);
+
+       if (adap->fe_adap[0].fe == NULL)
+               return -ENODEV;
+
+       st->read_status = adap->fe_adap[0].fe->ops.read_status;
+       adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
+       st->sleep = adap->fe_adap[0].fe->ops.sleep;
+       adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
+
+       return 0;
+}
+
+/* S5H1411 */
+static struct s5h1411_config pinnacle_801e_config = {
+       .output_mode   = S5H1411_PARALLEL_OUTPUT,
+       .gpio          = S5H1411_GPIO_OFF,
+       .mpeg_timing   = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
+       .qam_if        = S5H1411_IF_44000,
+       .vsb_if        = S5H1411_IF_44000,
+       .inversion     = S5H1411_INVERSION_OFF,
+       .status_mode   = S5H1411_DEMODLOCKING
+};
+
+/* Pinnacle PCTV HD Pro 801e GPIOs map:
+   GPIO0  - currently unknown
+   GPIO1  - xc5000 tuner reset
+   GPIO2  - CX25843 sleep
+   GPIO3  - currently unknown
+   GPIO4  - currently unknown
+   GPIO6  - currently unknown
+   GPIO7  - currently unknown
+   GPIO9  - currently unknown
+   GPIO10 - CX25843 reset
+ */
+static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+
+       /* Make use of the new i2c functions from FW 1.20 */
+       st->fw_use_new_i2c_api = 1;
+
+       /* The s5h1411 requires the dib0700 to not be in master mode */
+       st->disable_streaming_master_mode = 1;
+
+       /* All msleep values taken from Windows USB trace */
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
+       dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(400);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+       msleep(60);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(30);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
+       msleep(30);
+
+       /* Put the CX25843 to sleep for now since we're in digital mode */
+       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
+
+       /* GPIOs are initialized, do the attach */
+       adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
+                             &adap->dev->i2c_adap);
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int dib0700_xc5000_tuner_callback(void *priv, int component,
+                                        int command, int arg)
+{
+       struct dvb_usb_adapter *adap = priv;
+
+       if (command == XC5000_TUNER_RESET) {
+               /* Reset the tuner */
+               dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
+               msleep(10);
+       } else {
+               err("xc5000: unknown tuner callback command: %d\n", command);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct xc5000_config s5h1411_xc5000_tunerconfig = {
+       .i2c_address      = 0x64,
+       .if_khz           = 5380,
+};
+
+static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       /* FIXME: generalize & move to common area */
+       adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback;
+
+       return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
+                         &s5h1411_xc5000_tunerconfig)
+               == NULL ? -ENODEV : 0;
+}
+
+static int dib0700_xc4000_tuner_callback(void *priv, int component,
+                                        int command, int arg)
+{
+       struct dvb_usb_adapter *adap = priv;
+
+       if (command == XC4000_TUNER_RESET) {
+               /* Reset the tuner */
+               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
+               msleep(10);
+               dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+       } else {
+               err("xc4000: unknown tuner callback command: %d\n", command);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
+       .band_caps = BAND_UHF | BAND_VHF,
+       .setup = 0x64,
+       .inv_gain = 0x02c8,
+       .time_stabiliz = 0x15,
+       .alpha_level = 0x00,
+       .thlock = 0x76,
+       .wbd_inv = 0x01,
+       .wbd_ref = 0x0b33,
+       .wbd_sel = 0x00,
+       .wbd_alpha = 0x02,
+       .agc1_max = 0x00,
+       .agc1_min = 0x00,
+       .agc2_max = 0x9b26,
+       .agc2_min = 0x26ca,
+       .agc1_pt1 = 0x00,
+       .agc1_pt2 = 0x00,
+       .agc1_pt3 = 0x00,
+       .agc1_slope1 = 0x00,
+       .agc1_slope2 = 0x00,
+       .agc2_pt1 = 0x00,
+       .agc2_pt2 = 0x80,
+       .agc2_slope1 = 0x1d,
+       .agc2_slope2 = 0x1d,
+       .alpha_mant = 0x11,
+       .alpha_exp = 0x1b,
+       .beta_mant = 0x17,
+       .beta_exp = 0x33,
+       .perform_agc_softsplit = 0x00,
+};
+
+static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
+       60000, 30000,   /* internal, sampling */
+       1, 8, 3, 1, 0,  /* pll_cfg: prediv, ratio, range, reset, bypass */
+       0, 0, 1, 1, 0,  /* misc: refdiv, bypclk_div, IO_CLK_en_core, */
+                       /* ADClkSrc, modulo */
+       (3 << 14) | (1 << 12) | 524,    /* sad_cfg: refsel, sel, freq_15k */
+       39370534,       /* ifreq */
+       20452225,       /* timf */
+       30000000        /* xtal */
+};
+
+/* FIXME: none of these inputs are validated yet */
+static struct dib7000p_config pctv_340e_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &stk7700p_7000p_xc4000_agc_config,
+       .bw  = &stk7700p_xc4000_pll_config,
+
+       .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
+};
+
+/* PCTV 340e GPIOs map:
+   dib0700:
+   GPIO2  - CX25843 sleep
+   GPIO3  - CS5340 reset
+   GPIO5  - IRD
+   GPIO6  - Power Supply
+   GPIO8  - LNA (1=off 0=on)
+   GPIO10 - CX25843 reset
+   dib7000:
+   GPIO8  - xc4000 reset
+ */
+static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+
+       /* Power Supply on */
+       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0);
+       msleep(50);
+       dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1);
+       msleep(100); /* Allow power supply to settle before probing */
+
+       /* cx25843 reset */
+       dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 0);
+       msleep(1); /* cx25843 datasheet say 350us required */
+       dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 1);
+
+       /* LNA off for now */
+       dib0700_set_gpio(adap->dev, GPIO8,  GPIO_OUT, 1);
+
+       /* Put the CX25843 to sleep for now since we're in digital mode */
+       dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
+
+       /* FIXME: not verified yet */
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(500);
+
+       if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
+               /* Demodulator not found for some reason? */
+               return -ENODEV;
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
+                             &pctv_340e_config);
+       st->is_dib7000pc = 1;
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static struct xc4000_config dib7000p_xc4000_tunerconfig = {
+       .i2c_address      = 0x61,
+       .default_pm       = 1,
+       .dvb_amplitude    = 0,
+       .set_smoothedcvbs = 0,
+       .if_khz           = 5400
+};
+
+static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *tun_i2c;
+
+       /* The xc4000 is not on the main i2c bus */
+       tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+                                         DIBX000_I2C_INTERFACE_TUNER, 1);
+       if (tun_i2c == NULL) {
+               printk(KERN_ERR "Could not reach tuner i2c bus\n");
+               return 0;
+       }
+
+       /* Setup the reset callback */
+       adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback;
+
+       return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c,
+                         &dib7000p_xc4000_tunerconfig)
+               == NULL ? -ENODEV : 0;
+}
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+       .i2c_addr           = 0x0e,
+       .mpeg_mode          = LGDT3305_MPEG_PARALLEL,
+       .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
+       .tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
+       .deny_i2c_rptr      = 0,
+       .spectral_inversion = 1,
+       .qam_if_khz         = 6000,
+       .vsb_if_khz         = 6000,
+       .usref_8vsb         = 0x0500,
+};
+
+static struct mxl5007t_config hcw_mxl5007t_config = {
+       .xtal_freq_hz = MxL_XTAL_25_MHZ,
+       .if_freq_hz = MxL_IF_6_MHZ,
+       .invert_if = 1,
+};
+
+/* TIGER-ATSC map:
+   GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
+   GPIO1  - ANT_SEL  (H: VPA, L: MCX)
+   GPIO4  - SCL2
+   GPIO6  - EN_TUNER
+   GPIO7  - SDA2
+   GPIO10 - DEM_RST
+
+   MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
+ */
+static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+
+       /* Make use of the new i2c functions from FW 1.20 */
+       st->fw_use_new_i2c_api = 1;
+
+       st->disable_streaming_master_mode = 1;
+
+       /* fe power enable */
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+       msleep(30);
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(30);
+
+       /* demod reset */
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(30);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+       msleep(30);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(30);
+
+       adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach,
+                             &hcw_lgdt3305_config,
+                             &adap->dev->i2c_adap);
+
+       return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
+                         &adap->dev->i2c_adap, 0x60,
+                         &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
+}
+
+
+/* DVB-USB and USB stuff follows */
+struct usb_device_id dib0700_usb_id_table[] = {
+/* 0 */        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
+/* 5 */        { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
+       { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
+       { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
+       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
+/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
+       { USB_DEVICE(USB_VID_TERRATEC,
+                       USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
+/* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
+       { USB_DEVICE(USB_VID_PINNACLE,
+                       USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
+       { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
+/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
+       { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
+       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
+       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
+       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
+/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_EXPRESSCARD_320CX) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV72E) },
+/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
+       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_EC372S) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS) },
+       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
+/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
+       { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U8000) },
+       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700PH) },
+       { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000H) },
+/* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
+       { USB_DEVICE(USB_VID_TERRATEC,
+                       USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
+       { USB_DEVICE(USB_VID_SONY,      USB_PID_SONY_PLAYTV) },
+/* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
+       { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_MC770) },
+       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT) },
+/* 50 */{ USB_DEVICE(USB_VID_ELGATO,   USB_PID_ELGATO_EYETV_DTT_Dlx) },
+       { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T3) },
+       { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T5) },
+       { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
+/* 55 */{ USB_DEVICE(USB_VID_YUAN,     USB_PID_YUAN_STK7700D_2) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73A) },
+       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV73ESE) },
+       { USB_DEVICE(USB_VID_PCTV,      USB_PID_PINNACLE_PCTV282E) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
+/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
+       { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
+       { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
+/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096GP) },
+       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DIVERSITY) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM9090M) },
+/* 70 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM8096MD) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM9090MD) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM7090) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090PVR) },
+       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
+/* 75 */{ USB_DEVICE(USB_VID_MEDION,    USB_PID_CREATIX_CTX1921) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E) },
+       { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E_SE) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090E) },
+       { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7790E) },
+/* 80 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE8096P) },
+       { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT_2) },
+       { 0 }           /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
+
+#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
+       .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
+       .usb_ctrl          = DEVICE_SPECIFIC, \
+       .firmware          = "dvb-usb-dib0700-1.20.fw", \
+       .download_firmware = dib0700_download_firmware, \
+       .no_reconnect      = 1, \
+       .size_of_priv      = sizeof(struct dib0700_state), \
+       .i2c_algo          = &dib0700_i2c_algo, \
+       .identify_state    = dib0700_identify_state
+
+#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
+       .streaming_ctrl   = dib0700_streaming_ctrl, \
+       .stream = { \
+               .type = USB_BULK, \
+               .count = 4, \
+               .endpoint = ep, \
+               .u = { \
+                       .bulk = { \
+                               .buffersize = 39480, \
+                       } \
+               } \
+       }
+
+struct dvb_usb_device_properties dib0700_devices[] = {
+       {
+               DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk7700p_pid_filter,
+                               .pid_filter_ctrl  = stk7700p_pid_filter_ctrl,
+                               .frontend_attach  = stk7700p_frontend_attach,
+                               .tuner_attach     = stk7700p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                       },
+               },
+
+               .num_device_descs = 8,
+               .devices = {
+                       {   "DiBcom STK7700P reference design",
+                               { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-T Stick",
+                               { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
+                               { NULL },
+                       },
+                       {   "AVerMedia AVerTV DVB-T Volar",
+                               { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
+                               { NULL },
+                       },
+                       {   "Compro Videomate U500",
+                               { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
+                               { NULL },
+                       },
+                       {   "Uniwill STK7700P based (Hama and others)",
+                               { &dib0700_usb_id_table[7], NULL },
+                               { NULL },
+                       },
+                       {   "Leadtek Winfast DTV Dongle (STK7700P based)",
+                               { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
+                               { NULL },
+                       },
+                       {   "AVerMedia AVerTV DVB-T Express",
+                               { &dib0700_usb_id_table[20] },
+                               { NULL },
+                       },
+                       {   "Gigabyte U7000",
+                               { &dib0700_usb_id_table[21], NULL },
+                               { NULL },
+                       }
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .frontend_attach  = bristol_frontend_attach,
+                               .tuner_attach     = bristol_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                       }, {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .frontend_attach  = bristol_frontend_attach,
+                               .tuner_attach     = bristol_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                       }
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "Hauppauge Nova-T 500 Dual DVB-T",
+                               { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7700d_frontend_attach,
+                               .tuner_attach     = stk7700d_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                       }, {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7700d_frontend_attach,
+                               .tuner_attach     = stk7700d_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                       }
+               },
+
+               .num_device_descs = 5,
+               .devices = {
+                       {   "Pinnacle PCTV 2000e",
+                               { &dib0700_usb_id_table[11], NULL },
+                               { NULL },
+                       },
+                       {   "Terratec Cinergy DT XS Diversity",
+                               { &dib0700_usb_id_table[12], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
+                               { &dib0700_usb_id_table[13], NULL },
+                               { NULL },
+                       },
+                       {   "DiBcom STK7700D reference design",
+                               { &dib0700_usb_id_table[14], NULL },
+                               { NULL },
+                       },
+                       {   "YUAN High-Tech DiBcom STK7700D",
+                               { &dib0700_usb_id_table[55], NULL },
+                               { NULL },
+                       },
+
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7700P2_frontend_attach,
+                               .tuner_attach     = stk7700d_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                       },
+               },
+
+               .num_device_descs = 3,
+               .devices = {
+                       {   "ASUS My Cinema U3000 Mini DVBT Tuner",
+                               { &dib0700_usb_id_table[23], NULL },
+                               { NULL },
+                       },
+                       {   "Yuan EC372S",
+                               { &dib0700_usb_id_table[31], NULL },
+                               { NULL },
+                       },
+                       {   "Terratec Cinergy T Express",
+                               { &dib0700_usb_id_table[42], NULL },
+                               { NULL },
+                       }
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070p_frontend_attach,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 12,
+               .devices = {
+                       {   "DiBcom STK7070P reference design",
+                               { &dib0700_usb_id_table[15], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV DVB-T Flash Stick",
+                               { &dib0700_usb_id_table[16], NULL },
+                               { NULL },
+                       },
+                       {   "Artec T14BR DVB-T",
+                               { &dib0700_usb_id_table[22], NULL },
+                               { NULL },
+                       },
+                       {   "ASUS My Cinema U3100 Mini DVBT Tuner",
+                               { &dib0700_usb_id_table[24], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-T Stick",
+                               { &dib0700_usb_id_table[25], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-T MyTV.t",
+                               { &dib0700_usb_id_table[26], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV 72e",
+                               { &dib0700_usb_id_table[29], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV 73e",
+                               { &dib0700_usb_id_table[30], NULL },
+                               { NULL },
+                       },
+                       {   "Elgato EyeTV DTT",
+                               { &dib0700_usb_id_table[49], NULL },
+                               { NULL },
+                       },
+                       {   "Yuan PD378S",
+                               { &dib0700_usb_id_table[45], NULL },
+                               { NULL },
+                       },
+                       {   "Elgato EyeTV Dtt Dlx PD378S",
+                               { &dib0700_usb_id_table[50], NULL },
+                               { NULL },
+                       },
+                       {   "Elgato EyeTV DTT rev. 2",
+                               { &dib0700_usb_id_table[81], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070p_frontend_attach,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 3,
+               .devices = {
+                       {   "Pinnacle PCTV 73A",
+                               { &dib0700_usb_id_table[56], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV 73e SE",
+                               { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV 282e",
+                               { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = novatd_frontend_attach,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }, {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = novatd_frontend_attach,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "Hauppauge Nova-TD Stick (52009)",
+                               { &dib0700_usb_id_table[35], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070pd_frontend_attach0,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }, {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070pd_frontend_attach1,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }
+               },
+
+               .num_device_descs = 5,
+               .devices = {
+                       {   "DiBcom STK7070PD reference design",
+                               { &dib0700_usb_id_table[17], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
+                               { &dib0700_usb_id_table[18], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-TD-500 (84xxx)",
+                               { &dib0700_usb_id_table[36], NULL },
+                               { NULL },
+                       },
+                       {  "Terratec Cinergy DT USB XS Diversity/ T5",
+                               { &dib0700_usb_id_table[43],
+                                       &dib0700_usb_id_table[53], NULL},
+                               { NULL },
+                       },
+                       {  "Sony PlayTV",
+                               { &dib0700_usb_id_table[44], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070pd_frontend_attach0,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }, {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7070pd_frontend_attach1,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "Elgato EyeTV Diversity",
+                               { &dib0700_usb_id_table[68], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7700ph_frontend_attach,
+                               .tuner_attach     = stk7700ph_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv = sizeof(struct
+                                               dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 9,
+               .devices = {
+                       {   "Terratec Cinergy HT USB XE",
+                               { &dib0700_usb_id_table[27], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle Expresscard 320cx",
+                               { &dib0700_usb_id_table[28], NULL },
+                               { NULL },
+                       },
+                       {   "Terratec Cinergy HT Express",
+                               { &dib0700_usb_id_table[32], NULL },
+                               { NULL },
+                       },
+                       {   "Gigabyte U8000-RH",
+                               { &dib0700_usb_id_table[37], NULL },
+                               { NULL },
+                       },
+                       {   "YUAN High-Tech STK7700PH",
+                               { &dib0700_usb_id_table[38], NULL },
+                               { NULL },
+                       },
+                       {   "Asus My Cinema-U3000Hybrid",
+                               { &dib0700_usb_id_table[39], NULL },
+                               { NULL },
+                       },
+                       {   "YUAN High-Tech MC770",
+                               { &dib0700_usb_id_table[48], NULL },
+                               { NULL },
+                       },
+                       {   "Leadtek WinFast DTV Dongle H",
+                               { &dib0700_usb_id_table[51], NULL },
+                               { NULL },
+                       },
+                       {   "YUAN High-Tech STK7700D",
+                               { &dib0700_usb_id_table[54], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .frontend_attach  = s5h1411_frontend_attach,
+                               .tuner_attach     = xc5000_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv = sizeof(struct
+                                               dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 2,
+               .devices = {
+                       {   "Pinnacle PCTV HD Pro USB Stick",
+                               { &dib0700_usb_id_table[40], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV HD USB Stick",
+                               { &dib0700_usb_id_table[41], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .frontend_attach  = lgdt3305_frontend_attach,
+                               .tuner_attach     = mxl5007t_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv = sizeof(struct
+                                               dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 2,
+               .devices = {
+                       {   "Hauppauge ATSC MiniCard (B200)",
+                               { &dib0700_usb_id_table[46], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge ATSC MiniCard (B210)",
+                               { &dib0700_usb_id_table[47], NULL },
+                               { NULL },
+                       },
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter       = stk70x0p_pid_filter,
+                               .pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = stk7770p_frontend_attach,
+                               .tuner_attach     = dib7770p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 4,
+               .devices = {
+                       {   "DiBcom STK7770P reference design",
+                               { &dib0700_usb_id_table[59], NULL },
+                               { NULL },
+                       },
+                       {   "Terratec Cinergy T USB XXS (HD)/ T3",
+                               { &dib0700_usb_id_table[33],
+                                       &dib0700_usb_id_table[52],
+                                       &dib0700_usb_id_table[60], NULL},
+                               { NULL },
+                       },
+                       {   "TechniSat AirStar TeleStick 2",
+                               { &dib0700_usb_id_table[74], NULL },
+                               { NULL },
+                       },
+                       {   "Medion CTX1921 DVB-T USB",
+                               { &dib0700_usb_id_table[75], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = stk807x_frontend_attach,
+                               .tuner_attach     = dib807x_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 3,
+               .devices = {
+                       {   "DiBcom STK807xP reference design",
+                               { &dib0700_usb_id_table[62], NULL },
+                               { NULL },
+                       },
+                       {   "Prolink Pixelview SBTVD",
+                               { &dib0700_usb_id_table[63], NULL },
+                               { NULL },
+                       },
+                       {   "EvolutePC TVWay+",
+                               { &dib0700_usb_id_table[64], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = stk807xpvr_frontend_attach0,
+                               .tuner_attach     = dib807x_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = stk807xpvr_frontend_attach1,
+                               .tuner_attach     = dib807x_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom STK807xPVR reference design",
+                               { &dib0700_usb_id_table[61], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = stk809x_frontend_attach,
+                               .tuner_attach     = dib809x_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom STK8096GP reference design",
+                               { &dib0700_usb_id_table[67], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = dib90x0_pid_filter,
+                               .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
+                               .frontend_attach  = stk9090m_frontend_attach,
+                               .tuner_attach     = dib9090_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom STK9090M reference design",
+                               { &dib0700_usb_id_table[69], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk80xx_pid_filter,
+                               .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                               .frontend_attach  = nim8096md_frontend_attach,
+                               .tuner_attach     = nim8096md_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom NIM8096MD reference design",
+                               { &dib0700_usb_id_table[70], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = dib90x0_pid_filter,
+                               .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
+                               .frontend_attach  = nim9090md_frontend_attach,
+                               .tuner_attach     = nim9090md_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom NIM9090MD reference design",
+                               { &dib0700_usb_id_table[71], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk70x0p_pid_filter,
+                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = nim7090_frontend_attach,
+                               .tuner_attach     = nim7090_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom NIM7090 reference design",
+                               { &dib0700_usb_id_table[72], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk70x0p_pid_filter,
+                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = tfe7090pvr_frontend0_attach,
+                               .tuner_attach     = tfe7090pvr_tuner0_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                               .pid_filter_count = 32,
+                               .pid_filter = stk70x0p_pid_filter,
+                               .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+                               .frontend_attach  = tfe7090pvr_frontend1_attach,
+                               .tuner_attach     = tfe7090pvr_tuner1_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom TFE7090PVR reference design",
+                               { &dib0700_usb_id_table[73], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                       .num_frontends = 1,
+                       .fe = {{
+                               .frontend_attach  = pctv340e_frontend_attach,
+                               .tuner_attach     = xc4000_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }},
+                               .size_of_priv = sizeof(struct
+                                               dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 2,
+               .devices = {
+                       {   "Pinnacle PCTV 340e HD Pro USB Stick",
+                               { &dib0700_usb_id_table[76], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV Hybrid Stick Solo",
+                               { &dib0700_usb_id_table[77], NULL },
+                               { NULL },
+                       },
+               },
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .num_frontends = 1,
+                               .fe = {{
+                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                                       .pid_filter_count = 32,
+                                       .pid_filter = stk70x0p_pid_filter,
+                                       .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+                                       .frontend_attach  = tfe7090e_frontend_attach,
+                                       .tuner_attach     = tfe7090e_tuner_attach,
+
+                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                               } },
+
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom TFE7090E reference design",
+                               { &dib0700_usb_id_table[78], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .num_frontends = 1,
+                               .fe = {{
+                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                                       .pid_filter_count = 32,
+                                       .pid_filter = stk70x0p_pid_filter,
+                                       .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+                                       .frontend_attach  = tfe7790e_frontend_attach,
+                                       .tuner_attach     = tfe7790e_tuner_attach,
+
+                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                               } },
+
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom TFE7790E reference design",
+                               { &dib0700_usb_id_table[79], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .num_frontends = 1,
+                               .fe = {{
+                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                                       .pid_filter_count = 32,
+                                       .pid_filter = stk80xx_pid_filter,
+                                       .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                                       .frontend_attach  = tfe8096p_frontend_attach,
+                                       .tuner_attach     = tfe8096p_tuner_attach,
+
+                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+                               } },
+
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom TFE8096P reference design",
+                               { &dib0700_usb_id_table[80], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name      = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_TYPE_RC5 |
+                                           RC_TYPE_RC6 |
+                                           RC_TYPE_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
+       },
+};
+
+int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/usb/dvb-usb/dib07x0.h b/drivers/media/usb/dvb-usb/dib07x0.h
new file mode 100644 (file)
index 0000000..7e62c10
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _DIB07X0_H_
+#define _DIB07X0_H_
+
+enum dib07x0_gpios {
+       GPIO0  =  0,
+       GPIO1  =  2,
+       GPIO2  =  3,
+       GPIO3  =  4,
+       GPIO4  =  5,
+       GPIO5  =  6,
+       GPIO6  =  8,
+       GPIO7  = 10,
+       GPIO8  = 11,
+       GPIO9  = 14,
+       GPIO10 = 15,
+};
+
+#define GPIO_IN  0
+#define GPIO_OUT 1
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
new file mode 100644 (file)
index 0000000..a76bbb2
--- /dev/null
@@ -0,0 +1,479 @@
+/* Common methods for dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
+MODULE_LICENSE("GPL");
+
+#define deb_info(args...) dprintk(debug,0x01,args)
+
+/* common stuff used by the different dibusb modules */
+int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
+               if (st->ops.fifo_ctrl != NULL)
+                       if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) {
+                               err("error while controlling the fifo of the demod.");
+                               return -ENODEV;
+                       }
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dibusb_streaming_ctrl);
+
+int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
+{
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
+               if (st->ops.pid_ctrl != NULL)
+                       st->ops.pid_ctrl(adap->fe_adap[0].fe,
+                                        index, pid, onoff);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter);
+
+int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
+               if (st->ops.pid_parse != NULL)
+                       if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0)
+                               err("could not handle pid_parser");
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
+
+int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b[3];
+       int ret;
+       b[0] = DIBUSB_REQ_SET_IOCTL;
+       b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
+       b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
+       ret = dvb_usb_generic_write(d,b,3);
+       msleep(10);
+       return ret;
+}
+EXPORT_SYMBOL(dibusb_power_ctrl);
+
+int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       u8 b[3] = { 0 };
+       int ret;
+
+       if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
+               return ret;
+
+       if (onoff) {
+               b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
+               b[1] = 0x00;
+               if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
+                       return ret;
+       }
+
+       b[0] = DIBUSB_REQ_SET_IOCTL;
+       b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+       return dvb_usb_generic_write(adap->dev,b,3);
+}
+EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
+
+int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       if (onoff) {
+               u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
+               return dvb_usb_generic_write(d,b,3);
+       } else
+               return 0;
+}
+EXPORT_SYMBOL(dibusb2_0_power_ctrl);
+
+static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
+       /* write only ? */
+       int wo = (rbuf == NULL || rlen == 0),
+               len = 2 + wlen + (wo ? 0 : 2);
+
+       sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
+       sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
+
+       memcpy(&sndbuf[2],wbuf,wlen);
+
+       if (!wo) {
+               sndbuf[wlen+2] = (rlen >> 8) & 0xff;
+               sndbuf[wlen+3] = rlen & 0xff;
+       }
+
+       return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
+                                         && (msg[i+1].flags & I2C_M_RD)) {
+                       if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
+                                               msg[i+1].buf,msg[i+1].len) < 0)
+                               break;
+                       i++;
+               } else if ((msg[i].flags & I2C_M_RD) == 0) {
+                       if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
+                               break;
+               } else if (msg[i].addr != 0x50) {
+                       /* 0x50 is the address of the eeprom - we need to protect it
+                        * from dibusb's bad i2c implementation: reads without
+                        * writing the offset before are forbidden */
+                       if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
+                               break;
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dibusb_i2c_algo = {
+       .master_xfer   = dibusb_i2c_xfer,
+       .functionality = dibusb_i2c_func,
+};
+EXPORT_SYMBOL(dibusb_i2c_algo);
+
+int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
+{
+       u8 wbuf[1] = { offs };
+       return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+}
+EXPORT_SYMBOL(dibusb_read_eeprom_byte);
+
+/* 3000MC/P stuff */
+// Config Adjacent channels  Perf -cal22
+static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
+       .band_caps = BAND_VHF | BAND_UHF,
+       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
+
+       .agc1_max = 48497,
+       .agc1_min = 23593,
+       .agc2_max = 46531,
+       .agc2_min = 24904,
+
+       .agc1_pt1 = 0x65,
+       .agc1_pt2 = 0x69,
+
+       .agc1_slope1 = 0x51,
+       .agc1_slope2 = 0x27,
+
+       .agc2_pt1 = 0,
+       .agc2_pt2 = 0x33,
+
+       .agc2_slope1 = 0x35,
+       .agc2_slope2 = 0x37,
+};
+
+static struct dib3000mc_config stk3000p_dib3000p_config = {
+       &dib3000p_mt2060_agc_config,
+
+       .max_time     = 0x196,
+       .ln_adc_level = 0x1cc7,
+
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_command1 = 1,
+       .agc_command2 = 1,
+};
+
+static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
+       .band_caps = BAND_VHF | BAND_UHF,
+       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
+
+       .agc1_max = 56361,
+       .agc1_min = 22282,
+       .agc2_max = 47841,
+       .agc2_min = 36045,
+
+       .agc1_pt1 = 0x3b,
+       .agc1_pt2 = 0x6b,
+
+       .agc1_slope1 = 0x55,
+       .agc1_slope2 = 0x1d,
+
+       .agc2_pt1 = 0,
+       .agc2_pt2 = 0x0a,
+
+       .agc2_slope1 = 0x95,
+       .agc2_slope2 = 0x1e,
+};
+
+#if defined(CONFIG_DVB_DIB3000MC) ||                                   \
+       (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
+
+static struct dib3000mc_config mod3000p_dib3000p_config = {
+       &dib3000p_panasonic_agc_config,
+
+       .max_time     = 0x51,
+       .ln_adc_level = 0x1cc7,
+
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_command1 = 1,
+       .agc_command2 = 1,
+};
+
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+                       adap->dev->udev->descriptor.idProduct ==
+                       USB_PID_LITEON_DVB_T_WARM) {
+               msleep(1000);
+       }
+
+       adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
+                                        &adap->dev->i2c_adap,
+                                        DEFAULT_DIB3000P_I2C_ADDRESS,
+                                        &mod3000p_dib3000p_config);
+       if ((adap->fe_adap[0].fe) == NULL)
+               adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
+                                                &adap->dev->i2c_adap,
+                                                DEFAULT_DIB3000MC_I2C_ADDRESS,
+                                                &mod3000p_dib3000p_config);
+       if ((adap->fe_adap[0].fe) != NULL) {
+               if (adap->priv != NULL) {
+                       struct dibusb_state *st = adap->priv;
+                       st->ops.pid_parse = dib3000mc_pid_parse;
+                       st->ops.pid_ctrl  = dib3000mc_pid_control;
+               }
+               return 0;
+       }
+       return -ENODEV;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
+
+static struct mt2060_config stk3000p_mt2060_config = {
+       0x60
+};
+
+int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dibusb_state *st = adap->priv;
+       u8 a,b;
+       u16 if1 = 1220;
+       struct i2c_adapter *tun_i2c;
+
+       // First IF calibration for Liteon Sticks
+       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+               adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
+
+               dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
+               dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
+
+               if (a == 0x00)
+                       if1 += b;
+               else if (a == 0x80)
+                       if1 -= b;
+               else
+                       warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
+
+       } else if (adap->dev->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
+                  adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
+               u8 desc;
+               dibusb_read_eeprom_byte(adap->dev, 7, &desc);
+               if (desc == 2) {
+                       a = 127;
+                       do {
+                               dibusb_read_eeprom_byte(adap->dev, a, &desc);
+                               a--;
+                       } while (a > 7 && (desc == 0xff || desc == 0x00));
+                       if (desc & 0x80)
+                               if1 -= (0xff - desc);
+                       else
+                               if1 += desc;
+               }
+       }
+
+       tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
+       if (dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
+               /* not found - use panasonic pll parameters */
+               if (dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL)
+                       return -ENOMEM;
+       } else {
+               st->mt2060_present = 1;
+               /* set the correct parameters for the dib3000p */
+               dib3000mc_set_config(adap->fe_adap[0].fe, &stk3000p_dib3000p_config);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
+#endif
+
+/*
+ * common remote control stuff
+ */
+struct rc_map_table rc_map_dibusb_table[] = {
+       /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
+       { 0x0016, KEY_POWER },
+       { 0x0010, KEY_MUTE },
+       { 0x0003, KEY_1 },
+       { 0x0001, KEY_2 },
+       { 0x0006, KEY_3 },
+       { 0x0009, KEY_4 },
+       { 0x001d, KEY_5 },
+       { 0x001f, KEY_6 },
+       { 0x000d, KEY_7 },
+       { 0x0019, KEY_8 },
+       { 0x001b, KEY_9 },
+       { 0x0015, KEY_0 },
+       { 0x0005, KEY_CHANNELUP },
+       { 0x0002, KEY_CHANNELDOWN },
+       { 0x001e, KEY_VOLUMEUP },
+       { 0x000a, KEY_VOLUMEDOWN },
+       { 0x0011, KEY_RECORD },
+       { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+       { 0x0014, KEY_PLAY },
+       { 0x001a, KEY_STOP },
+       { 0x0040, KEY_REWIND },
+       { 0x0012, KEY_FASTFORWARD },
+       { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+       { 0x004c, KEY_PAUSE },
+       { 0x004d, KEY_SCREEN }, /* Full screen mode. */
+       { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+       /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
+       { 0x000c, KEY_CANCEL }, /* Cancel */
+       { 0x001c, KEY_EPG }, /* EPG */
+       { 0x0000, KEY_TAB }, /* Tab */
+       { 0x0048, KEY_INFO }, /* Preview */
+       { 0x0004, KEY_LIST }, /* RecordList */
+       { 0x000f, KEY_TEXT }, /* Teletext */
+       /* Key codes for the KWorld/ADSTech/JetWay remote. */
+       { 0x8612, KEY_POWER },
+       { 0x860f, KEY_SELECT }, /* source */
+       { 0x860c, KEY_UNKNOWN }, /* scan */
+       { 0x860b, KEY_EPG },
+       { 0x8610, KEY_MUTE },
+       { 0x8601, KEY_1 },
+       { 0x8602, KEY_2 },
+       { 0x8603, KEY_3 },
+       { 0x8604, KEY_4 },
+       { 0x8605, KEY_5 },
+       { 0x8606, KEY_6 },
+       { 0x8607, KEY_7 },
+       { 0x8608, KEY_8 },
+       { 0x8609, KEY_9 },
+       { 0x860a, KEY_0 },
+       { 0x8618, KEY_ZOOM },
+       { 0x861c, KEY_UNKNOWN }, /* preview */
+       { 0x8613, KEY_UNKNOWN }, /* snap */
+       { 0x8600, KEY_UNDO },
+       { 0x861d, KEY_RECORD },
+       { 0x860d, KEY_STOP },
+       { 0x860e, KEY_PAUSE },
+       { 0x8616, KEY_PLAY },
+       { 0x8611, KEY_BACK },
+       { 0x8619, KEY_FORWARD },
+       { 0x8614, KEY_UNKNOWN }, /* pip */
+       { 0x8615, KEY_ESC },
+       { 0x861a, KEY_UP },
+       { 0x861e, KEY_DOWN },
+       { 0x861f, KEY_LEFT },
+       { 0x861b, KEY_RIGHT },
+
+       /* Key codes for the DiBcom MOD3000 remote. */
+       { 0x8000, KEY_MUTE },
+       { 0x8001, KEY_TEXT },
+       { 0x8002, KEY_HOME },
+       { 0x8003, KEY_POWER },
+
+       { 0x8004, KEY_RED },
+       { 0x8005, KEY_GREEN },
+       { 0x8006, KEY_YELLOW },
+       { 0x8007, KEY_BLUE },
+
+       { 0x8008, KEY_DVD },
+       { 0x8009, KEY_AUDIO },
+       { 0x800a, KEY_IMAGES },      /* Pictures */
+       { 0x800b, KEY_VIDEO },
+
+       { 0x800c, KEY_BACK },
+       { 0x800d, KEY_UP },
+       { 0x800e, KEY_RADIO },
+       { 0x800f, KEY_EPG },
+
+       { 0x8010, KEY_LEFT },
+       { 0x8011, KEY_OK },
+       { 0x8012, KEY_RIGHT },
+       { 0x8013, KEY_UNKNOWN },    /* SAP */
+
+       { 0x8014, KEY_TV },
+       { 0x8015, KEY_DOWN },
+       { 0x8016, KEY_MENU },       /* DVD Menu */
+       { 0x8017, KEY_LAST },
+
+       { 0x8018, KEY_RECORD },
+       { 0x8019, KEY_STOP },
+       { 0x801a, KEY_PAUSE },
+       { 0x801b, KEY_PLAY },
+
+       { 0x801c, KEY_PREVIOUS },
+       { 0x801d, KEY_REWIND },
+       { 0x801e, KEY_FASTFORWARD },
+       { 0x801f, KEY_NEXT},
+
+       { 0x8040, KEY_1 },
+       { 0x8041, KEY_2 },
+       { 0x8042, KEY_3 },
+       { 0x8043, KEY_CHANNELUP },
+
+       { 0x8044, KEY_4 },
+       { 0x8045, KEY_5 },
+       { 0x8046, KEY_6 },
+       { 0x8047, KEY_CHANNELDOWN },
+
+       { 0x8048, KEY_7 },
+       { 0x8049, KEY_8 },
+       { 0x804a, KEY_9 },
+       { 0x804b, KEY_VOLUMEUP },
+
+       { 0x804c, KEY_CLEAR },
+       { 0x804d, KEY_0 },
+       { 0x804e, KEY_ENTER },
+       { 0x804f, KEY_VOLUMEDOWN },
+};
+EXPORT_SYMBOL(rc_map_dibusb_table);
+
+int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
+       dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+       dvb_usb_nec_rc_key_to_event(d,key,event,state);
+       if (key[0] != 0)
+               deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+       return 0;
+}
+EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
new file mode 100644 (file)
index 0000000..a4ac37e
--- /dev/null
@@ -0,0 +1,471 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dibusb_state *st = adap->priv;
+
+       return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
+}
+
+static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib3000_config demod_cfg;
+       struct dibusb_state *st = adap->priv;
+
+       demod_cfg.demod_address = 0x8;
+
+       adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
+                                        &adap->dev->i2c_adap, &st->ops);
+       if ((adap->fe_adap[0].fe) == NULL)
+               return -ENODEV;
+
+       adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
+
+       return 0;
+}
+
+static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dibusb_state *st = adap->priv;
+
+       st->tuner_addr = 0x61;
+
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
+                  DVB_PLL_TUA6010XS);
+       return 0;
+}
+
+static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dibusb_state *st = adap->priv;
+
+       st->tuner_addr = 0x60;
+
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
+                  DVB_PLL_TDA665X);
+       return 0;
+}
+
+/* Some of the Artec 1.1 device aren't equipped with the default tuner
+ * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
+ * this out. */
+static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
+{
+       u8 b[2] = { 0,0 }, b2[1];
+       int ret = 0;
+       struct i2c_msg msg[2] = {
+               { .flags = 0,        .buf = b,  .len = 2 },
+               { .flags = I2C_M_RD, .buf = b2, .len = 1 },
+       };
+       struct dibusb_state *st = adap->priv;
+
+       /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
+       msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
+
+       if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
+               adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
+
+       if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
+               err("tuner i2c write failed.");
+               ret = -EREMOTEIO;
+       }
+
+       if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
+               adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
+
+       if (b2[0] == 0xfe) {
+               info("This device has the Thomson Cable onboard. Which is default.");
+               ret = dibusb_thomson_tuner_attach(adap);
+       } else {
+               info("This device has the Panasonic ENV77H11D5 onboard.");
+               ret = dibusb_panasonic_tuner_attach(adap);
+       }
+
+       return ret;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_device_properties dibusb1_1_properties;
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
+static struct dvb_usb_device_properties dibusb2_0b_properties;
+static struct dvb_usb_device_properties artec_t1_usb2_properties;
+
+static int dibusb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return 0;
+
+       return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mb_table [] = {
+/* 00 */       { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_COLD) },
+/* 01 */       { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_WARM) },
+/* 02 */       { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_COLD) },
+/* 03 */       { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_WARM) },
+/* 04 */       { USB_DEVICE(USB_VID_COMPRO_UNK,        USB_PID_COMPRO_DVBU2000_UNK_COLD) },
+/* 05 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_COLD) },
+/* 06 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_WARM) },
+/* 07 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_COLD) },
+/* 08 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_WARM) },
+/* 09 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_COLD) },
+/* 10 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_WARM) },
+/* 11 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_COLD) },
+/* 12 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_WARM) },
+/* 13 */       { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_COLD) },
+/* 14 */       { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_WARM) },
+/* 15 */       { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_COLD) },
+/* 16 */       { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_WARM) },
+/* 17 */       { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_COLD) },
+/* 18 */       { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_WARM) },
+/* 19 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
+/* 20 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
+/* 21 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+/* 22 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+/* 23 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_COLD) },
+
+/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
+/* 24 */       { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_WARM) },
+/* 25 */       { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_COLD) },
+/* 26 */       { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_WARM) },
+
+/* 27 */       { USB_DEVICE(USB_VID_KWORLD,            USB_PID_KWORLD_VSTREAM_COLD) },
+
+/* 28 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+/* 29 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
+
+/*
+ * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
+ *      we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
+ *      have been left on the device. If you don't have such a device but an Artec
+ *      device that's supposed to work with this driver but is not detected by it,
+ *      free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
+ */
+
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
+/* 30 */       { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+#endif
+
+                       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
+
+static struct dvb_usb_device_properties dibusb1_1_properties = {
+       .caps =  DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_AN2135,
+
+       .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
+
+                       .streaming_ctrl   = dibusb_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
+                       .tuner_attach     = dibusb_tuner_probe_and_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_dibusb_table,
+               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+               .rc_query         = dibusb_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 9,
+       .devices = {
+               {       "AVerMedia AverTV DVBT USB1.1",
+                       { &dibusb_dib3000mb_table[0],  NULL },
+                       { &dibusb_dib3000mb_table[1],  NULL },
+               },
+               {       "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
+                       { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
+                       { &dibusb_dib3000mb_table[3], NULL },
+               },
+               {       "DiBcom USB1.1 DVB-T reference design (MOD3000)",
+                       { &dibusb_dib3000mb_table[5],  NULL },
+                       { &dibusb_dib3000mb_table[6],  NULL },
+               },
+               {       "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
+                       { &dibusb_dib3000mb_table[7], NULL },
+                       { &dibusb_dib3000mb_table[8], NULL },
+               },
+               {       "Grandtec USB1.1 DVB-T",
+                       { &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
+                       { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
+               },
+               {       "Unknown USB1.1 DVB-T device ???? please report the name to the author",
+                       { &dibusb_dib3000mb_table[13], NULL },
+                       { &dibusb_dib3000mb_table[14], NULL },
+               },
+               {       "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
+                       { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
+                       { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
+               },
+               {       "Artec T1 USB1.1 TVBOX with AN2135",
+                       { &dibusb_dib3000mb_table[19], NULL },
+                       { &dibusb_dib3000mb_table[20], NULL },
+               },
+               {       "VideoWalker DVB-T USB",
+                       { &dibusb_dib3000mb_table[25], NULL },
+                       { &dibusb_dib3000mb_table[26], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = CYPRESS_AN2235,
+
+       .firmware = "dvb-usb-dibusb-an2235-01.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
+                       .pid_filter_count = 16,
+
+                       .streaming_ctrl   = dibusb_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
+                       .tuner_attach     = dibusb_tuner_probe_and_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               },
+       },
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_dibusb_table,
+               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+               .rc_query         = dibusb_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
+       .num_device_descs = 2,
+#else
+       .num_device_descs = 1,
+#endif
+       .devices = {
+               {       "Artec T1 USB1.1 TVBOX with AN2235",
+                       { &dibusb_dib3000mb_table[21], NULL },
+                       { &dibusb_dib3000mb_table[22], NULL },
+               },
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
+               {       "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
+                       { &dibusb_dib3000mb_table[30], NULL },
+                       { NULL },
+               },
+               { NULL },
+#endif
+       }
+};
+
+static struct dvb_usb_device_properties dibusb2_0b_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+
+       .firmware = "dvb-usb-adstech-usb2-02.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
+
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
+                       .tuner_attach     = dibusb_thomson_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_dibusb_table,
+               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+               .rc_query         = dibusb_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 2,
+       .devices = {
+               {       "KWorld/ADSTech Instant DVB-T USB2.0",
+                       { &dibusb_dib3000mb_table[23], NULL },
+                       { &dibusb_dib3000mb_table[24], NULL },
+               },
+               {       "KWorld Xpert DVB-T USB2.0",
+                       { &dibusb_dib3000mb_table[27], NULL },
+                       { NULL }
+               },
+               { NULL },
+       }
+};
+
+static struct dvb_usb_device_properties artec_t1_usb2_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+
+       .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
+
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mb_frontend_attach,
+                       .tuner_attach     = dibusb_tuner_probe_and_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_dibusb_table,
+               .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+               .rc_query         = dibusb_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {       "Artec T1 USB2.0",
+                       { &dibusb_dib3000mb_table[28], NULL },
+                       { &dibusb_dib3000mb_table[29], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct usb_driver dibusb_driver = {
+       .name           = "dvb_usb_dibusb_mb",
+       .probe          = dibusb_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = dibusb_dib3000mb_table,
+};
+
+module_usb_driver(dibusb_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
new file mode 100644 (file)
index 0000000..9d1a59d
--- /dev/null
@@ -0,0 +1,149 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* USB Driver stuff */
+static struct dvb_usb_device_properties dibusb_mc_properties;
+
+static int dibusb_mc_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE,
+                                  NULL, adapter_nr);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mc_table [] = {
+/* 00 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3001_COLD) },
+/* 01 */       { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3001_WARM) },
+/* 02 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+/* 03 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
+/* 04 */       { USB_DEVICE(USB_VID_LITEON,            USB_PID_LITEON_DVB_T_COLD) },
+/* 05 */       { USB_DEVICE(USB_VID_LITEON,            USB_PID_LITEON_DVB_T_WARM) },
+/* 06 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_DIGIVOX_MINI_SL_COLD) },
+/* 07 */       { USB_DEVICE(USB_VID_EMPIA,             USB_PID_DIGIVOX_MINI_SL_WARM) },
+/* 08 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB2_COLD) },
+/* 09 */       { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB2_WARM) },
+/* 10 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
+/* 11 */       { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
+/* 12 */       { USB_DEVICE(USB_VID_LEADTEK,           USB_PID_WINFAST_DTV_DONGLE_COLD) },
+/* 13 */       { USB_DEVICE(USB_VID_LEADTEK,           USB_PID_WINFAST_DTV_DONGLE_WARM) },
+/* 14 */       { USB_DEVICE(USB_VID_HUMAX_COEX,        USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
+/* 15 */       { USB_DEVICE(USB_VID_HUMAX_COEX,        USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
+                       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
+
+static struct dvb_usb_device_properties dibusb_mc_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
+                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_map_table     = rc_map_dibusb_table,
+               .rc_map_size      = 111, /* FIXME */
+               .rc_query         = dibusb_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 8,
+       .devices = {
+               {   "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
+                       { &dibusb_dib3000mc_table[0], NULL },
+                       { &dibusb_dib3000mc_table[1], NULL },
+               },
+               {   "Artec T1 USB2.0 TVBOX (please check the warm ID)",
+                       { &dibusb_dib3000mc_table[2], NULL },
+                       { &dibusb_dib3000mc_table[3], NULL },
+               },
+               {   "LITE-ON USB2.0 DVB-T Tuner",
+                   /* Also rebranded as Intuix S800, Toshiba */
+                       { &dibusb_dib3000mc_table[4], NULL },
+                       { &dibusb_dib3000mc_table[5], NULL },
+               },
+               {   "MSI Digivox Mini SL",
+                       { &dibusb_dib3000mc_table[6], NULL },
+                       { &dibusb_dib3000mc_table[7], NULL },
+               },
+               {   "GRAND - USB2.0 DVB-T adapter",
+                       { &dibusb_dib3000mc_table[8], NULL },
+                       { &dibusb_dib3000mc_table[9], NULL },
+               },
+               {   "Artec T14 - USB2.0 DVB-T",
+                       { &dibusb_dib3000mc_table[10], NULL },
+                       { &dibusb_dib3000mc_table[11], NULL },
+               },
+               {   "Leadtek - USB2.0 Winfast DTV dongle",
+                       { &dibusb_dib3000mc_table[12], NULL },
+                       { &dibusb_dib3000mc_table[13], NULL },
+               },
+               {   "Humax/Coex DVB-T USB Stick 2.0 High Speed",
+                       { &dibusb_dib3000mc_table[14], NULL },
+                       { &dibusb_dib3000mc_table[15], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct usb_driver dibusb_mc_driver = {
+       .name           = "dvb_usb_dibusb_mc",
+       .probe          = dibusb_mc_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = dibusb_dib3000mc_table,
+};
+
+module_usb_driver(dibusb_mc_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
new file mode 100644 (file)
index 0000000..e47c321
--- /dev/null
@@ -0,0 +1,131 @@
+/* Header file for all dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DIBUSB_H_
+#define _DVB_USB_DIBUSB_H_
+
+#ifndef DVB_USB_LOG_PREFIX
+ #define DVB_USB_LOG_PREFIX "dibusb"
+#endif
+#include "dvb-usb.h"
+
+#include "dib3000.h"
+#include "dib3000mc.h"
+#include "mt2060.h"
+
+/*
+ * protocol of all dibusb related devices
+ */
+
+/*
+ * bulk msg to/from endpoint 0x01
+ *
+ * general structure:
+ * request_byte parameter_bytes
+ */
+
+#define DIBUSB_REQ_START_READ                  0x00
+#define DIBUSB_REQ_START_DEMOD                 0x01
+
+/*
+ * i2c read
+ * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
+ * bulk read:  byte_buffer (length_word bytes)
+ */
+#define DIBUSB_REQ_I2C_READ                    0x02
+
+/*
+ * i2c write
+ * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
+ */
+#define DIBUSB_REQ_I2C_WRITE                   0x03
+
+/*
+ * polling the value of the remote control
+ * bulk write: 0x04
+ * bulk read:  byte_buffer (5 bytes)
+ */
+#define DIBUSB_REQ_POLL_REMOTE       0x04
+
+/* additional status values for Hauppauge Remote Control Protocol */
+#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED        0x01
+#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY  0x03
+
+/* streaming mode:
+ * bulk write: 0x05 mode_byte
+ *
+ * mode_byte is mostly 0x00
+ */
+#define DIBUSB_REQ_SET_STREAMING_MODE  0x05
+
+/* interrupt the internal read loop, when blocking */
+#define DIBUSB_REQ_INTR_READ                   0x06
+
+/* io control
+ * 0x07 cmd_byte param_bytes
+ *
+ * param_bytes can be up to 32 bytes
+ *
+ * cmd_byte function    parameter name
+ * 0x00     power mode
+ *                      0x00      sleep
+ *                      0x01      wakeup
+ *
+ * 0x01     enable streaming
+ * 0x02     disable streaming
+ *
+ *
+ */
+#define DIBUSB_REQ_SET_IOCTL                   0x07
+
+/* IOCTL commands */
+
+/* change the power mode in firmware */
+#define DIBUSB_IOCTL_CMD_POWER_MODE            0x00
+#define DIBUSB_IOCTL_POWER_SLEEP                       0x00
+#define DIBUSB_IOCTL_POWER_WAKEUP                      0x01
+
+/* modify streaming of the FX2 */
+#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
+#define DIBUSB_IOCTL_CMD_DISABLE_STREAM        0x02
+
+struct dibusb_state {
+       struct dib_fe_xfer_ops ops;
+       int mt2060_present;
+       u8 tuner_addr;
+};
+
+struct dibusb_device_state {
+       /* for RC5 remote control */
+       int old_toggle;
+       int last_repeat_count;
+};
+
+extern struct i2c_algorithm dibusb_i2c_algo;
+
+extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
+extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
+
+extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
+extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
+
+extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
+extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
+
+#define DEFAULT_RC_INTERVAL 150
+//#define DEFAULT_RC_INTERVAL 100000
+
+extern struct rc_map_table rc_map_dibusb_table[];
+extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
+extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
new file mode 100644 (file)
index 0000000..ff34419
--- /dev/null
@@ -0,0 +1,354 @@
+/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
+ * receiver
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * partly based on the SDK published by Nebula Electronics
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "digitv.h"
+
+#include "mt352.h"
+#include "nxt6000.h"
+
+/* debug */
+static int dvb_usb_digitv_debug;
+module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_rc(args...)   dprintk(dvb_usb_digitv_debug,0x01,args)
+
+static int digitv_ctrl_msg(struct dvb_usb_device *d,
+               u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       int wo = (rbuf == NULL || rlen == 0); /* write-only */
+       u8 sndbuf[7],rcvbuf[7];
+       memset(sndbuf,0,7); memset(rcvbuf,0,7);
+
+       sndbuf[0] = cmd;
+       sndbuf[1] = vv;
+       sndbuf[2] = wo ? wlen : rlen;
+
+       if (wo) {
+               memcpy(&sndbuf[3],wbuf,wlen);
+               dvb_usb_generic_write(d,sndbuf,7);
+       } else {
+               dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
+               memcpy(rbuf,&rcvbuf[3],rlen);
+       }
+       return 0;
+}
+
+/* I2C */
+static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       if (num > 2)
+               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
+                                               msg[i+1].buf,msg[i+1].len) < 0)
+                               break;
+                       i++;
+               } else
+                       if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
+                                               &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 digitv_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm digitv_i2c_algo = {
+       .master_xfer   = digitv_i2c_xfer,
+       .functionality = digitv_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int digitv_identify_state (struct usb_device *udev, struct
+               dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
+               int *cold)
+{
+       *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
+       return 0;
+}
+
+static int digitv_mt352_demod_init(struct dvb_frontend *fe)
+{
+       static u8 reset_buf[] = { 0x89, 0x38,  0x8a, 0x2d, 0x50, 0x80 };
+       static u8 init_buf[] = { 0x68, 0xa0,  0x8e, 0x40,  0x53, 0x50,
+                       0x67, 0x20,  0x7d, 0x01,  0x7c, 0x00,  0x7a, 0x00,
+                       0x79, 0x20,  0x57, 0x05,  0x56, 0x31,  0x88, 0x0f,
+                       0x75, 0x32 };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
+               mt352_write(fe, &reset_buf[i], 2);
+
+       msleep(1);
+
+       for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
+               mt352_write(fe, &init_buf[i], 2);
+
+       return 0;
+}
+
+static struct mt352_config digitv_mt352_config = {
+       .demod_init = digitv_mt352_demod_init,
+};
+
+static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       u8 b[5];
+
+       fe->ops.tuner_ops.calc_regs(fe, b, sizeof(b));
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
+}
+
+static struct nxt6000_config digitv_nxt6000_config = {
+       .clock_inversion = 1,
+};
+
+static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct digitv_state *st = adap->dev->priv;
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &digitv_mt352_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL) {
+               st->is_nxt6000 = 0;
+               return 0;
+       }
+       adap->fe_adap[0].fe = dvb_attach(nxt6000_attach,
+                                        &digitv_nxt6000_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) != NULL) {
+               st->is_nxt6000 = 1;
+               return 0;
+       }
+       return -EIO;
+}
+
+static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct digitv_state *st = adap->dev->priv;
+
+       if (!dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_TDED4))
+               return -ENODEV;
+
+       if (st->is_nxt6000)
+               adap->fe_adap[0].fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
+
+       return 0;
+}
+
+static struct rc_map_table rc_map_digitv_table[] = {
+       { 0x5f55, KEY_0 },
+       { 0x6f55, KEY_1 },
+       { 0x9f55, KEY_2 },
+       { 0xaf55, KEY_3 },
+       { 0x5f56, KEY_4 },
+       { 0x6f56, KEY_5 },
+       { 0x9f56, KEY_6 },
+       { 0xaf56, KEY_7 },
+       { 0x5f59, KEY_8 },
+       { 0x6f59, KEY_9 },
+       { 0x9f59, KEY_TV },
+       { 0xaf59, KEY_AUX },
+       { 0x5f5a, KEY_DVD },
+       { 0x6f5a, KEY_POWER },
+       { 0x9f5a, KEY_CAMERA },     /* labelled 'Picture' */
+       { 0xaf5a, KEY_AUDIO },
+       { 0x5f65, KEY_INFO },
+       { 0x6f65, KEY_F13 },     /* 16:9 */
+       { 0x9f65, KEY_F14 },     /* 14:9 */
+       { 0xaf65, KEY_EPG },
+       { 0x5f66, KEY_EXIT },
+       { 0x6f66, KEY_MENU },
+       { 0x9f66, KEY_UP },
+       { 0xaf66, KEY_DOWN },
+       { 0x5f69, KEY_LEFT },
+       { 0x6f69, KEY_RIGHT },
+       { 0x9f69, KEY_ENTER },
+       { 0xaf69, KEY_CHANNELUP },
+       { 0x5f6a, KEY_CHANNELDOWN },
+       { 0x6f6a, KEY_VOLUMEUP },
+       { 0x9f6a, KEY_VOLUMEDOWN },
+       { 0xaf6a, KEY_RED },
+       { 0x5f95, KEY_GREEN },
+       { 0x6f95, KEY_YELLOW },
+       { 0x9f95, KEY_BLUE },
+       { 0xaf95, KEY_SUBTITLE },
+       { 0x5f96, KEY_F15 },     /* AD */
+       { 0x6f96, KEY_TEXT },
+       { 0x9f96, KEY_MUTE },
+       { 0xaf96, KEY_REWIND },
+       { 0x5f99, KEY_STOP },
+       { 0x6f99, KEY_PLAY },
+       { 0x9f99, KEY_FASTFORWARD },
+       { 0xaf99, KEY_F16 },     /* chapter */
+       { 0x5f9a, KEY_PAUSE },
+       { 0x6f9a, KEY_PLAY },
+       { 0x9f9a, KEY_RECORD },
+       { 0xaf9a, KEY_F17 },     /* picture in picture */
+       { 0x5fa5, KEY_KPPLUS },  /* zoom in */
+       { 0x6fa5, KEY_KPMINUS }, /* zoom out */
+       { 0x9fa5, KEY_F18 },     /* capture */
+       { 0xafa5, KEY_F19 },     /* web */
+       { 0x5fa6, KEY_EMAIL },
+       { 0x6fa6, KEY_PHONE },
+       { 0x9fa6, KEY_PC },
+};
+
+static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       int i;
+       u8 key[5];
+       u8 b[4] = { 0 };
+
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+
+       digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
+
+       /* Tell the device we've read the remote. Not sure how necessary
+          this is, but the Nebula SDK does it. */
+       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+
+       /* if something is inside the buffer, simulate key press */
+       if (key[1] != 0)
+       {
+                 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+                       if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
+                           rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
+                               *event = d->props.rc.legacy.rc_map_table[i].keycode;
+                               *state = REMOTE_KEY_PRESSED;
+                               return 0;
+                       }
+               }
+       }
+
+       if (key[0] != 0)
+               deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+       return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties digitv_properties;
+
+static int digitv_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct dvb_usb_device *d;
+       int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
+                                     adapter_nr);
+       if (ret == 0) {
+               u8 b[4] = { 0 };
+
+               if (d != NULL) { /* do that only when the firmware is loaded */
+                       b[0] = 1;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+
+                       b[0] = 0;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+               }
+       }
+       return ret;
+}
+
+static struct usb_device_id digitv_table [] = {
+               { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
+               { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, digitv_table);
+
+static struct dvb_usb_device_properties digitv_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-digitv-02.fw",
+
+       .size_of_priv = sizeof(struct digitv_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach  = digitv_frontend_attach,
+                       .tuner_attach     = digitv_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .identify_state   = digitv_identify_state,
+
+       .rc.legacy = {
+               .rc_interval      = 1000,
+               .rc_map_table     = rc_map_digitv_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_digitv_table),
+               .rc_query         = digitv_rc_query,
+       },
+
+       .i2c_algo         = &digitv_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Nebula Electronics uDigiTV DVB-T USB2.0)",
+                       { &digitv_table[0], NULL },
+                       { NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct usb_driver digitv_driver = {
+       .name           = "dvb_usb_digitv",
+       .probe          = digitv_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = digitv_table,
+};
+
+module_usb_driver(digitv_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
new file mode 100644 (file)
index 0000000..908c09f
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef _DVB_USB_DIGITV_H_
+#define _DVB_USB_DIGITV_H_
+
+#define DVB_USB_LOG_PREFIX "digitv"
+#include "dvb-usb.h"
+
+struct digitv_state {
+    int is_nxt6000;
+};
+
+/* protocol (from usblogging and the SDK:
+ *
+ * Always 7 bytes bulk message(s) for controlling
+ *
+ * First byte describes the command. Reads are 2 consecutive transfer (as always).
+ *
+ * General structure:
+ *
+ * write or first message of a read:
+ * <cmdbyte> VV <len> B0 B1 B2 B3
+ *
+ * second message of a read
+ * <cmdbyte> VV <len> R0 R1 R2 R3
+ *
+ * whereas 0 < len <= 4
+ *
+ * I2C address is stored somewhere inside the device.
+ *
+ * 0x01 read from EEPROM
+ *  VV = offset; B* = 0; R* = value(s)
+ *
+ * 0x02 read register of the COFDM
+ *  VV = register; B* = 0; R* = value(s)
+ *
+ * 0x05 write register of the COFDM
+ *  VV = register; B* = value(s);
+ *
+ * 0x06 write to the tuner (only for NXT6000)
+ *  VV = 0; B* = PLL data; len = 4;
+ *
+ * 0x03 read remote control
+ *  VV = 0; B* = 0; len = 4; R* = key
+ *
+ * 0x07 write to the remote (don't know why one should this, resetting ?)
+ *  VV = 0; B* = key; len = 4;
+ *
+ * 0x08 write remote type
+ *  VV = 0; B[0] = 0x01, len = 4
+ *
+ * 0x09 write device init
+ *  TODO
+ */
+#define USB_READ_EEPROM         1
+
+#define USB_READ_COFDM          2
+#define USB_WRITE_COFDM         5
+
+#define USB_WRITE_TUNER         6
+
+#define USB_READ_REMOTE         3
+#define USB_WRITE_REMOTE        7
+#define USB_WRITE_REMOTE_TYPE   8
+
+#define USB_DEV_INIT            9
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
new file mode 100644 (file)
index 0000000..3d81daa
--- /dev/null
@@ -0,0 +1,210 @@
+/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dtt200u.h"
+
+struct dtt200u_fe_state {
+       struct dvb_usb_device *d;
+
+       fe_status_t stat;
+
+       struct dtv_frontend_properties fep;
+       struct dvb_frontend frontend;
+};
+
+static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 st = GET_TUNE_STATUS, b[3];
+
+       dvb_usb_generic_rw(state->d,&st,1,b,3,0);
+
+       switch (b[0]) {
+               case 0x01:
+                       *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+                       break;
+               case 0x00: /* pending */
+                       *stat = FE_TIMEDOUT; /* during set_frontend */
+                       break;
+               default:
+               case 0x02: /* failed */
+                       *stat = 0;
+                       break;
+       }
+       return 0;
+}
+
+static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 bw = GET_VIT_ERR_CNT,b[3];
+       dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
+       *ber = (b[0] << 16) | (b[1] << 8) | b[2];
+       return 0;
+}
+
+static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
+
+       dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
+       *unc = (b[0] << 8) | b[1];
+       return 0;
+}
+
+static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 bw = GET_AGC, b;
+       dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
+       *strength = (b << 8) | b;
+       return 0;
+}
+
+static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 bw = GET_SNR,br;
+       dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
+       *snr = ~((br << 8) | br);
+       return 0;
+}
+
+static int dtt200u_fe_init(struct dvb_frontend* fe)
+{
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       u8 b = SET_INIT;
+       return dvb_usb_generic_write(state->d,&b,1);
+}
+
+static int dtt200u_fe_sleep(struct dvb_frontend* fe)
+{
+       return dtt200u_fe_init(fe);
+}
+
+static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1500;
+       tune->step_size = 0;
+       tune->max_drift = 0;
+       return 0;
+}
+
+static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       int i;
+       fe_status_t st;
+       u16 freq = fep->frequency / 250000;
+       u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
+
+       switch (fep->bandwidth_hz) {
+       case 8000000:
+               bwbuf[1] = 8;
+               break;
+       case 7000000:
+               bwbuf[1] = 7;
+               break;
+       case 6000000:
+               bwbuf[1] = 6;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dvb_usb_generic_write(state->d,bwbuf,2);
+
+       freqbuf[1] = freq & 0xff;
+       freqbuf[2] = (freq >> 8) & 0xff;
+       dvb_usb_generic_write(state->d,freqbuf,3);
+
+       for (i = 0; i < 30; i++) {
+               msleep(20);
+               dtt200u_fe_read_status(fe, &st);
+               if (st & FE_TIMEDOUT)
+                       continue;
+       }
+
+       return 0;
+}
+
+static int dtt200u_fe_get_frontend(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dtt200u_fe_state *state = fe->demodulator_priv;
+       memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties));
+       return 0;
+}
+
+static void dtt200u_fe_release(struct dvb_frontend* fe)
+{
+       struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops dtt200u_fe_ops;
+
+struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
+{
+       struct dtt200u_fe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       deb_info("attaching frontend dtt200u\n");
+
+       state->d = d;
+
+       memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       return NULL;
+}
+
+static struct dvb_frontend_ops dtt200u_fe_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "WideView USB DVB-T",
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 250000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                               FE_CAN_TRANSMISSION_MODE_AUTO |
+                               FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_RECOVER |
+                               FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = dtt200u_fe_release,
+
+       .init = dtt200u_fe_init,
+       .sleep = dtt200u_fe_sleep,
+
+       .set_frontend = dtt200u_fe_set_frontend,
+       .get_frontend = dtt200u_fe_get_frontend,
+       .get_tune_settings = dtt200u_fe_get_tune_settings,
+
+       .read_status = dtt200u_fe_read_status,
+       .read_ber = dtt200u_fe_read_ber,
+       .read_signal_strength = dtt200u_fe_read_signal_strength,
+       .read_snr = dtt200u_fe_read_snr,
+       .read_ucblocks = dtt200u_fe_read_unc_blocks,
+};
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
new file mode 100644 (file)
index 0000000..66f205c
--- /dev/null
@@ -0,0 +1,368 @@
+/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Steve Chang from WideView for providing support for the WT-220U.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dtt200u.h"
+
+/* debug */
+int dvb_usb_dtt200u_debug;
+module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b = SET_INIT;
+
+       if (onoff)
+               dvb_usb_generic_write(d,&b,2);
+
+       return 0;
+}
+
+static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       u8 b_streaming[2] = { SET_STREAMING, onoff };
+       u8 b_rst_pid = RESET_PID_FILTER;
+
+       dvb_usb_generic_write(adap->dev, b_streaming, 2);
+
+       if (onoff == 0)
+               dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
+       return 0;
+}
+
+static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
+{
+       u8 b_pid[4];
+       pid = onoff ? pid : 0;
+
+       b_pid[0] = SET_PID_FILTER;
+       b_pid[1] = index;
+       b_pid[2] = pid & 0xff;
+       b_pid[3] = (pid >> 8) & 0x1f;
+
+       return dvb_usb_generic_write(adap->dev, b_pid, 4);
+}
+
+/* remote control */
+/* key list for the tiny remote control (Yakumo, don't know about the others) */
+static struct rc_map_table rc_map_dtt200u_table[] = {
+       { 0x8001, KEY_MUTE },
+       { 0x8002, KEY_CHANNELDOWN },
+       { 0x8003, KEY_VOLUMEDOWN },
+       { 0x8004, KEY_1 },
+       { 0x8005, KEY_2 },
+       { 0x8006, KEY_3 },
+       { 0x8007, KEY_4 },
+       { 0x8008, KEY_5 },
+       { 0x8009, KEY_6 },
+       { 0x800a, KEY_7 },
+       { 0x800c, KEY_ZOOM },
+       { 0x800d, KEY_0 },
+       { 0x800e, KEY_SELECT },
+       { 0x8012, KEY_POWER },
+       { 0x801a, KEY_CHANNELUP },
+       { 0x801b, KEY_8 },
+       { 0x801e, KEY_VOLUMEUP },
+       { 0x801f, KEY_9 },
+};
+
+static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 key[5],cmd = GET_RC_CODE;
+       dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+       dvb_usb_nec_rc_key_to_event(d,key,event,state);
+       if (key[0] != 0)
+               deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+       return 0;
+}
+
+static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev);
+       return 0;
+}
+
+static struct dvb_usb_device_properties dtt200u_properties;
+static struct dvb_usb_device_properties wt220u_fc_properties;
+static struct dvb_usb_device_properties wt220u_properties;
+static struct dvb_usb_device_properties wt220u_zl0353_properties;
+static struct dvb_usb_device_properties wt220u_miglia_properties;
+
+static int dtt200u_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &wt220u_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return 0;
+
+       return -ENODEV;
+}
+
+static struct usb_device_id dtt200u_usb_table [] = {
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM)  },
+       { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD)  },
+       { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD)  },
+       { 0 },
+};
+MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
+
+static struct dvb_usb_device_properties dtt200u_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-dtt200u-01.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
+       .streaming_ctrl  = dtt200u_streaming_ctrl,
+       .pid_filter      = dtt200u_pid_filter,
+       .frontend_attach = dtt200u_frontend_attach,
+       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+               .count = 7,
+               .endpoint = 0x02,
+               .u = {
+                       .bulk = {
+                               .buffersize = 4096,
+                       }
+               }
+       },
+               }},
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval     = 300,
+               .rc_map_table    = rc_map_dtt200u_table,
+               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
+               .rc_query        = dtt200u_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
+                 .cold_ids = { &dtt200u_usb_table[0], NULL },
+                 .warm_ids = { &dtt200u_usb_table[1], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct dvb_usb_device_properties wt220u_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-wt220u-02.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
+       .streaming_ctrl  = dtt200u_streaming_ctrl,
+       .pid_filter      = dtt200u_pid_filter,
+       .frontend_attach = dtt200u_frontend_attach,
+       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+               .count = 7,
+               .endpoint = 0x02,
+               .u = {
+                       .bulk = {
+                               .buffersize = 4096,
+                       }
+               }
+       },
+               }},
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval     = 300,
+               .rc_map_table      = rc_map_dtt200u_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
+               .rc_query        = dtt200u_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
+                 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
+                 .warm_ids = { &dtt200u_usb_table[3], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct dvb_usb_device_properties wt220u_fc_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-wt220u-fc03.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
+       .streaming_ctrl  = dtt200u_streaming_ctrl,
+       .pid_filter      = dtt200u_pid_filter,
+       .frontend_attach = dtt200u_frontend_attach,
+       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+               .count = 7,
+                               .endpoint = 0x06,
+               .u = {
+                       .bulk = {
+                               .buffersize = 4096,
+                       }
+               }
+       },
+               }},
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval     = 300,
+               .rc_map_table    = rc_map_dtt200u_table,
+               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
+               .rc_query        = dtt200u_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
+                 .cold_ids = { &dtt200u_usb_table[6], NULL },
+                 .warm_ids = { &dtt200u_usb_table[7], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct dvb_usb_device_properties wt220u_zl0353_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-wt220u-zl0353-01.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
+                       .streaming_ctrl  = dtt200u_streaming_ctrl,
+                       .pid_filter      = dtt200u_pid_filter,
+                       .frontend_attach = dtt200u_frontend_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc.legacy = {
+               .rc_interval     = 300,
+               .rc_map_table    = rc_map_dtt200u_table,
+               .rc_map_size     = ARRAY_SIZE(rc_map_dtt200u_table),
+               .rc_query        = dtt200u_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
+                 .cold_ids = { &dtt200u_usb_table[4], NULL },
+                 .warm_ids = { &dtt200u_usb_table[5], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct dvb_usb_device_properties wt220u_miglia_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-wt220u-miglia-01.fw",
+
+       .num_adapters = 1,
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView WT-220U PenType Receiver (Miglia)",
+                 .cold_ids = { &dtt200u_usb_table[9], NULL },
+                 /* This device turns into WT220U_ZL0353_WARM when fw
+                    has been uploaded */
+                 .warm_ids = { NULL },
+               },
+               { NULL },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver dtt200u_usb_driver = {
+       .name           = "dvb_usb_dtt200u",
+       .probe          = dtt200u_usb_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = dtt200u_usb_table,
+};
+
+module_usb_driver(dtt200u_usb_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtt200u.h b/drivers/media/usb/dvb-usb/dtt200u.h
new file mode 100644 (file)
index 0000000..005b0a7
--- /dev/null
@@ -0,0 +1,57 @@
+/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DTT200U_H_
+#define _DVB_USB_DTT200U_H_
+
+#define DVB_USB_LOG_PREFIX "dtt200u"
+
+#include "dvb-usb.h"
+
+extern int dvb_usb_dtt200u_debug;
+#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
+
+/* guessed protocol description (reverse engineered):
+ * read
+ *  00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
+ *  88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
+ */
+
+#define GET_SPEED              0x00
+#define GET_TUNE_STATUS                0x81
+#define GET_RC_CODE            0x84
+#define GET_CONFIGURATION      0x88
+#define GET_AGC                        0x89
+#define GET_SNR                        0x8a
+#define GET_VIT_ERR_CNT                0x8c
+#define GET_RS_ERR_CNT         0x8d
+#define GET_RS_UNCOR_BLK_CNT   0x8e
+
+/* write
+ *  01 - init
+ *  02 - frequency (divided by 250000)
+ *  03 - bandwidth
+ *  04 - pid table (index pid(7:0) pid(12:8))
+ *  05 - reset the pid table
+ *  08 - transfer switch
+ */
+
+#define SET_INIT               0x01
+#define SET_RF_FREQ            0x02
+#define SET_BANDWIDTH          0x03
+#define SET_PID_FILTER         0x04
+#define RESET_PID_FILTER       0x05
+#define SET_STREAMING          0x08
+
+extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
new file mode 100644 (file)
index 0000000..3d11df4
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
+ *
+ * Copyright (C) 2008  Antoine Jacquet <royale@zerezo.com>
+ * http://royale.zerezo.com/dtv5100/
+ *
+ * Inspired by gl861.c and au6610.c drivers
+ *
+ * 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
+ */
+
+#include "dtv5100.h"
+#include "zl10353.h"
+#include "qt1010.h"
+
+/* debug */
+static int dvb_usb_dtv5100_debug;
+module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                          u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u8 request;
+       u8 type;
+       u16 value;
+       u16 index;
+
+       switch (wlen) {
+       case 1:
+               /* write { reg }, read { value } */
+               request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
+                                                       DTV5100_TUNER_READ);
+               type = USB_TYPE_VENDOR | USB_DIR_IN;
+               value = 0;
+               break;
+       case 2:
+               /* write { reg, value } */
+               request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
+                                                       DTV5100_TUNER_WRITE);
+               type = USB_TYPE_VENDOR | USB_DIR_OUT;
+               value = wbuf[1];
+               break;
+       default:
+               warn("wlen = %x, aborting.", wlen);
+               return -EINVAL;
+       }
+       index = (addr << 8) + wbuf[0];
+
+       msleep(1); /* avoid I2C errors */
+       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
+                              type, value, index, rbuf, rlen,
+                              DTV5100_USB_TIMEOUT);
+}
+
+/* I2C */
+static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                           int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                           msg[i].len, msg[i+1].buf,
+                                           msg[i+1].len) < 0)
+                               break;
+                       i++;
+               } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                          msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dtv5100_i2c_algo = {
+       .master_xfer   = dtv5100_i2c_xfer,
+       .functionality = dtv5100_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config dtv5100_zl10353_config = {
+       .demod_address = DTV5100_DEMOD_ADDR,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
+                             &adap->dev->i2c_adap);
+       if (adap->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       /* disable i2c gate, or it won't work... is this safe? */
+       adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
+
+       return 0;
+}
+
+static struct qt1010_config dtv5100_qt1010_config = {
+       .i2c_address = DTV5100_TUNER_ADDR
+};
+
+static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(qt1010_attach,
+                         adap->fe_adap[0].fe, &adap->dev->i2c_adap,
+                         &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties dtv5100_properties;
+
+static int dtv5100_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       int i, ret;
+       struct usb_device *udev = interface_to_usbdev(intf);
+
+       /* initialize non qt1010/zl10353 part? */
+       for (i = 0; dtv5100_init[i].request; i++) {
+               ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                                     dtv5100_init[i].request,
+                                     USB_TYPE_VENDOR | USB_DIR_OUT,
+                                     dtv5100_init[i].value,
+                                     dtv5100_init[i].index, NULL, 0,
+                                     DTV5100_USB_TIMEOUT);
+               if (ret)
+                       return ret;
+       }
+
+       ret = dvb_usb_device_init(intf, &dtv5100_properties,
+                                 THIS_MODULE, NULL, adapter_nr);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static struct usb_device_id dtv5100_table[] = {
+       { USB_DEVICE(0x06be, 0xa232) },
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, dtv5100_table);
+
+static struct dvb_usb_device_properties dtv5100_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+
+       .size_of_priv = 0,
+
+       .num_adapters = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+               .frontend_attach = dtv5100_frontend_attach,
+               .tuner_attach    = dtv5100_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x82,
+                       .u = {
+                               .bulk = {
+                                       .buffersize = 4096,
+                               }
+                       }
+               },
+               }},
+       } },
+
+       .i2c_algo = &dtv5100_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {
+                       .name = "AME DTV-5100 USB2.0 DVB-T",
+                       .cold_ids = { NULL },
+                       .warm_ids = { &dtv5100_table[0], NULL },
+               },
+       }
+};
+
+static struct usb_driver dtv5100_driver = {
+       .name           = "dvb_usb_dtv5100",
+       .probe          = dtv5100_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = dtv5100_table,
+};
+
+module_usb_driver(dtv5100_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtv5100.h b/drivers/media/usb/dvb-usb/dtv5100.h
new file mode 100644 (file)
index 0000000..93e96e0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
+ *
+ * Copyright (C) 2008  Antoine Jacquet <royale@zerezo.com>
+ * http://royale.zerezo.com/dtv5100/
+ *
+ * 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
+ */
+
+#ifndef _DVB_USB_DTV5100_H_
+#define _DVB_USB_DTV5100_H_
+
+#define DVB_USB_LOG_PREFIX "dtv5100"
+#include "dvb-usb.h"
+
+#define DTV5100_USB_TIMEOUT 500
+
+#define DTV5100_DEMOD_ADDR     0x00
+#define DTV5100_DEMOD_WRITE    0xc0
+#define DTV5100_DEMOD_READ     0xc1
+
+#define DTV5100_TUNER_ADDR     0xc4
+#define DTV5100_TUNER_WRITE    0xc7
+#define DTV5100_TUNER_READ     0xc8
+
+#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
+#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
+
+static struct {
+       u8 request;
+       u8 value;
+       u16 index;
+} dtv5100_init[] = {
+       { 0x000000c5, 0x00000000, 0x00000001 },
+       { 0x000000c5, 0x00000001, 0x00000001 },
+       { }             /* Terminating entry */
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-common.h b/drivers/media/usb/dvb-usb/dvb-usb-common.h
new file mode 100644 (file)
index 0000000..6b7b2a8
--- /dev/null
@@ -0,0 +1,52 @@
+/* dvb-usb-common.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * a header file containing prototypes and types for internal use of the dvb-usb-lib
+ */
+#ifndef _DVB_USB_COMMON_H_
+#define _DVB_USB_COMMON_H_
+
+#define DVB_USB_LOG_PREFIX "dvb-usb"
+#include "dvb-usb.h"
+
+extern int dvb_usb_debug;
+extern int dvb_usb_disable_rc_polling;
+
+#define deb_info(args...)  dprintk(dvb_usb_debug,0x001,args)
+#define deb_xfer(args...)  dprintk(dvb_usb_debug,0x002,args)
+#define deb_pll(args...)   dprintk(dvb_usb_debug,0x004,args)
+#define deb_ts(args...)    dprintk(dvb_usb_debug,0x008,args)
+#define deb_err(args...)   dprintk(dvb_usb_debug,0x010,args)
+#define deb_rc(args...)    dprintk(dvb_usb_debug,0x020,args)
+#define deb_fw(args...)    dprintk(dvb_usb_debug,0x040,args)
+#define deb_mem(args...)   dprintk(dvb_usb_debug,0x080,args)
+#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
+
+/* commonly used  methods */
+extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
+
+extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
+
+extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
+extern int usb_urb_exit(struct usb_data_stream *stream);
+extern int usb_urb_submit(struct usb_data_stream *stream);
+extern int usb_urb_kill(struct usb_data_stream *stream);
+
+extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
+
+extern int dvb_usb_i2c_init(struct dvb_usb_device *);
+extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap,
+                                   short *adapter_nums);
+extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
+
+extern int dvb_usb_remote_init(struct dvb_usb_device *);
+extern int dvb_usb_remote_exit(struct dvb_usb_device *);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
new file mode 100644 (file)
index 0000000..719413b
--- /dev/null
@@ -0,0 +1,288 @@
+/* dvb-usb-dvb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * linux-dvb API.
+ */
+#include "dvb-usb-common.h"
+
+/* does the complete input transfer handling */
+static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
+{
+       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
+       int newfeedcount, ret;
+
+       if (adap == NULL)
+               return -ENODEV;
+
+       if ((adap->active_fe < 0) ||
+           (adap->active_fe >= adap->num_frontends_initialized)) {
+               return -EINVAL;
+       }
+
+       newfeedcount = adap->feedcount + (onoff ? 1 : -1);
+
+       /* stop feed before setting a new pid if there will be no pid anymore */
+       if (newfeedcount == 0) {
+               deb_ts("stop feeding\n");
+               usb_urb_kill(&adap->fe_adap[adap->active_fe].stream);
+
+               if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
+                       ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 0);
+                       if (ret < 0) {
+                               err("error while stopping stream.");
+                               return ret;
+                       }
+               }
+       }
+
+       adap->feedcount = newfeedcount;
+
+       /* activate the pid on the device specific pid_filter */
+       deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",
+               adap->fe_adap[adap->active_fe].pid_filtering ?
+               "yes" : "no", dvbdmxfeed->pid, dvbdmxfeed->pid,
+               dvbdmxfeed->index, onoff ? "on" : "off");
+       if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+               adap->fe_adap[adap->active_fe].pid_filtering &&
+               adap->props.fe[adap->active_fe].pid_filter != NULL)
+               adap->props.fe[adap->active_fe].pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
+
+       /* start the feed if this was the first feed and there is still a feed
+        * for reception.
+        */
+       if (adap->feedcount == onoff && adap->feedcount > 0) {
+               deb_ts("submitting all URBs\n");
+               usb_urb_submit(&adap->fe_adap[adap->active_fe].stream);
+
+               deb_ts("controlling pid parser\n");
+               if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                       adap->props.fe[adap->active_fe].caps &
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+                       adap->props.fe[adap->active_fe].pid_filter_ctrl != NULL) {
+                       ret = adap->props.fe[adap->active_fe].pid_filter_ctrl(adap,
+                               adap->fe_adap[adap->active_fe].pid_filtering);
+                       if (ret < 0) {
+                               err("could not handle pid_parser");
+                               return ret;
+                       }
+               }
+               deb_ts("start feeding\n");
+               if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
+                       ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 1);
+                       if (ret < 0) {
+                               err("error while enabling fifo.");
+                               return ret;
+                       }
+               }
+
+       }
+       return 0;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+       return dvb_usb_ctrl_feed(dvbdmxfeed,1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
+       return dvb_usb_ctrl_feed(dvbdmxfeed,0);
+}
+
+int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
+{
+       int i;
+       int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
+                                      adap->dev->owner, &adap->dev->udev->dev,
+                                      adapter_nums);
+
+       if (ret < 0) {
+               deb_info("dvb_register_adapter failed: error %d", ret);
+               goto err;
+       }
+       adap->dvb_adap.priv = adap;
+
+       if (adap->dev->props.read_mac_address) {
+               if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
+                       info("MAC address: %pM",adap->dvb_adap.proposed_mac);
+               else
+                       err("MAC address reading failed.");
+       }
+
+
+       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       adap->demux.priv             = adap;
+
+       adap->demux.filternum        = 0;
+       for (i = 0; i < adap->props.num_frontends; i++) {
+               if (adap->demux.filternum < adap->fe_adap[i].max_feed_count)
+                       adap->demux.filternum = adap->fe_adap[i].max_feed_count;
+       }
+       adap->demux.feednum          = adap->demux.filternum;
+       adap->demux.start_feed       = dvb_usb_start_feed;
+       adap->demux.stop_feed        = dvb_usb_stop_feed;
+       adap->demux.write_to_decoder = NULL;
+       if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
+               err("dvb_dmx_init failed: error %d",ret);
+               goto err_dmx;
+       }
+
+       adap->dmxdev.filternum       = adap->demux.filternum;
+       adap->dmxdev.demux           = &adap->demux.dmx;
+       adap->dmxdev.capabilities    = 0;
+       if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
+               err("dvb_dmxdev_init failed: error %d",ret);
+               goto err_dmx_dev;
+       }
+
+       if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net,
+                                               &adap->demux.dmx)) < 0) {
+               err("dvb_net_init failed: error %d",ret);
+               goto err_net_init;
+       }
+
+       adap->state |= DVB_USB_ADAP_STATE_DVB;
+       return 0;
+
+err_net_init:
+       dvb_dmxdev_release(&adap->dmxdev);
+err_dmx_dev:
+       dvb_dmx_release(&adap->demux);
+err_dmx:
+       dvb_unregister_adapter(&adap->dvb_adap);
+err:
+       return ret;
+}
+
+int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+{
+       if (adap->state & DVB_USB_ADAP_STATE_DVB) {
+               deb_info("unregistering DVB part\n");
+               dvb_net_release(&adap->dvb_net);
+               adap->demux.dmx.close(&adap->demux.dmx);
+               dvb_dmxdev_release(&adap->dmxdev);
+               dvb_dmx_release(&adap->demux);
+               dvb_unregister_adapter(&adap->dvb_adap);
+               adap->state &= ~DVB_USB_ADAP_STATE_DVB;
+       }
+       return 0;
+}
+
+static int dvb_usb_set_active_fe(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+       int ret = (adap->props.frontend_ctrl) ?
+               adap->props.frontend_ctrl(fe, onoff) : 0;
+
+       if (ret < 0) {
+               err("frontend_ctrl request failed");
+               return ret;
+       }
+       if (onoff)
+               adap->active_fe = fe->id;
+
+       return 0;
+}
+
+static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+       dvb_usb_device_power_ctrl(adap->dev, 1);
+
+       dvb_usb_set_active_fe(fe, 1);
+
+       if (adap->fe_adap[fe->id].fe_init)
+               adap->fe_adap[fe->id].fe_init(fe);
+
+       return 0;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+       if (adap->fe_adap[fe->id].fe_sleep)
+               adap->fe_adap[fe->id].fe_sleep(fe);
+
+       dvb_usb_set_active_fe(fe, 0);
+
+       return dvb_usb_device_power_ctrl(adap->dev, 0);
+}
+
+int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
+{
+       int ret, i;
+
+       /* register all given adapter frontends */
+       for (i = 0; i < adap->props.num_frontends; i++) {
+
+               if (adap->props.fe[i].frontend_attach == NULL) {
+                       err("strange: '%s' #%d,%d "
+                           "doesn't want to attach a frontend.",
+                           adap->dev->desc->name, adap->id, i);
+
+                       return 0;
+               }
+
+               ret = adap->props.fe[i].frontend_attach(adap);
+               if (ret || adap->fe_adap[i].fe == NULL) {
+                       /* only print error when there is no FE at all */
+                       if (i == 0)
+                               err("no frontend was attached by '%s'",
+                                       adap->dev->desc->name);
+
+                       return 0;
+               }
+
+               adap->fe_adap[i].fe->id = i;
+
+               /* re-assign sleep and wakeup functions */
+               adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init;
+               adap->fe_adap[i].fe->ops.init  = dvb_usb_fe_wakeup;
+               adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
+               adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;
+
+               if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
+                       err("Frontend %d registration failed.", i);
+                       dvb_frontend_detach(adap->fe_adap[i].fe);
+                       adap->fe_adap[i].fe = NULL;
+                       /* In error case, do not try register more FEs,
+                        * still leaving already registered FEs alive. */
+                       if (i == 0)
+                               return -ENODEV;
+                       else
+                               return 0;
+               }
+
+               /* only attach the tuner if the demod is there */
+               if (adap->props.fe[i].tuner_attach != NULL)
+                       adap->props.fe[i].tuner_attach(adap);
+
+               adap->num_frontends_initialized++;
+       }
+
+       return 0;
+}
+
+int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+{
+       int i = adap->num_frontends_initialized - 1;
+
+       /* unregister all given adapter frontends */
+       for (; i >= 0; i--) {
+               if (adap->fe_adap[i].fe != NULL) {
+                       dvb_unregister_frontend(adap->fe_adap[i].fe);
+                       dvb_frontend_detach(adap->fe_adap[i].fe);
+               }
+       }
+       adap->num_frontends_initialized = 0;
+
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
new file mode 100644 (file)
index 0000000..733a7ff
--- /dev/null
@@ -0,0 +1,146 @@
+/* dvb-usb-firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
+ *
+ * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
+ */
+#include "dvb-usb-common.h"
+
+#include <linux/usb.h>
+
+struct usb_cypress_controller {
+       int id;
+       const char *name;       /* name of the usb controller */
+       u16 cpu_cs_register;    /* needs to be restarted, when the firmware has been downloaded. */
+};
+
+static struct usb_cypress_controller cypress[] = {
+       { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
+       { .id = CYPRESS_AN2135,  .name = "Cypress AN2135",  .cpu_cs_register = 0x7f92 },
+       { .id = CYPRESS_AN2235,  .name = "Cypress AN2235",  .cpu_cs_register = 0x7f92 },
+       { .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
+{
+       return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+                       0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
+}
+
+int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
+{
+       struct hexline hx;
+       u8 reset;
+       int ret,pos=0;
+
+       /* stop the CPU */
+       reset = 1;
+       if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+               err("could not stop the USB controller CPU.");
+
+       while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
+               deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
+               ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+
+               if (ret != hx.len) {
+                       err("error while transferring firmware "
+                               "(transferred size: %d, block size: %d)",
+                               ret,hx.len);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       if (ret < 0) {
+               err("firmware download failed at %d with %d",pos,ret);
+               return ret;
+       }
+
+       if (ret == 0) {
+               /* restart the CPU */
+               reset = 0;
+               if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+                       err("could not restart the USB controller CPU.");
+                       ret = -EINVAL;
+               }
+       } else
+               ret = -EIO;
+
+       return ret;
+}
+EXPORT_SYMBOL(usb_cypress_load_firmware);
+
+int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
+{
+       int ret;
+       const struct firmware *fw = NULL;
+
+       if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
+               err("did not find the firmware file. (%s) "
+                       "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+                       props->firmware,ret);
+               return ret;
+       }
+
+       info("downloading firmware from file '%s'",props->firmware);
+
+       switch (props->usb_ctrl) {
+               case CYPRESS_AN2135:
+               case CYPRESS_AN2235:
+               case CYPRESS_FX2:
+                       ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
+                       break;
+               case DEVICE_SPECIFIC:
+                       if (props->download_firmware)
+                               ret = props->download_firmware(udev,fw);
+                       else {
+                               err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
+                               ret = -EINVAL;
+                       }
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+       }
+
+       release_firmware(fw);
+       return ret;
+}
+
+int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+                              int *pos)
+{
+       u8 *b = (u8 *) &fw->data[*pos];
+       int data_offs = 4;
+       if (*pos >= fw->size)
+               return 0;
+
+       memset(hx,0,sizeof(struct hexline));
+
+       hx->len  = b[0];
+
+       if ((*pos + hx->len + 4) >= fw->size)
+               return -EINVAL;
+
+       hx->addr = b[1] | (b[2] << 8);
+       hx->type = b[3];
+
+       if (hx->type == 0x04) {
+               /* b[4] and b[5] are the Extended linear address record data field */
+               hx->addr |= (b[4] << 24) | (b[5] << 16);
+/*             hx->len -= 2;
+               data_offs += 2; */
+       }
+       memcpy(hx->data,&b[data_offs],hx->len);
+       hx->chk = b[hx->len + data_offs];
+
+       *pos += hx->len + 5;
+
+       return *pos;
+}
+EXPORT_SYMBOL(dvb_usb_get_hexline);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
new file mode 100644 (file)
index 0000000..88e4a62
--- /dev/null
@@ -0,0 +1,43 @@
+/* dvb-usb-i2c.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for (de-)initializing an I2C adapter.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_i2c_init(struct dvb_usb_device *d)
+{
+       int ret = 0;
+
+       if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
+               return 0;
+
+       if (d->props.i2c_algo == NULL) {
+               err("no i2c algorithm specified");
+               return -EINVAL;
+       }
+
+       strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
+       d->i2c_adap.algo      = d->props.i2c_algo;
+       d->i2c_adap.algo_data = NULL;
+       d->i2c_adap.dev.parent = &d->udev->dev;
+
+       i2c_set_adapdata(&d->i2c_adap, d);
+
+       if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
+               err("could not add i2c adapter");
+
+       d->state |= DVB_USB_STATE_I2C;
+
+       return ret;
+}
+
+int dvb_usb_i2c_exit(struct dvb_usb_device *d)
+{
+       if (d->state & DVB_USB_STATE_I2C)
+               i2c_del_adapter(&d->i2c_adap);
+       d->state &= ~DVB_USB_STATE_I2C;
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
new file mode 100644 (file)
index 0000000..169196e
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * DVB USB library - provides a generic interface for a DVB USB device driver.
+ *
+ * dvb-usb-init.c
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dvb-usb-common.h"
+
+/* debug */
+int dvb_usb_debug;
+module_param_named(debug, dvb_usb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256  (or-able))." DVB_USB_DEBUG_STATUS);
+
+int dvb_usb_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
+
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
+MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
+
+static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+{
+       struct dvb_usb_adapter *adap;
+       int ret, n, o;
+
+       for (n = 0; n < d->props.num_adapters; n++) {
+               adap = &d->adapter[n];
+               adap->dev = d;
+               adap->id  = n;
+
+               memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
+
+       for (o = 0; o < adap->props.num_frontends; o++) {
+               struct dvb_usb_adapter_fe_properties *props = &adap->props.fe[o];
+               /* speed - when running at FULL speed we need a HW PID filter */
+               if (d->udev->speed == USB_SPEED_FULL && !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+                       err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
+                       return -ENODEV;
+               }
+
+               if ((d->udev->speed == USB_SPEED_FULL && props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+                       (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+                       info("will use the device's hardware PID filter (table count: %d).", props->pid_filter_count);
+                       adap->fe_adap[o].pid_filtering  = 1;
+                       adap->fe_adap[o].max_feed_count = props->pid_filter_count;
+               } else {
+                       info("will pass the complete MPEG2 transport stream to the software demuxer.");
+                       adap->fe_adap[o].pid_filtering  = 0;
+                       adap->fe_adap[o].max_feed_count = 255;
+               }
+
+               if (!adap->fe_adap[o].pid_filtering &&
+                       dvb_usb_force_pid_filter_usage &&
+                       props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+                       info("pid filter enabled by module option.");
+                       adap->fe_adap[o].pid_filtering  = 1;
+                       adap->fe_adap[o].max_feed_count = props->pid_filter_count;
+               }
+
+               if (props->size_of_priv > 0) {
+                       adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL);
+                       if (adap->fe_adap[o].priv == NULL) {
+                               err("no memory for priv for adapter %d fe %d.", n, o);
+                               return -ENOMEM;
+                       }
+               }
+       }
+
+               if (adap->props.size_of_priv > 0) {
+                       adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
+                       if (adap->priv == NULL) {
+                               err("no memory for priv for adapter %d.", n);
+                               return -ENOMEM;
+                       }
+               }
+
+               if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+                       (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
+                       (ret = dvb_usb_adapter_frontend_init(adap))) {
+                       return ret;
+               }
+
+               /* use exclusive FE lock if there is multiple shared FEs */
+               if (adap->fe_adap[1].fe)
+                       adap->dvb_adap.mfe_shared = 1;
+
+               d->num_adapters_initialized++;
+               d->state |= DVB_USB_STATE_DVB;
+       }
+
+       /*
+        * when reloading the driver w/o replugging the device
+        * sometimes a timeout occures, this helps
+        */
+       if (d->props.generic_bulk_ctrl_endpoint != 0) {
+               usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+               usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+       }
+
+       return 0;
+}
+
+static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
+{
+       int n;
+
+       for (n = 0; n < d->num_adapters_initialized; n++) {
+               dvb_usb_adapter_frontend_exit(&d->adapter[n]);
+               dvb_usb_adapter_dvb_exit(&d->adapter[n]);
+               dvb_usb_adapter_stream_exit(&d->adapter[n]);
+               kfree(d->adapter[n].priv);
+       }
+       d->num_adapters_initialized = 0;
+       d->state &= ~DVB_USB_STATE_DVB;
+       return 0;
+}
+
+
+/* general initialization functions */
+static int dvb_usb_exit(struct dvb_usb_device *d)
+{
+       deb_info("state before exiting everything: %x\n", d->state);
+       dvb_usb_remote_exit(d);
+       dvb_usb_adapter_exit(d);
+       dvb_usb_i2c_exit(d);
+       deb_info("state should be zero now: %x\n", d->state);
+       d->state = DVB_USB_STATE_INIT;
+       kfree(d->priv);
+       kfree(d);
+       return 0;
+}
+
+static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
+{
+       int ret = 0;
+
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
+
+       d->state = DVB_USB_STATE_INIT;
+
+       if (d->props.size_of_priv > 0) {
+               d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
+               if (d->priv == NULL) {
+                       err("no memory for priv in 'struct dvb_usb_device'");
+                       return -ENOMEM;
+               }
+       }
+
+       /* check the capabilities and set appropriate variables */
+       dvb_usb_device_power_ctrl(d, 1);
+
+       if ((ret = dvb_usb_i2c_init(d)) ||
+               (ret = dvb_usb_adapter_init(d, adapter_nums))) {
+               dvb_usb_exit(d);
+               return ret;
+       }
+
+       if ((ret = dvb_usb_remote_init(d)))
+               err("could not initialize remote control.");
+
+       dvb_usb_device_power_ctrl(d, 0);
+
+       return 0;
+}
+
+/* determine the name and the state of the just found USB device */
+static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
+{
+       int i, j;
+       struct dvb_usb_device_description *desc = NULL;
+
+       *cold = -1;
+
+       for (i = 0; i < props->num_device_descs; i++) {
+
+               for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
+                       deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
+                       if (props->devices[i].cold_ids[j]->idVendor  == le16_to_cpu(udev->descriptor.idVendor) &&
+                               props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+                               *cold = 1;
+                               desc = &props->devices[i];
+                               break;
+                       }
+               }
+
+               if (desc != NULL)
+                       break;
+
+               for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
+                       deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
+                       if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
+                               props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+                               *cold = 0;
+                               desc = &props->devices[i];
+                               break;
+                       }
+               }
+       }
+
+       if (desc != NULL && props->identify_state != NULL)
+               props->identify_state(udev, props, &desc, cold);
+
+       return desc;
+}
+
+int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       if (onoff)
+               d->powered++;
+       else
+               d->powered--;
+
+       if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
+               deb_info("power control: %d\n", onoff);
+               if (d->props.power_ctrl)
+                       return d->props.power_ctrl(d, onoff);
+       }
+       return 0;
+}
+
+/*
+ * USB
+ */
+int dvb_usb_device_init(struct usb_interface *intf,
+                       struct dvb_usb_device_properties *props,
+                       struct module *owner, struct dvb_usb_device **du,
+                       short *adapter_nums)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct dvb_usb_device *d = NULL;
+       struct dvb_usb_device_description *desc = NULL;
+
+       int ret = -ENOMEM, cold = 0;
+
+       if (du != NULL)
+               *du = NULL;
+
+       if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
+               deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
+               return -ENODEV;
+       }
+
+       if (cold) {
+               info("found a '%s' in cold state, will try to load a firmware", desc->name);
+               ret = dvb_usb_download_firmware(udev, props);
+               if (!props->no_reconnect || ret != 0)
+                       return ret;
+       }
+
+       info("found a '%s' in warm state.", desc->name);
+       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+       if (d == NULL) {
+               err("no memory for 'struct dvb_usb_device'");
+               return -ENOMEM;
+       }
+
+       d->udev = udev;
+       memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
+       d->desc = desc;
+       d->owner = owner;
+
+       usb_set_intfdata(intf, d);
+
+       if (du != NULL)
+               *du = d;
+
+       ret = dvb_usb_init(d, adapter_nums);
+
+       if (ret == 0)
+               info("%s successfully initialized and connected.", desc->name);
+       else
+               info("%s error while loading driver (%d)", desc->name, ret);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usb_device_init);
+
+void dvb_usb_device_exit(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       const char *name = "generic DVB-USB module";
+
+       usb_set_intfdata(intf, NULL);
+       if (d != NULL && d->desc != NULL) {
+               name = d->desc->name;
+               dvb_usb_exit(d);
+       }
+       info("%s successfully deinitialized and disconnected.", name);
+
+}
+EXPORT_SYMBOL(dvb_usb_device_exit);
+
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
new file mode 100644 (file)
index 0000000..41bacff
--- /dev/null
@@ -0,0 +1,391 @@
+/* dvb-usb-remote.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing the input-device and for handling remote-control-queries.
+ */
+#include "dvb-usb-common.h"
+#include <linux/usb/input.h>
+
+static unsigned int
+legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
+                               struct rc_map_table *keymap,
+                               unsigned int keymap_size)
+{
+       unsigned int index;
+       unsigned int scancode;
+
+       if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+               index = ke->index;
+       } else {
+               if (input_scancode_to_scalar(ke, &scancode))
+                       return keymap_size;
+
+               /* See if we can match the raw key code. */
+               for (index = 0; index < keymap_size; index++)
+                       if (keymap[index].scancode == scancode)
+                               break;
+
+               /* See if there is an unused hole in the map */
+               if (index >= keymap_size) {
+                       for (index = 0; index < keymap_size; index++) {
+                               if (keymap[index].keycode == KEY_RESERVED ||
+                                   keymap[index].keycode == KEY_UNKNOWN) {
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       return index;
+}
+
+static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
+                                    struct input_keymap_entry *ke)
+{
+       struct dvb_usb_device *d = input_get_drvdata(dev);
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
+       unsigned int index;
+
+       index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
+       if (index >= keymap_size)
+               return -EINVAL;
+
+       ke->keycode = keymap[index].keycode;
+       if (ke->keycode == KEY_UNKNOWN)
+               ke->keycode = KEY_RESERVED;
+       ke->len = sizeof(keymap[index].scancode);
+       memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
+       ke->index = index;
+
+       return 0;
+}
+
+static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
+                                    const struct input_keymap_entry *ke,
+                                    unsigned int *old_keycode)
+{
+       struct dvb_usb_device *d = input_get_drvdata(dev);
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
+       unsigned int index;
+
+       index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
+       /*
+        * FIXME: Currently, it is not possible to increase the size of
+        * scancode table. For it to happen, one possibility
+        * would be to allocate a table with key_map_size + 1,
+        * copying data, appending the new key on it, and freeing
+        * the old one - or maybe just allocating some spare space
+        */
+       if (index >= keymap_size)
+               return -EINVAL;
+
+       *old_keycode = keymap[index].keycode;
+       keymap->keycode = ke->keycode;
+       __set_bit(ke->keycode, dev->keybit);
+
+       if (*old_keycode != KEY_RESERVED) {
+               __clear_bit(*old_keycode, dev->keybit);
+               for (index = 0; index < keymap_size; index++) {
+                       if (keymap[index].keycode == *old_keycode) {
+                               __set_bit(*old_keycode, dev->keybit);
+                               break;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
+{
+       struct dvb_usb_device *d =
+               container_of(work, struct dvb_usb_device, rc_query_work.work);
+       u32 event;
+       int state;
+
+       /* TODO: need a lock here.  We can simply skip checking for the remote control
+          if we're busy. */
+
+       /* when the parameter has been set to 1 via sysfs while the driver was running */
+       if (dvb_usb_disable_rc_polling)
+               return;
+
+       if (d->props.rc.legacy.rc_query(d,&event,&state)) {
+               err("error while querying for an remote control event.");
+               goto schedule;
+       }
+
+
+       switch (state) {
+               case REMOTE_NO_KEY_PRESSED:
+                       break;
+               case REMOTE_KEY_PRESSED:
+                       deb_rc("key pressed\n");
+                       d->last_event = event;
+               case REMOTE_KEY_REPEAT:
+                       deb_rc("key repeated\n");
+                       input_event(d->input_dev, EV_KEY, event, 1);
+                       input_sync(d->input_dev);
+                       input_event(d->input_dev, EV_KEY, d->last_event, 0);
+                       input_sync(d->input_dev);
+                       break;
+               default:
+                       break;
+       }
+
+/* improved repeat handling ???
+       switch (state) {
+               case REMOTE_NO_KEY_PRESSED:
+                       deb_rc("NO KEY PRESSED\n");
+                       if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+                               deb_rc("releasing event %d\n",d->last_event);
+                               input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+                               input_sync(d->rc_input_dev);
+                       }
+                       d->last_state = REMOTE_NO_KEY_PRESSED;
+                       d->last_event = 0;
+                       break;
+               case REMOTE_KEY_PRESSED:
+                       deb_rc("KEY PRESSED\n");
+                       deb_rc("pressing event %d\n",event);
+
+                       input_event(d->rc_input_dev, EV_KEY, event, 1);
+                       input_sync(d->rc_input_dev);
+
+                       d->last_event = event;
+                       d->last_state = REMOTE_KEY_PRESSED;
+                       break;
+               case REMOTE_KEY_REPEAT:
+                       deb_rc("KEY_REPEAT\n");
+                       if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+                               deb_rc("repeating event %d\n",d->last_event);
+                               input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
+                               input_sync(d->rc_input_dev);
+                               d->last_state = REMOTE_KEY_REPEAT;
+                       }
+               default:
+                       break;
+       }
+*/
+
+schedule:
+       schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
+}
+
+static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
+{
+       int i, err, rc_interval;
+       struct input_dev *input_dev;
+
+       input_dev = input_allocate_device();
+       if (!input_dev)
+               return -ENOMEM;
+
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       input_dev->name = "IR-receiver inside an USB DVB receiver";
+       input_dev->phys = d->rc_phys;
+       usb_to_input_id(d->udev, &input_dev->id);
+       input_dev->dev.parent = &d->udev->dev;
+       d->input_dev = input_dev;
+       d->rc_dev = NULL;
+
+       input_dev->getkeycode = legacy_dvb_usb_getkeycode;
+       input_dev->setkeycode = legacy_dvb_usb_setkeycode;
+
+       /* set the bits for the keys */
+       deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
+       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+               deb_rc("setting bit for event %d item %d\n",
+                       d->props.rc.legacy.rc_map_table[i].keycode, i);
+               set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
+       }
+
+       /* setting these two values to non-zero, we have to manage key repeats */
+       input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
+       input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
+
+       input_set_drvdata(input_dev, d);
+
+       err = input_register_device(input_dev);
+       if (err)
+               input_free_device(input_dev);
+
+       rc_interval = d->props.rc.legacy.rc_interval;
+
+       INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
+
+       info("schedule remote query interval to %d msecs.", rc_interval);
+       schedule_delayed_work(&d->rc_query_work,
+                             msecs_to_jiffies(rc_interval));
+
+       d->state |= DVB_USB_STATE_REMOTE;
+
+       return err;
+}
+
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void dvb_usb_read_remote_control(struct work_struct *work)
+{
+       struct dvb_usb_device *d =
+               container_of(work, struct dvb_usb_device, rc_query_work.work);
+       int err;
+
+       /* TODO: need a lock here.  We can simply skip checking for the remote control
+          if we're busy. */
+
+       /* when the parameter has been set to 1 via sysfs while the
+        * driver was running, or when bulk mode is enabled after IR init
+        */
+       if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
+               return;
+
+       err = d->props.rc.core.rc_query(d);
+       if (err)
+               err("error %d while querying for an remote control event.", err);
+
+       schedule_delayed_work(&d->rc_query_work,
+                             msecs_to_jiffies(d->props.rc.core.rc_interval));
+}
+
+static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
+{
+       int err, rc_interval;
+       struct rc_dev *dev;
+
+       dev = rc_allocate_device();
+       if (!dev)
+               return -ENOMEM;
+
+       dev->driver_name = d->props.rc.core.module_name;
+       dev->map_name = d->props.rc.core.rc_codes;
+       dev->change_protocol = d->props.rc.core.change_protocol;
+       dev->allowed_protos = d->props.rc.core.allowed_protos;
+       dev->driver_type = d->props.rc.core.driver_type;
+       usb_to_input_id(d->udev, &dev->input_id);
+       dev->input_name = "IR-receiver inside an USB DVB receiver";
+       dev->input_phys = d->rc_phys;
+       dev->dev.parent = &d->udev->dev;
+       dev->priv = d;
+
+       err = rc_register_device(dev);
+       if (err < 0) {
+               rc_free_device(dev);
+               return err;
+       }
+
+       d->input_dev = NULL;
+       d->rc_dev = dev;
+
+       if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
+               return 0;
+
+       /* Polling mode - initialize a work queue for handling it */
+       INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
+
+       rc_interval = d->props.rc.core.rc_interval;
+
+       info("schedule remote query interval to %d msecs.", rc_interval);
+       schedule_delayed_work(&d->rc_query_work,
+                             msecs_to_jiffies(rc_interval));
+
+       return 0;
+}
+
+int dvb_usb_remote_init(struct dvb_usb_device *d)
+{
+       int err;
+
+       if (dvb_usb_disable_rc_polling)
+               return 0;
+
+       if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
+               d->props.rc.mode = DVB_RC_LEGACY;
+       else if (d->props.rc.core.rc_codes)
+               d->props.rc.mode = DVB_RC_CORE;
+       else
+               return 0;
+
+       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+
+       /* Start the remote-control polling. */
+       if (d->props.rc.legacy.rc_interval < 40)
+               d->props.rc.legacy.rc_interval = 100; /* default */
+
+       if (d->props.rc.mode == DVB_RC_LEGACY)
+               err = legacy_dvb_usb_remote_init(d);
+       else
+               err = rc_core_dvb_usb_remote_init(d);
+       if (err)
+               return err;
+
+       d->state |= DVB_USB_STATE_REMOTE;
+
+       return 0;
+}
+
+int dvb_usb_remote_exit(struct dvb_usb_device *d)
+{
+       if (d->state & DVB_USB_STATE_REMOTE) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+               if (d->props.rc.mode == DVB_RC_LEGACY)
+                       input_unregister_device(d->input_dev);
+               else
+                       rc_unregister_device(d->rc_dev);
+       }
+       d->state &= ~DVB_USB_STATE_REMOTE;
+       return 0;
+}
+
+#define DVB_USB_RC_NEC_EMPTY           0x00
+#define DVB_USB_RC_NEC_KEY_PRESSED     0x01
+#define DVB_USB_RC_NEC_KEY_REPEATED    0x02
+int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
+               u8 keybuf[5], u32 *event, int *state)
+{
+       int i;
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+       switch (keybuf[0]) {
+               case DVB_USB_RC_NEC_EMPTY:
+                       break;
+               case DVB_USB_RC_NEC_KEY_PRESSED:
+                       if ((u8) ~keybuf[1] != keybuf[2] ||
+                               (u8) ~keybuf[3] != keybuf[4]) {
+                               deb_err("remote control checksum failed.\n");
+                               break;
+                       }
+                       /* See if we can match the raw key code. */
+                       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
+                               if (rc5_custom(&keymap[i]) == keybuf[1] &&
+                                       rc5_data(&keymap[i]) == keybuf[3]) {
+                                       *event = keymap[i].keycode;
+                                       *state = REMOTE_KEY_PRESSED;
+                                       return 0;
+                               }
+                       deb_err("key mapping failed - no appropriate key found in keymapping\n");
+                       break;
+               case DVB_USB_RC_NEC_KEY_REPEATED:
+                       *state = REMOTE_KEY_REPEAT;
+                       break;
+               default:
+                       deb_err("unknown type of remote status: %d\n",keybuf[0]);
+                       break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
new file mode 100644 (file)
index 0000000..5c8f651
--- /dev/null
@@ -0,0 +1,121 @@
+/* dvb-usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * USB and URB stuff.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+       u16 rlen, int delay_ms)
+{
+       int actlen,ret = -ENOMEM;
+
+       if (!d || wbuf == NULL || wlen == 0)
+               return -EINVAL;
+
+       if (d->props.generic_bulk_ctrl_endpoint == 0) {
+               err("endpoint for generic control not specified.");
+               return -EINVAL;
+       }
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       deb_xfer(">>> ");
+       debug_dump(wbuf,wlen,deb_xfer);
+
+       ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
+                       d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
+                       2000);
+
+       if (ret)
+               err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
+       else
+               ret = actlen != wlen ? -1 : 0;
+
+       /* an answer is expected, and no error before */
+       if (!ret && rbuf && rlen) {
+               if (delay_ms)
+                       msleep(delay_ms);
+
+               ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
+                               d->props.generic_bulk_ctrl_endpoint_response ?
+                               d->props.generic_bulk_ctrl_endpoint_response :
+                               d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
+                               2000);
+
+               if (ret)
+                       err("recv bulk message failed: %d",ret);
+               else {
+                       deb_xfer("<<< ");
+                       debug_dump(rbuf,actlen,deb_xfer);
+               }
+       }
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usb_generic_rw);
+
+int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+       return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
+}
+EXPORT_SYMBOL(dvb_usb_generic_write);
+
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+               dvb_dmx_swfilter(&adap->demux, buffer, length);
+}
+
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+               dvb_dmx_swfilter_204(&adap->demux, buffer, length);
+}
+
+static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
+                                     u8 *buffer, size_t length)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+               dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
+}
+
+int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
+{
+       int i, ret = 0;
+       for (i = 0; i < adap->props.num_frontends; i++) {
+
+               adap->fe_adap[i].stream.udev      = adap->dev->udev;
+               if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
+                       adap->fe_adap[i].stream.complete =
+                               dvb_usb_data_complete_204;
+               else
+               if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
+                       adap->fe_adap[i].stream.complete =
+                               dvb_usb_data_complete_raw;
+               else
+               adap->fe_adap[i].stream.complete  = dvb_usb_data_complete;
+               adap->fe_adap[i].stream.user_priv = adap;
+               ret = usb_urb_init(&adap->fe_adap[i].stream,
+                                  &adap->props.fe[i].stream);
+               if (ret < 0)
+                       break;
+       }
+       return ret;
+}
+
+int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
+{
+       int i;
+       for (i = 0; i < adap->props.num_frontends; i++)
+               usb_urb_exit(&adap->fe_adap[i].stream);
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
new file mode 100644 (file)
index 0000000..aab0f99
--- /dev/null
@@ -0,0 +1,483 @@
+/* dvb-usb.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * the headerfile, all dvb-usb-drivers have to include.
+ *
+ * TODO: clean-up the structures for unused fields and update the comments
+ */
+#ifndef __DVB_USB_H__
+#define __DVB_USB_H__
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/mutex.h>
+#include <media/rc-core.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+
+#include "dvb-pll.h"
+
+#include "dvb-usb-ids.h"
+
+/* debug */
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var,level,args...) \
+           do { if ((var & level)) { printk(args); } } while (0)
+
+#define debug_dump(b,l,func) {\
+       int loop_; \
+       for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
+       func("\n");\
+}
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define debug_dump(b,l,func)
+
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+
+#endif
+
+/* generic log methods - taken from usb.h */
+#ifndef DVB_USB_LOG_PREFIX
+ #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
+#endif
+
+#undef err
+#define err(format, arg...)  printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+/**
+ * struct dvb_usb_device_description - name and its according USB IDs
+ * @name: real name of the box, regardless which DVB USB device class is in use
+ * @cold_ids: array of struct usb_device_id which describe the device in
+ *  pre-firmware state
+ * @warm_ids: array of struct usb_device_id which describe the device in
+ *  post-firmware state
+ *
+ * Each DVB USB device class can have one or more actual devices, this struct
+ * assigns a name to it.
+ */
+struct dvb_usb_device_description {
+       const char *name;
+
+#define DVB_USB_ID_MAX_NUM 15
+       struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
+       struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
+};
+
+static inline u8 rc5_custom(struct rc_map_table *key)
+{
+       return (key->scancode >> 8) & 0xff;
+}
+
+static inline u8 rc5_data(struct rc_map_table *key)
+{
+       return key->scancode & 0xff;
+}
+
+static inline u16 rc5_scan(struct rc_map_table *key)
+{
+       return key->scancode & 0xffff;
+}
+
+struct dvb_usb_device;
+struct dvb_usb_adapter;
+struct usb_data_stream;
+
+/**
+ * Properties of USB streaming - TODO this structure should be somewhere else
+ * describes the kind of USB transfer used for data-streaming.
+ *  (BULK or ISOC)
+ */
+struct usb_data_stream_properties {
+#define USB_BULK  1
+#define USB_ISOC  2
+       int type;
+       int count;
+       int endpoint;
+
+       union {
+               struct {
+                       int buffersize; /* per URB */
+               } bulk;
+               struct {
+                       int framesperurb;
+                       int framesize;
+                       int interval;
+               } isoc;
+       } u;
+};
+
+/**
+ * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
+ *    A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
+ * @caps: capabilities of the DVB USB device.
+ * @pid_filter_count: number of PID filter position in the optional hardware
+ *  PID-filter.
+ * @num_frontends: number of frontends of the DVB USB adapter.
+ * @frontend_ctrl: called to power on/off active frontend.
+ * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
+ *  device (not URB submitting/killing).
+ * @pid_filter_ctrl: called to en/disable the PID filter, if any.
+ * @pid_filter: called to set/unset a PID for filtering.
+ * @frontend_attach: called to attach the possible frontends (fill fe-field
+ *  of struct dvb_usb_device).
+ * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
+ *  pll_desc and pll_init_buf of struct dvb_usb_device).
+ * @stream: configuration of the USB streaming
+ */
+struct dvb_usb_adapter_fe_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
+#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS         0x08
+#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD         0x10
+       int caps;
+       int pid_filter_count;
+
+       int (*streaming_ctrl)  (struct dvb_usb_adapter *, int);
+       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+       int (*pid_filter)      (struct dvb_usb_adapter *, int, u16, int);
+
+       int (*frontend_attach) (struct dvb_usb_adapter *);
+       int (*tuner_attach)    (struct dvb_usb_adapter *);
+
+       struct usb_data_stream_properties stream;
+
+       int size_of_priv;
+};
+
+#define MAX_NO_OF_FE_PER_ADAP 3
+struct dvb_usb_adapter_properties {
+       int size_of_priv;
+
+       int (*frontend_ctrl)   (struct dvb_frontend *, int);
+
+       int num_frontends;
+       struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP];
+};
+
+/**
+ * struct dvb_rc_legacy - old properties of remote controller
+ * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
+ *  remote control handling).
+ * @rc_map_size: number of items in @rc_map_table.
+ * @rc_query: called to query an event event.
+ * @rc_interval: time in ms between two queries.
+ */
+struct dvb_rc_legacy {
+/* remote control properties */
+#define REMOTE_NO_KEY_PRESSED      0x00
+#define REMOTE_KEY_PRESSED         0x01
+#define REMOTE_KEY_REPEAT          0x02
+       struct rc_map_table  *rc_map_table;
+       int rc_map_size;
+       int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
+       int rc_interval;
+};
+
+/**
+ * struct dvb_rc properties of remote controller, using rc-core
+ * @rc_codes: name of rc codes table
+ * @protocol: type of protocol(s) currently used by the driver
+ * @allowed_protos: protocol(s) supported by the driver
+ * @driver_type: Used to point if a device supports raw mode
+ * @change_protocol: callback to change protocol
+ * @rc_query: called to query an event event.
+ * @rc_interval: time in ms between two queries.
+ * @bulk_mode: device supports bulk mode for RC (disable polling mode)
+ */
+struct dvb_rc {
+       char *rc_codes;
+       u64 protocol;
+       u64 allowed_protos;
+       enum rc_driver_type driver_type;
+       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       char *module_name;
+       int (*rc_query) (struct dvb_usb_device *d);
+       int rc_interval;
+       bool bulk_mode;                         /* uses bulk mode */
+};
+
+/**
+ * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one
+ *                    based on rc-core
+ * This is initialized/used only inside dvb-usb-remote.c.
+ * It shouldn't be set by the drivers.
+ */
+enum dvb_usb_mode {
+       DVB_RC_LEGACY,
+       DVB_RC_CORE,
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
+ * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
+ *  download.
+ * @firmware: name of the firmware file.
+ * @download_firmware: called to download the firmware when the usb_ctrl is
+ *  DEVICE_SPECIFIC.
+ * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
+ *  so do the warm initialization right after it
+ *
+ * @size_of_priv: how many bytes shall be allocated for the private field
+ *  of struct dvb_usb_device.
+ *
+ * @power_ctrl: called to enable/disable power of the device.
+ * @read_mac_address: called to read the MAC address of the device.
+ * @identify_state: called to determine the state (cold or warm), when it
+ *  is not distinguishable by the USB IDs.
+ *
+ * @rc: remote controller properties
+ *
+ * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
+ *
+ * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
+ *  endpoint which received control messages with bulk transfers. When this
+ *  is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
+ *  helper functions.
+ *
+ * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
+ *  endpoint for responses to control messages sent with bulk transfers via
+ *  the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
+ *  instead of the generic_bulk_ctrl_endpoint when reading usb responses in
+ *  the dvb_usb_generic_rw helper function.
+ *
+ * @num_device_descs: number of struct dvb_usb_device_description in @devices
+ * @devices: array of struct dvb_usb_device_description compatibles with these
+ *  properties.
+ */
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
+
+#define DVB_USB_IS_AN_I2C_ADAPTER            0x01
+       int caps;
+
+#define DEVICE_SPECIFIC 0
+#define CYPRESS_AN2135  1
+#define CYPRESS_AN2235  2
+#define CYPRESS_FX2     3
+       int        usb_ctrl;
+       int        (*download_firmware) (struct usb_device *, const struct firmware *);
+       const char *firmware;
+       int        no_reconnect;
+
+       int size_of_priv;
+
+       int num_adapters;
+       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+
+       int (*power_ctrl)       (struct dvb_usb_device *, int);
+       int (*read_mac_address) (struct dvb_usb_device *, u8 []);
+       int (*identify_state)   (struct usb_device *, struct dvb_usb_device_properties *,
+                       struct dvb_usb_device_description **, int *);
+
+       struct {
+               enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */
+               struct dvb_rc_legacy legacy;
+               struct dvb_rc core;
+       } rc;
+
+       struct i2c_algorithm *i2c_algo;
+
+       int generic_bulk_ctrl_endpoint;
+       int generic_bulk_ctrl_endpoint_response;
+
+       int num_device_descs;
+       struct dvb_usb_device_description devices[12];
+};
+
+/**
+ * struct usb_data_stream - generic object of an USB stream
+ * @buf_num: number of buffer allocated.
+ * @buf_size: size of each buffer in buf_list.
+ * @buf_list: array containing all allocate buffers for streaming.
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list.
+ *
+ * @urbs_initialized: number of URBs initialized.
+ * @urbs_submitted: number of URBs submitted.
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+       struct usb_device                 *udev;
+       struct usb_data_stream_properties  props;
+
+#define USB_STATE_INIT    0x00
+#define USB_STATE_URB_BUF 0x01
+       int state;
+
+       void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       int            buf_num;
+       unsigned long  buf_size;
+       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+       int urbs_initialized;
+       int urbs_submitted;
+
+       void *user_priv;
+};
+
+/**
+ * struct dvb_usb_adapter - a DVB adapter on a USB device
+ * @id: index of this adapter (starting with 0).
+ *
+ * @feedcount: number of reqested feeds (used for streaming-activation)
+ * @pid_filtering: is hardware pid_filtering used or not.
+ *
+ * @pll_addr: I2C address of the tuner for programming
+ * @pll_init: array containing the initialization buffer
+ * @pll_desc: pointer to the appropriate struct dvb_pll_desc
+ * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
+ *
+ * @dvb_adap: device's dvb_adapter.
+ * @dmxdev: device's dmxdev.
+ * @demux: device's software demuxer.
+ * @dvb_net: device's dvb_net interfaces.
+ * @dvb_frontend: device's frontend.
+ * @max_feed_count: how many feeds can be handled simultaneously by this
+ *  device
+ *
+ * @fe_init:  rerouted frontend-init (wakeup) function.
+ * @fe_sleep: rerouted frontend-sleep function.
+ *
+ * @stream: the usb data stream.
+ */
+struct dvb_usb_fe_adapter {
+       struct dvb_frontend *fe;
+
+       int (*fe_init)  (struct dvb_frontend *);
+       int (*fe_sleep) (struct dvb_frontend *);
+
+       struct usb_data_stream stream;
+
+       int pid_filtering;
+       int max_feed_count;
+
+       void *priv;
+};
+
+struct dvb_usb_adapter {
+       struct dvb_usb_device *dev;
+       struct dvb_usb_adapter_properties props;
+
+#define DVB_USB_ADAP_STATE_INIT 0x000
+#define DVB_USB_ADAP_STATE_DVB  0x001
+       int state;
+
+       u8  id;
+
+       int feedcount;
+
+       /* dvb */
+       struct dvb_adapter   dvb_adap;
+       struct dmxdev        dmxdev;
+       struct dvb_demux     demux;
+       struct dvb_net       dvb_net;
+
+       struct dvb_usb_fe_adapter fe_adap[MAX_NO_OF_FE_PER_ADAP];
+       int active_fe;
+       int num_frontends_initialized;
+
+       void *priv;
+};
+
+/**
+ * struct dvb_usb_device - object of a DVB USB device
+ * @props: copy of the struct dvb_usb_properties this device belongs to.
+ * @desc: pointer to the device's struct dvb_usb_device_description.
+ * @state: initialization and runtime state of the device.
+ *
+ * @powered: indicated whether the device is power or not.
+ *  Powered is in/decremented for each call to modify the state.
+ * @udev: pointer to the device's struct usb_device.
+ *
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
+ *
+ * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
+ *
+ * @rc_dev: rc device for the remote control (rc-core mode)
+ * @input_dev: input device for the remote control (legacy mode)
+ * @rc_query_work: struct work_struct frequent rc queries
+ * @last_event: last triggered event
+ * @last_state: last state (no, pressed, repeat)
+ * @owner: owner of the dvb_adapter
+ * @priv: private data of the actual driver (allocate by dvb-usb, size defined
+ *  in size_of_priv of dvb_usb_properties).
+ */
+struct dvb_usb_device {
+       struct dvb_usb_device_properties props;
+       struct dvb_usb_device_description *desc;
+
+       struct usb_device *udev;
+
+#define DVB_USB_STATE_INIT        0x000
+#define DVB_USB_STATE_I2C         0x001
+#define DVB_USB_STATE_DVB         0x002
+#define DVB_USB_STATE_REMOTE      0x004
+       int state;
+
+       int powered;
+
+       /* locking */
+       struct mutex usb_mutex;
+
+       /* i2c */
+       struct mutex i2c_mutex;
+       struct i2c_adapter i2c_adap;
+
+       int                    num_adapters_initialized;
+       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+
+       /* remote control */
+       struct rc_dev *rc_dev;
+       struct input_dev *input_dev;
+       char rc_phys[64];
+       struct delayed_work rc_query_work;
+       u32 last_event;
+       int last_state;
+
+       struct module *owner;
+
+       void *priv;
+};
+
+extern int dvb_usb_device_init(struct usb_interface *,
+                              struct dvb_usb_device_properties *,
+                              struct module *, struct dvb_usb_device **,
+                              short *adapter_nums);
+extern void dvb_usb_device_exit(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
+extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+/* commonly used remote control parsing */
+extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
+
+/* commonly used firmware download types and function */
+struct hexline {
+       u8 len;
+       u32 addr;
+       u8 type;
+       u8 data[255];
+       u8 chk;
+};
+extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
+extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
+
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_dvb.c b/drivers/media/usb/dvb-usb/dvb_usb_dvb.c
new file mode 100644 (file)
index 0000000..384fe8e
--- /dev/null
@@ -0,0 +1,403 @@
+/* dvb-usb-dvb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * linux-dvb API.
+ */
+#include "dvb_usb_common.h"
+
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_204(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
+}
+
+int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+
+       adap->stream.udev = adap_to_d(adap)->udev;
+       adap->stream.user_priv = adap;
+       adap->stream.complete = dvb_usb_data_complete;
+
+       return usb_urb_initv2(&adap->stream, &adap->props->stream);
+}
+
+int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+       usb_urb_exitv2(&adap->stream);
+
+       return 0;
+}
+
+/* does the complete input transfer handling */
+static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int count)
+{
+       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       pr_debug("%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: " \
+                       "%04x (%04d) at index %d '%s'\n", __func__, adap->id,
+                       adap->active_fe, dvbdmxfeed->type,
+                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
+                       dvbdmxfeed->pid, dvbdmxfeed->index,
+                       (count == 1) ? "on" : "off");
+
+       if (adap->active_fe == -1)
+               return -EINVAL;
+
+       adap->feed_count += count;
+
+       /* stop feeding if it is last pid */
+       if (adap->feed_count == 0) {
+               pr_debug("%s: stop feeding\n", __func__);
+               usb_urb_killv2(&adap->stream);
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(adap, 0);
+                       if (ret < 0) {
+                               pr_err("%s: streaming_ctrl() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+               mutex_unlock(&adap->sync_mutex);
+       }
+
+       /* activate the pid on the device pid filter */
+       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                       adap->pid_filtering &&
+                       adap->props->pid_filter)
+               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
+                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
+                       if (ret < 0)
+                               pr_err("%s: pid_filter() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+
+       /* start feeding if it is first pid */
+       if (adap->feed_count == 1 && count == 1) {
+               struct usb_data_stream_properties stream_props;
+               mutex_lock(&adap->sync_mutex);
+               pr_debug("%s: start feeding\n", __func__);
+
+               /* resolve input and output streaming paramters */
+               if (d->props->get_stream_config) {
+                       memcpy(&stream_props, &adap->props->stream,
+                               sizeof(struct usb_data_stream_properties));
+                       ret = d->props->get_stream_config(
+                                       adap->fe[adap->active_fe],
+                                       &adap->ts_type, &stream_props);
+                       if (ret < 0)
+                               goto err_mutex_unlock;
+               } else {
+                       stream_props = adap->props->stream;
+               }
+
+               switch (adap->ts_type) {
+               case DVB_USB_FE_TS_TYPE_204:
+                       adap->stream.complete = dvb_usb_data_complete_204;
+                       break;
+               case DVB_USB_FE_TS_TYPE_RAW:
+                       adap->stream.complete = dvb_usb_data_complete_raw;
+                       break;
+               case DVB_USB_FE_TS_TYPE_188:
+               default:
+                       adap->stream.complete = dvb_usb_data_complete;
+                       break;
+               }
+
+               usb_urb_submitv2(&adap->stream, &stream_props);
+
+               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                               adap->props->caps &
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+                               adap->props->pid_filter_ctrl) {
+                       ret = adap->props->pid_filter_ctrl(adap,
+                                       adap->pid_filtering);
+                       if (ret < 0) {
+                               pr_err("%s: pid_filter_ctrl() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(adap, 1);
+                       if (ret < 0) {
+                               pr_err("%s: streaming_ctrl() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+       }
+
+       return 0;
+err_mutex_unlock:
+       mutex_unlock(&adap->sync_mutex);
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
+}
+
+int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+
+       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
+                       &d->udev->dev, d->props->adapter_nr);
+       if (ret < 0) {
+               pr_debug("%s: dvb_register_adapter() failed=%d\n", __func__,
+                               ret);
+               goto err;
+       }
+
+       adap->dvb_adap.priv = adap;
+
+       if (d->props->read_mac_address) {
+               ret = d->props->read_mac_address(adap,
+                               adap->dvb_adap.proposed_mac);
+               if (ret < 0)
+                       goto err_dmx;
+
+               pr_info("%s: MAC address: %pM\n", KBUILD_MODNAME,
+                               adap->dvb_adap.proposed_mac);
+       }
+
+       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       adap->demux.priv             = adap;
+       adap->demux.filternum        = 0;
+       if (adap->demux.filternum < adap->max_feed_count)
+               adap->demux.filternum = adap->max_feed_count;
+       adap->demux.feednum          = adap->demux.filternum;
+       adap->demux.start_feed       = dvb_usb_start_feed;
+       adap->demux.stop_feed        = dvb_usb_stop_feed;
+       adap->demux.write_to_decoder = NULL;
+       ret = dvb_dmx_init(&adap->demux);
+       if (ret < 0) {
+               pr_err("%s: dvb_dmx_init() failed=%d\n", KBUILD_MODNAME, ret);
+               goto err_dmx;
+       }
+
+       adap->dmxdev.filternum       = adap->demux.filternum;
+       adap->dmxdev.demux           = &adap->demux.dmx;
+       adap->dmxdev.capabilities    = 0;
+       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
+       if (ret < 0) {
+               pr_err("%s: dvb_dmxdev_init() failed=%d\n", KBUILD_MODNAME,
+                               ret);
+               goto err_dmx_dev;
+       }
+
+       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
+       if (ret < 0) {
+               pr_err("%s: dvb_net_init() failed=%d\n", KBUILD_MODNAME, ret);
+               goto err_net_init;
+       }
+
+       mutex_init(&adap->sync_mutex);
+
+       return 0;
+err_net_init:
+       dvb_dmxdev_release(&adap->dmxdev);
+err_dmx_dev:
+       dvb_dmx_release(&adap->demux);
+err_dmx:
+       dvb_unregister_adapter(&adap->dvb_adap);
+err:
+       adap->dvb_adap.priv = NULL;
+       return ret;
+}
+
+int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+
+       if (adap->dvb_adap.priv) {
+               dvb_net_release(&adap->dvb_net);
+               adap->demux.dmx.close(&adap->demux.dmx);
+               dvb_dmxdev_release(&adap->dmxdev);
+               dvb_dmx_release(&adap->demux);
+               dvb_unregister_adapter(&adap->dvb_adap);
+       }
+
+       return 0;
+}
+
+static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
+
+       ret = dvb_usbv2_device_power_ctrl(d, 1);
+       if (ret < 0)
+               goto err;
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 1);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (adap->fe_init[fe->id]) {
+               ret = adap->fe_init[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       adap->active_fe = fe->id;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
+
+       if (adap->fe_sleep[fe->id]) {
+               ret = adap->fe_sleep[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 0);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_device_power_ctrl(d, 0);
+       if (ret < 0)
+               goto err;
+
+       adap->active_fe = -1;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
+{
+       int ret, i, count_registered = 0;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+
+       memset(adap->fe, 0, sizeof(adap->fe));
+       adap->active_fe = -1;
+
+       if (d->props->frontend_attach) {
+               ret = d->props->frontend_attach(adap);
+               if (ret < 0) {
+                       pr_debug("%s: frontend_attach() failed=%d\n", __func__,
+                                       ret);
+                       goto err_dvb_frontend_detach;
+               }
+       } else {
+               pr_debug("%s: frontend_attach() do not exists\n", __func__);
+               ret = 0;
+               goto err;
+       }
+
+       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
+               adap->fe[i]->id = i;
+
+               /* re-assign sleep and wakeup functions */
+               adap->fe_init[i] = adap->fe[i]->ops.init;
+               adap->fe[i]->ops.init  = dvb_usb_fe_wakeup;
+               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
+               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
+
+               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
+               if (ret < 0) {
+                       pr_err("%s: frontend%d registration failed\n",
+                                       KBUILD_MODNAME, i);
+                       goto err_dvb_unregister_frontend;
+               }
+
+               count_registered++;
+       }
+
+       if (d->props->tuner_attach) {
+               ret = d->props->tuner_attach(adap);
+               if (ret < 0) {
+                       pr_debug("%s: tuner_attach() failed=%d\n", __func__,
+                                       ret);
+                       goto err_dvb_unregister_frontend;
+               }
+       }
+
+       return 0;
+
+err_dvb_unregister_frontend:
+       for (i = count_registered - 1; i >= 0; i--)
+               dvb_unregister_frontend(adap->fe[i]);
+
+err_dvb_frontend_detach:
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i])
+                       dvb_frontend_detach(adap->fe[i]);
+       }
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+{
+       int i;
+       pr_debug("%s: adap=%d\n", __func__, adap->id);
+
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i]) {
+                       dvb_unregister_frontend(adap->fe[i]);
+                       dvb_frontend_detach(adap->fe[i]);
+               }
+       }
+
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_remote.c b/drivers/media/usb/dvb-usb/dvb_usb_remote.c
new file mode 100644 (file)
index 0000000..f856ab6
--- /dev/null
@@ -0,0 +1,117 @@
+/* dvb-usb-remote.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing the input-device and for
+ * handling remote-control-queries.
+ */
+#include "dvb_usb_common.h"
+#include <linux/usb/input.h>
+
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void dvb_usb_read_remote_control(struct work_struct *work)
+{
+       struct dvb_usb_device *d = container_of(work,
+                       struct dvb_usb_device, rc_query_work.work);
+       int ret;
+
+       /* TODO: need a lock here.  We can simply skip checking for the remote
+          control if we're busy. */
+
+       /* when the parameter has been set to 1 via sysfs while the
+        * driver was running, or when bulk mode is enabled after IR init
+        */
+       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
+               return;
+
+       ret = d->rc.query(d);
+       if (ret < 0)
+               pr_err("%s: error %d while querying for an remote control " \
+                               "event\n", KBUILD_MODNAME, ret);
+
+       schedule_delayed_work(&d->rc_query_work,
+                             msecs_to_jiffies(d->rc.interval));
+}
+
+int dvb_usbv2_remote_init(struct dvb_usb_device *d)
+{
+       int ret;
+       struct rc_dev *dev;
+
+       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
+               return 0;
+
+       ret = d->props->get_rc_config(d, &d->rc);
+       if (ret < 0)
+               goto err;
+
+       dev = rc_allocate_device();
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev->dev.parent = &d->udev->dev;
+       dev->input_name = "IR-receiver inside an USB DVB receiver";
+       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+       dev->input_phys = d->rc_phys;
+       usb_to_input_id(d->udev, &dev->input_id);
+       /* TODO: likely RC-core should took const char * */
+       dev->driver_name = (char *) d->props->driver_name;
+       dev->driver_type = d->rc.driver_type;
+       dev->allowed_protos = d->rc.allowed_protos;
+       dev->change_protocol = d->rc.change_protocol;
+       dev->priv = d;
+       /* select used keymap */
+       if (d->rc.map_name)
+               dev->map_name = d->rc.map_name;
+       else if (d->rc_map)
+               dev->map_name = d->rc_map;
+       else
+               dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
+
+       ret = rc_register_device(dev);
+       if (ret < 0) {
+               rc_free_device(dev);
+               goto err;
+       }
+
+       d->input_dev = NULL;
+       d->rc_dev = dev;
+
+       /* start polling if needed */
+       if (d->rc.query && !d->rc.bulk_mode) {
+               /* initialize a work queue for handling polling */
+               INIT_DELAYED_WORK(&d->rc_query_work,
+                               dvb_usb_read_remote_control);
+               pr_info("%s: schedule remote query interval to %d msecs\n",
+                               KBUILD_MODNAME, d->rc.interval);
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+       }
+
+       d->state |= DVB_USB_STATE_REMOTE;
+
+       return 0;
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
+{
+       if (d->state & DVB_USB_STATE_REMOTE) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+               rc_unregister_device(d->rc_dev);
+       }
+
+       d->state &= ~DVB_USB_STATE_REMOTE;
+
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
new file mode 100644 (file)
index 0000000..9382895
--- /dev/null
@@ -0,0 +1,1951 @@
+/* DVB USB framework compliant Linux driver for the
+ *     DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
+ *     TeVii S600, S630, S650, S660, S480,
+ *     Prof 1100, 7500,
+ *     Geniatech SU3000 Cards
+ * Copyright (C) 2008-2011 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dw2102.h"
+#include "si21xx.h"
+#include "stv0299.h"
+#include "z0194a.h"
+#include "stv0288.h"
+#include "stb6000.h"
+#include "eds1547.h"
+#include "cx24116.h"
+#include "tda1002x.h"
+#include "mt312.h"
+#include "zl10039.h"
+#include "ds3000.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
+
+#ifndef USB_PID_DW2102
+#define USB_PID_DW2102 0x2102
+#endif
+
+#ifndef USB_PID_DW2104
+#define USB_PID_DW2104 0x2104
+#endif
+
+#ifndef USB_PID_DW3101
+#define USB_PID_DW3101 0x3101
+#endif
+
+#ifndef USB_PID_CINERGY_S
+#define USB_PID_CINERGY_S 0x0064
+#endif
+
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
+#endif
+
+#ifndef USB_PID_TEVII_S650
+#define USB_PID_TEVII_S650 0xd650
+#endif
+
+#ifndef USB_PID_TEVII_S660
+#define USB_PID_TEVII_S660 0xd660
+#endif
+
+#ifndef USB_PID_TEVII_S480_1
+#define USB_PID_TEVII_S480_1 0xd481
+#endif
+
+#ifndef USB_PID_TEVII_S480_2
+#define USB_PID_TEVII_S480_2 0xd482
+#endif
+
+#ifndef USB_PID_PROF_1100
+#define USB_PID_PROF_1100 0xb012
+#endif
+
+#define DW210X_READ_MSG 0
+#define DW210X_WRITE_MSG 1
+
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+/* on my own*/
+#define DW2102_VOLTAGE_CTRL (0x1800)
+#define SU3000_STREAM_CTRL (0x1900)
+#define DW2102_RC_QUERY (0x1a00)
+#define DW2102_LED_CTRL (0x1b00)
+
+#define        err_str "did not find the firmware file. (%s) " \
+               "Please see linux/Documentation/dvb/ for more details " \
+               "on firmware-problems."
+
+struct rc_map_dvb_usb_table_table {
+       struct rc_map_table *rc_keys;
+       int rc_keys_size;
+};
+
+struct su3000_state {
+       u8 initialized;
+};
+
+struct s6x0_state {
+       int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
+};
+
+/* debug */
+static int dvb_usb_dw2102_debug;
+module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
+                                               DVB_USB_DEBUG_STATUS);
+
+/* keymaps */
+static int ir_keymap;
+module_param_named(keymap, ir_keymap, int, 0644);
+MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ..."
+                       " 256=none");
+
+/* demod probe */
+static int demod_probe = 1;
+module_param_named(demod, demod_probe, int, 0644);
+MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
+                       "4=stv0903+stb6100(or-able)).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
+                       u16 index, u8 * data, u16 len, int flags)
+{
+       int ret;
+       u8 *u8buf;
+       unsigned int pipe = (flags == DW210X_READ_MSG) ?
+                               usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
+       u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+       u8buf = kmalloc(len, GFP_KERNEL);
+       if (!u8buf)
+               return -ENOMEM;
+
+
+       if (flags == DW210X_WRITE_MSG)
+               memcpy(u8buf, data, len);
+       ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
+                               value, index , u8buf, len, 2000);
+
+       if (flags == DW210X_READ_MSG)
+               memcpy(data, u8buf, len);
+
+       kfree(u8buf);
+       return ret;
+}
+
+/* I2C */
+static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+               int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i = 0;
+       u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
+       u16 value;
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       switch (num) {
+       case 2:
+               /* read stv0299 register */
+               value = msg[0].buf[0];/* register */
+               for (i = 0; i < msg[1].len; i++) {
+                       dw210x_op_rw(d->udev, 0xb5, value + i, 0,
+                                       buf6, 2, DW210X_READ_MSG);
+                       msg[1].buf[i] = buf6[0];
+               }
+               break;
+       case 1:
+               switch (msg[0].addr) {
+               case 0x68:
+                       /* write to stv0299 register */
+                       buf6[0] = 0x2a;
+                       buf6[1] = msg[0].buf[0];
+                       buf6[2] = msg[0].buf[1];
+                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                       buf6, 3, DW210X_WRITE_MSG);
+                       break;
+               case 0x60:
+                       if (msg[0].flags == 0) {
+                       /* write to tuner pll */
+                               buf6[0] = 0x2c;
+                               buf6[1] = 5;
+                               buf6[2] = 0xc0;
+                               buf6[3] = msg[0].buf[0];
+                               buf6[4] = msg[0].buf[1];
+                               buf6[5] = msg[0].buf[2];
+                               buf6[6] = msg[0].buf[3];
+                               dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                               buf6, 7, DW210X_WRITE_MSG);
+                       } else {
+                       /* read from tuner */
+                               dw210x_op_rw(d->udev, 0xb5, 0, 0,
+                                               buf6, 1, DW210X_READ_MSG);
+                               msg[0].buf[0] = buf6[0];
+                       }
+                       break;
+               case (DW2102_RC_QUERY):
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       buf6, 2, DW210X_READ_MSG);
+                       msg[0].buf[0] = buf6[0];
+                       msg[0].buf[1] = buf6[1];
+                       break;
+               case (DW2102_VOLTAGE_CTRL):
+                       buf6[0] = 0x30;
+                       buf6[1] = msg[0].buf[0];
+                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                       buf6, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+
+               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
+                                               struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       switch (num) {
+       case 2:
+               /* read si2109 register by number */
+               buf6[0] = msg[0].addr << 1;
+               buf6[1] = msg[0].len;
+               buf6[2] = msg[0].buf[0];
+               dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                               buf6, msg[0].len + 2, DW210X_WRITE_MSG);
+               /* read si2109 register */
+               dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
+                               buf6, msg[1].len + 2, DW210X_READ_MSG);
+               memcpy(msg[1].buf, buf6 + 2, msg[1].len);
+
+               break;
+       case 1:
+               switch (msg[0].addr) {
+               case 0x68:
+                       /* write to si2109 register */
+                       buf6[0] = msg[0].addr << 1;
+                       buf6[1] = msg[0].len;
+                       memcpy(buf6 + 2, msg[0].buf, msg[0].len);
+                       dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
+                                       msg[0].len + 2, DW210X_WRITE_MSG);
+                       break;
+               case(DW2102_RC_QUERY):
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       buf6, 2, DW210X_READ_MSG);
+                       msg[0].buf[0] = buf6[0];
+                       msg[0].buf[1] = buf6[1];
+                       break;
+               case(DW2102_VOLTAGE_CTRL):
+                       buf6[0] = 0x30;
+                       buf6[1] = msg[0].buf[0];
+                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                       buf6, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       switch (num) {
+       case 2: {
+               /* read */
+               /* first write first register number */
+               u8 ibuf[msg[1].len + 2], obuf[3];
+               obuf[0] = msg[0].addr << 1;
+               obuf[1] = msg[0].len;
+               obuf[2] = msg[0].buf[0];
+               dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+               /* second read registers */
+               dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
+                               ibuf, msg[1].len + 2, DW210X_READ_MSG);
+               memcpy(msg[1].buf, ibuf + 2, msg[1].len);
+
+               break;
+       }
+       case 1:
+               switch (msg[0].addr) {
+               case 0x68: {
+                       /* write to register */
+                       u8 obuf[msg[0].len + 2];
+                       obuf[0] = msg[0].addr << 1;
+                       obuf[1] = msg[0].len;
+                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
+                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               case 0x61: {
+                       /* write to tuner */
+                       u8 obuf[msg[0].len + 2];
+                       obuf[0] = msg[0].addr << 1;
+                       obuf[1] = msg[0].len;
+                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
+                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               case(DW2102_RC_QUERY): {
+                       u8 ibuf[2];
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       ibuf, 2, DW210X_READ_MSG);
+                       memcpy(msg[0].buf, ibuf , 2);
+                       break;
+               }
+               case(DW2102_VOLTAGE_CTRL): {
+                       u8 obuf[2];
+                       obuf[0] = 0x30;
+                       obuf[1] = msg[0].buf[0];
+                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                       obuf, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               }
+
+               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int len, i, j;
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (j = 0; j < num; j++) {
+               switch (msg[j].addr) {
+               case(DW2102_RC_QUERY): {
+                       u8 ibuf[2];
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       ibuf, 2, DW210X_READ_MSG);
+                       memcpy(msg[j].buf, ibuf , 2);
+                       break;
+               }
+               case(DW2102_VOLTAGE_CTRL): {
+                       u8 obuf[2];
+                       obuf[0] = 0x30;
+                       obuf[1] = msg[j].buf[0];
+                       dw210x_op_rw(d->udev, 0xb2, 0, 0,
+                                       obuf, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               /*case 0x55: cx24116
+               case 0x6a: stv0903
+               case 0x68: ds3000, stv0903
+               case 0x60: ts2020, stv6110, stb6100 */
+               default: {
+                       if (msg[j].flags == I2C_M_RD) {
+                               /* read registers */
+                               u8  ibuf[msg[j].len + 2];
+                               dw210x_op_rw(d->udev, 0xc3,
+                                               (msg[j].addr << 1) + 1, 0,
+                                               ibuf, msg[j].len + 2,
+                                               DW210X_READ_MSG);
+                               memcpy(msg[j].buf, ibuf + 2, msg[j].len);
+                       mdelay(10);
+                       } else if (((msg[j].buf[0] == 0xb0) &&
+                                               (msg[j].addr == 0x68)) ||
+                                               ((msg[j].buf[0] == 0xf7) &&
+                                               (msg[j].addr == 0x55))) {
+                               /* write firmware */
+                               u8 obuf[19];
+                               obuf[0] = msg[j].addr << 1;
+                               obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
+                               obuf[2] = msg[j].buf[0];
+                               len = msg[j].len - 1;
+                               i = 1;
+                               do {
+                                       memcpy(obuf + 3, msg[j].buf + i,
+                                                       (len > 16 ? 16 : len));
+                                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                               obuf, (len > 16 ? 16 : len) + 3,
+                                               DW210X_WRITE_MSG);
+                                       i += 16;
+                                       len -= 16;
+                               } while (len > 0);
+                       } else {
+                               /* write registers */
+                               u8 obuf[msg[j].len + 2];
+                               obuf[0] = msg[j].addr << 1;
+                               obuf[1] = msg[j].len;
+                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
+                               dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                               obuf, msg[j].len + 2,
+                                               DW210X_WRITE_MSG);
+                       }
+                       break;
+               }
+               }
+
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                                               int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       switch (num) {
+       case 2: {
+               /* read */
+               /* first write first register number */
+               u8 ibuf[msg[1].len + 2], obuf[3];
+               obuf[0] = msg[0].addr << 1;
+               obuf[1] = msg[0].len;
+               obuf[2] = msg[0].buf[0];
+               dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                               obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+               /* second read registers */
+               dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
+                               ibuf, msg[1].len + 2, DW210X_READ_MSG);
+               memcpy(msg[1].buf, ibuf + 2, msg[1].len);
+
+               break;
+       }
+       case 1:
+               switch (msg[0].addr) {
+               case 0x60:
+               case 0x0c: {
+                       /* write to register */
+                       u8 obuf[msg[0].len + 2];
+                       obuf[0] = msg[0].addr << 1;
+                       obuf[1] = msg[0].len;
+                       memcpy(obuf + 2, msg[0].buf, msg[0].len);
+                       dw210x_op_rw(d->udev, 0xc2, 0, 0,
+                                       obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               case(DW2102_RC_QUERY): {
+                       u8 ibuf[2];
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       ibuf, 2, DW210X_READ_MSG);
+                       memcpy(msg[0].buf, ibuf , 2);
+                       break;
+               }
+               }
+
+               break;
+       }
+
+       for (i = 0; i < num; i++) {
+               deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
+                               msg[i].flags == 0 ? ">>>" : "<<<");
+               debug_dump(msg[i].buf, msg[i].len, deb_xfer);
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                                               int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct usb_device *udev;
+       int len, i, j;
+
+       if (!d)
+               return -ENODEV;
+       udev = d->udev;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (j = 0; j < num; j++) {
+               switch (msg[j].addr) {
+               case (DW2102_RC_QUERY): {
+                       u8 ibuf[5];
+                       dw210x_op_rw(d->udev, 0xb8, 0, 0,
+                                       ibuf, 5, DW210X_READ_MSG);
+                       memcpy(msg[j].buf, ibuf + 3, 2);
+                       break;
+               }
+               case (DW2102_VOLTAGE_CTRL): {
+                       u8 obuf[2];
+
+                       obuf[0] = 1;
+                       obuf[1] = msg[j].buf[1];/* off-on */
+                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
+                                       obuf, 2, DW210X_WRITE_MSG);
+                       obuf[0] = 3;
+                       obuf[1] = msg[j].buf[0];/* 13v-18v */
+                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
+                                       obuf, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               case (DW2102_LED_CTRL): {
+                       u8 obuf[2];
+
+                       obuf[0] = 5;
+                       obuf[1] = msg[j].buf[0];
+                       dw210x_op_rw(d->udev, 0x8a, 0, 0,
+                                       obuf, 2, DW210X_WRITE_MSG);
+                       break;
+               }
+               /*case 0x55: cx24116
+               case 0x6a: stv0903
+               case 0x68: ds3000, stv0903
+               case 0x60: ts2020, stv6110, stb6100
+               case 0xa0: eeprom */
+               default: {
+                       if (msg[j].flags == I2C_M_RD) {
+                               /* read registers */
+                               u8 ibuf[msg[j].len];
+                               dw210x_op_rw(d->udev, 0x91, 0, 0,
+                                               ibuf, msg[j].len,
+                                               DW210X_READ_MSG);
+                               memcpy(msg[j].buf, ibuf, msg[j].len);
+                               break;
+                       } else if ((msg[j].buf[0] == 0xb0) &&
+                                               (msg[j].addr == 0x68)) {
+                               /* write firmware */
+                               u8 obuf[19];
+                               obuf[0] = (msg[j].len > 16 ?
+                                               18 : msg[j].len + 1);
+                               obuf[1] = msg[j].addr << 1;
+                               obuf[2] = msg[j].buf[0];
+                               len = msg[j].len - 1;
+                               i = 1;
+                               do {
+                                       memcpy(obuf + 3, msg[j].buf + i,
+                                                       (len > 16 ? 16 : len));
+                                       dw210x_op_rw(d->udev, 0x80, 0, 0,
+                                               obuf, (len > 16 ? 16 : len) + 3,
+                                               DW210X_WRITE_MSG);
+                                       i += 16;
+                                       len -= 16;
+                               } while (len > 0);
+                       } else if (j < (num - 1)) {
+                               /* write register addr before read */
+                               u8 obuf[msg[j].len + 2];
+                               obuf[0] = msg[j + 1].len;
+                               obuf[1] = (msg[j].addr << 1);
+                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
+                               dw210x_op_rw(d->udev,
+                                               udev->descriptor.idProduct ==
+                                               0x7500 ? 0x92 : 0x90, 0, 0,
+                                               obuf, msg[j].len + 2,
+                                               DW210X_WRITE_MSG);
+                               break;
+                       } else {
+                               /* write registers */
+                               u8 obuf[msg[j].len + 2];
+                               obuf[0] = msg[j].len + 1;
+                               obuf[1] = (msg[j].addr << 1);
+                               memcpy(obuf + 2, msg[j].buf, msg[j].len);
+                               dw210x_op_rw(d->udev, 0x80, 0, 0,
+                                               obuf, msg[j].len + 2,
+                                               DW210X_WRITE_MSG);
+                               break;
+                       }
+                       break;
+               }
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                                               int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       u8 obuf[0x40], ibuf[0x40];
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       switch (num) {
+       case 1:
+               switch (msg[0].addr) {
+               case SU3000_STREAM_CTRL:
+                       obuf[0] = msg[0].buf[0] + 0x36;
+                       obuf[1] = 3;
+                       obuf[2] = 0;
+                       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+                               err("i2c transfer failed.");
+                       break;
+               case DW2102_RC_QUERY:
+                       obuf[0] = 0x10;
+                       if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+                               err("i2c transfer failed.");
+                       msg[0].buf[1] = ibuf[0];
+                       msg[0].buf[0] = ibuf[1];
+                       break;
+               default:
+                       /* always i2c write*/
+                       obuf[0] = 0x08;
+                       obuf[1] = msg[0].addr;
+                       obuf[2] = msg[0].len;
+
+                       memcpy(&obuf[3], msg[0].buf, msg[0].len);
+
+                       if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
+                                               ibuf, 1, 0) < 0)
+                               err("i2c transfer failed.");
+
+               }
+               break;
+       case 2:
+               /* always i2c read */
+               obuf[0] = 0x09;
+               obuf[1] = msg[0].len;
+               obuf[2] = msg[1].len;
+               obuf[3] = msg[0].addr;
+               memcpy(&obuf[4], msg[0].buf, msg[0].len);
+
+               if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
+                                       ibuf, msg[1].len + 1, 0) < 0)
+                       err("i2c transfer failed.");
+
+               memcpy(msg[1].buf, &ibuf[1], msg[1].len);
+               break;
+       default:
+               warn("more than 2 i2c messages at a time is not handled yet.");
+               break;
+       }
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dw2102_i2c_algo = {
+       .master_xfer = dw2102_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm dw2102_serit_i2c_algo = {
+       .master_xfer = dw2102_serit_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm dw2102_earda_i2c_algo = {
+       .master_xfer = dw2102_earda_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm dw2104_i2c_algo = {
+       .master_xfer = dw2104_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm dw3101_i2c_algo = {
+       .master_xfer = dw3101_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm s6x0_i2c_algo = {
+       .master_xfer = s6x0_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static struct i2c_algorithm su3000_i2c_algo = {
+       .master_xfer = su3000_i2c_transfer,
+       .functionality = dw210x_i2c_func,
+};
+
+static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+       int i;
+       u8 ibuf[] = {0, 0};
+       u8 eeprom[256], eepromline[16];
+
+       for (i = 0; i < 256; i++) {
+               if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
+                       err("read eeprom failed.");
+                       return -1;
+               } else {
+                       eepromline[i%16] = ibuf[0];
+                       eeprom[i] = ibuf[0];
+               }
+               if ((i % 16) == 15) {
+                       deb_xfer("%02x: ", i - 15);
+                       debug_dump(eepromline, 16, deb_xfer);
+               }
+       }
+
+       memcpy(mac, eeprom + 8, 6);
+       return 0;
+};
+
+static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+       int i, ret;
+       u8 ibuf[] = { 0 }, obuf[] = { 0 };
+       u8 eeprom[256], eepromline[16];
+       struct i2c_msg msg[] = {
+               {
+                       .addr = 0xa0 >> 1,
+                       .flags = 0,
+                       .buf = obuf,
+                       .len = 1,
+               }, {
+                       .addr = 0xa0 >> 1,
+                       .flags = I2C_M_RD,
+                       .buf = ibuf,
+                       .len = 1,
+               }
+       };
+
+       for (i = 0; i < 256; i++) {
+               obuf[0] = i;
+               ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
+               if (ret != 2) {
+                       err("read eeprom failed.");
+                       return -1;
+               } else {
+                       eepromline[i % 16] = ibuf[0];
+                       eeprom[i] = ibuf[0];
+               }
+
+               if ((i % 16) == 15) {
+                       deb_xfer("%02x: ", i - 15);
+                       debug_dump(eepromline, 16, deb_xfer);
+               }
+       }
+
+       memcpy(mac, eeprom + 16, 6);
+       return 0;
+};
+
+static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       static u8 command_start[] = {0x00};
+       static u8 command_stop[] = {0x01};
+       struct i2c_msg msg = {
+               .addr = SU3000_STREAM_CTRL,
+               .flags = 0,
+               .buf = onoff ? command_start : command_stop,
+               .len = 1
+       };
+
+       i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
+
+       return 0;
+}
+
+static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
+{
+       struct su3000_state *state = (struct su3000_state *)d->priv;
+       u8 obuf[] = {0xde, 0};
+
+       info("%s: %d, initialized %d\n", __func__, i, state->initialized);
+
+       if (i && !state->initialized) {
+               state->initialized = 1;
+               /* reset board */
+               dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
+       }
+
+       return 0;
+}
+
+static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+       int i;
+       u8 obuf[] = { 0x1f, 0xf0 };
+       u8 ibuf[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = 0x51,
+                       .flags = 0,
+                       .buf = obuf,
+                       .len = 2,
+               }, {
+                       .addr = 0x51,
+                       .flags = I2C_M_RD,
+                       .buf = ibuf,
+                       .len = 1,
+
+               }
+       };
+
+       for (i = 0; i < 6; i++) {
+               obuf[1] = 0xf0 + i;
+               if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
+                       break;
+               else
+                       mac[i] = ibuf[0];
+
+               debug_dump(mac, 6, printk);
+       }
+
+       return 0;
+}
+
+static int su3000_identify_state(struct usb_device *udev,
+                                struct dvb_usb_device_properties *props,
+                                struct dvb_usb_device_description **desc,
+                                int *cold)
+{
+       info("%s\n", __func__);
+
+       *cold = 0;
+       return 0;
+}
+
+static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       static u8 command_13v[] = {0x00, 0x01};
+       static u8 command_18v[] = {0x01, 0x01};
+       static u8 command_off[] = {0x00, 0x00};
+       struct i2c_msg msg = {
+               .addr = DW2102_VOLTAGE_CTRL,
+               .flags = 0,
+               .buf = command_off,
+               .len = 2,
+       };
+
+       struct dvb_usb_adapter *udev_adap =
+               (struct dvb_usb_adapter *)(fe->dvb->priv);
+       if (voltage == SEC_VOLTAGE_18)
+               msg.buf = command_18v;
+       else if (voltage == SEC_VOLTAGE_13)
+               msg.buf = command_13v;
+
+       i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
+
+       return 0;
+}
+
+static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct dvb_usb_adapter *d =
+               (struct dvb_usb_adapter *)(fe->dvb->priv);
+       struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
+
+       dw210x_set_voltage(fe, voltage);
+       if (st->old_set_voltage)
+               st->old_set_voltage(fe, voltage);
+
+       return 0;
+}
+
+static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
+{
+       static u8 led_off[] = { 0 };
+       static u8 led_on[] = { 1 };
+       struct i2c_msg msg = {
+               .addr = DW2102_LED_CTRL,
+               .flags = 0,
+               .buf = led_off,
+               .len = 1
+       };
+       struct dvb_usb_adapter *udev_adap =
+               (struct dvb_usb_adapter *)(fe->dvb->priv);
+
+       if (offon)
+               msg.buf = led_on;
+       i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
+}
+
+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 cx24116_config dw2104_config = {
+       .demod_address = 0x55,
+       .mpg_clk_pos_pol = 0x01,
+};
+
+static struct si21xx_config serit_sp1511lhb_config = {
+       .demod_address = 0x68,
+       .min_delay_ms = 100,
+
+};
+
+static struct tda10023_config dw3101_tda10023_config = {
+       .demod_address = 0x0c,
+       .invert = 1,
+};
+
+static struct mt312_config zl313_config = {
+       .demod_address = 0x0e,
+};
+
+static struct ds3000_config dw2104_ds3000_config = {
+       .demod_address = 0x68,
+};
+
+static struct stv0900_config dw2104a_stv0900_config = {
+       .demod_address = 0x6a,
+       .demod_mode = 0,
+       .xtal = 27000000,
+       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+       .diseqc_mode = 2,/* 2/3 PWM */
+       .tun1_maddress = 0,/* 0x60 */
+       .tun1_adc = 0,/* 2 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stb6100_config dw2104a_stb6100_config = {
+       .tuner_address = 0x60,
+       .refclock = 27000000,
+};
+
+static struct stv0900_config dw2104_stv0900_config = {
+       .demod_address = 0x68,
+       .demod_mode = 0,
+       .xtal = 8000000,
+       .clkmode = 3,
+       .diseqc_mode = 2,
+       .tun1_maddress = 0,
+       .tun1_adc = 1,/* 1 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stv6110_config dw2104_stv6110_config = {
+       .i2c_address = 0x60,
+       .mclk = 16000000,
+       .clk_div = 1,
+};
+
+static struct stv0900_config prof_7500_stv0900_config = {
+       .demod_address = 0x6a,
+       .demod_mode = 0,
+       .xtal = 27000000,
+       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+       .diseqc_mode = 2,/* 2/3 PWM */
+       .tun1_maddress = 0,/* 0x60 */
+       .tun1_adc = 0,/* 2 Vpp */
+       .path1_mode = 3,
+       .tun1_type = 3,
+       .set_lock_led = dw210x_led_ctrl,
+};
+
+static struct ds3000_config su3000_ds3000_config = {
+       .demod_address = 0x68,
+       .ci_mode = 1,
+};
+
+static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
+{
+       struct dvb_tuner_ops *tuner_ops = NULL;
+
+       if (demod_probe & 4) {
+               d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
+                               &d->dev->i2c_adap, 0);
+               if (d->fe_adap[0].fe != NULL) {
+                       if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
+                                       &dw2104a_stb6100_config,
+                                       &d->dev->i2c_adap)) {
+                               tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
+                               tuner_ops->set_frequency = stb6100_set_freq;
+                               tuner_ops->get_frequency = stb6100_get_freq;
+                               tuner_ops->set_bandwidth = stb6100_set_bandw;
+                               tuner_ops->get_bandwidth = stb6100_get_bandw;
+                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached STV0900+STB6100!\n");
+                               return 0;
+                       }
+               }
+       }
+
+       if (demod_probe & 2) {
+               d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
+                               &d->dev->i2c_adap, 0);
+               if (d->fe_adap[0].fe != NULL) {
+                       if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
+                                       &dw2104_stv6110_config,
+                                       &d->dev->i2c_adap)) {
+                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached STV0900+STV6110A!\n");
+                               return 0;
+                       }
+               }
+       }
+
+       if (demod_probe & 1) {
+               d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
+                               &d->dev->i2c_adap);
+               if (d->fe_adap[0].fe != NULL) {
+                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached cx24116!\n");
+                       return 0;
+               }
+       }
+
+       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+                       &d->dev->i2c_adap);
+       if (d->fe_adap[0].fe != NULL) {
+               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+               info("Attached DS3000!\n");
+               return 0;
+       }
+
+       return -EIO;
+}
+
+static struct dvb_usb_device_properties dw2102_properties;
+static struct dvb_usb_device_properties dw2104_properties;
+static struct dvb_usb_device_properties s6x0_properties;
+
+static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
+{
+       if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
+               /*dw2102_properties.adapter->tuner_attach = NULL;*/
+               d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
+                                       &d->dev->i2c_adap);
+               if (d->fe_adap[0].fe != NULL) {
+                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached si21xx!\n");
+                       return 0;
+               }
+       }
+
+       if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
+               d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
+                                       &d->dev->i2c_adap);
+               if (d->fe_adap[0].fe != NULL) {
+                       if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
+                                       &d->dev->i2c_adap)) {
+                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                               info("Attached stv0288!\n");
+                               return 0;
+                       }
+               }
+       }
+
+       if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
+               /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
+               d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
+                                       &d->dev->i2c_adap);
+               if (d->fe_adap[0].fe != NULL) {
+                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached stv0299!\n");
+                       return 0;
+               }
+       }
+       return -EIO;
+}
+
+static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
+{
+       d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
+                               &d->dev->i2c_adap, 0x48);
+       if (d->fe_adap[0].fe != NULL) {
+               info("Attached tda10023!\n");
+               return 0;
+       }
+       return -EIO;
+}
+
+static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
+{
+       d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
+                       &d->dev->i2c_adap);
+       if (d->fe_adap[0].fe != NULL) {
+               if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
+                               &d->dev->i2c_adap)) {
+                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+                       info("Attached zl100313+zl10039!\n");
+                       return 0;
+               }
+       }
+
+       return -EIO;
+}
+
+static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
+{
+       u8 obuf[] = {7, 1};
+
+       d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
+                       &d->dev->i2c_adap);
+
+       if (d->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
+               return -EIO;
+
+       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+
+       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
+       info("Attached stv0288+stb6000!\n");
+
+       return 0;
+
+}
+
+static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
+{
+       struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
+       u8 obuf[] = {7, 1};
+
+       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+                       &d->dev->i2c_adap);
+
+       if (d->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
+       d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
+
+       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
+       info("Attached ds3000+ds2020!\n");
+
+       return 0;
+}
+
+static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
+{
+       u8 obuf[] = {7, 1};
+
+       d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
+                                       &d->dev->i2c_adap, 0);
+       if (d->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
+
+       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
+
+       info("Attached STV0900+STB6100A!\n");
+
+       return 0;
+}
+
+static int su3000_frontend_attach(struct dvb_usb_adapter *d)
+{
+       u8 obuf[3] = { 0xe, 0x80, 0 };
+       u8 ibuf[] = { 0 };
+
+       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+               err("command 0x0e transfer failed.");
+
+       obuf[0] = 0xe;
+       obuf[1] = 0x83;
+       obuf[2] = 0;
+
+       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+               err("command 0x0e transfer failed.");
+
+       obuf[0] = 0xe;
+       obuf[1] = 0x83;
+       obuf[2] = 1;
+
+       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+               err("command 0x0e transfer failed.");
+
+       obuf[0] = 0x51;
+
+       if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+               err("command 0x51 transfer failed.");
+
+       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
+                                       &d->dev->i2c_adap);
+       if (d->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       info("Attached DS3000!\n");
+
+       return 0;
+}
+
+static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
+               &adap->dev->i2c_adap, DVB_PLL_OPERA1);
+       return 0;
+}
+
+static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
+               &adap->dev->i2c_adap, DVB_PLL_TUA6034);
+
+       return 0;
+}
+
+static struct rc_map_table rc_map_dw210x_table[] = {
+       { 0xf80a, KEY_POWER2 },         /*power*/
+       { 0xf80c, KEY_MUTE },           /*mute*/
+       { 0xf811, KEY_1 },
+       { 0xf812, KEY_2 },
+       { 0xf813, KEY_3 },
+       { 0xf814, KEY_4 },
+       { 0xf815, KEY_5 },
+       { 0xf816, KEY_6 },
+       { 0xf817, KEY_7 },
+       { 0xf818, KEY_8 },
+       { 0xf819, KEY_9 },
+       { 0xf810, KEY_0 },
+       { 0xf81c, KEY_CHANNELUP },      /*ch+*/
+       { 0xf80f, KEY_CHANNELDOWN },    /*ch-*/
+       { 0xf81a, KEY_VOLUMEUP },       /*vol+*/
+       { 0xf80e, KEY_VOLUMEDOWN },     /*vol-*/
+       { 0xf804, KEY_RECORD },         /*rec*/
+       { 0xf809, KEY_FAVORITES },      /*fav*/
+       { 0xf808, KEY_REWIND },         /*rewind*/
+       { 0xf807, KEY_FASTFORWARD },    /*fast*/
+       { 0xf80b, KEY_PAUSE },          /*pause*/
+       { 0xf802, KEY_ESC },            /*cancel*/
+       { 0xf803, KEY_TAB },            /*tab*/
+       { 0xf800, KEY_UP },             /*up*/
+       { 0xf81f, KEY_OK },             /*ok*/
+       { 0xf801, KEY_DOWN },           /*down*/
+       { 0xf805, KEY_CAMERA },         /*cap*/
+       { 0xf806, KEY_STOP },           /*stop*/
+       { 0xf840, KEY_ZOOM },           /*full*/
+       { 0xf81e, KEY_TV },             /*tvmode*/
+       { 0xf81b, KEY_LAST },           /*recall*/
+};
+
+static struct rc_map_table rc_map_tevii_table[] = {
+       { 0xf80a, KEY_POWER },
+       { 0xf80c, KEY_MUTE },
+       { 0xf811, KEY_1 },
+       { 0xf812, KEY_2 },
+       { 0xf813, KEY_3 },
+       { 0xf814, KEY_4 },
+       { 0xf815, KEY_5 },
+       { 0xf816, KEY_6 },
+       { 0xf817, KEY_7 },
+       { 0xf818, KEY_8 },
+       { 0xf819, KEY_9 },
+       { 0xf810, KEY_0 },
+       { 0xf81c, KEY_MENU },
+       { 0xf80f, KEY_VOLUMEDOWN },
+       { 0xf81a, KEY_LAST },
+       { 0xf80e, KEY_OPEN },
+       { 0xf804, KEY_RECORD },
+       { 0xf809, KEY_VOLUMEUP },
+       { 0xf808, KEY_CHANNELUP },
+       { 0xf807, KEY_PVR },
+       { 0xf80b, KEY_TIME },
+       { 0xf802, KEY_RIGHT },
+       { 0xf803, KEY_LEFT },
+       { 0xf800, KEY_UP },
+       { 0xf81f, KEY_OK },
+       { 0xf801, KEY_DOWN },
+       { 0xf805, KEY_TUNER },
+       { 0xf806, KEY_CHANNELDOWN },
+       { 0xf840, KEY_PLAYPAUSE },
+       { 0xf81e, KEY_REWIND },
+       { 0xf81b, KEY_FAVORITES },
+       { 0xf81d, KEY_BACK },
+       { 0xf84d, KEY_FASTFORWARD },
+       { 0xf844, KEY_EPG },
+       { 0xf84c, KEY_INFO },
+       { 0xf841, KEY_AB },
+       { 0xf843, KEY_AUDIO },
+       { 0xf845, KEY_SUBTITLE },
+       { 0xf84a, KEY_LIST },
+       { 0xf846, KEY_F1 },
+       { 0xf847, KEY_F2 },
+       { 0xf85e, KEY_F3 },
+       { 0xf85c, KEY_F4 },
+       { 0xf852, KEY_F5 },
+       { 0xf85a, KEY_F6 },
+       { 0xf856, KEY_MODE },
+       { 0xf858, KEY_SWITCHVIDEOMODE },
+};
+
+static struct rc_map_table rc_map_tbs_table[] = {
+       { 0xf884, KEY_POWER },
+       { 0xf894, KEY_MUTE },
+       { 0xf887, KEY_1 },
+       { 0xf886, KEY_2 },
+       { 0xf885, KEY_3 },
+       { 0xf88b, KEY_4 },
+       { 0xf88a, KEY_5 },
+       { 0xf889, KEY_6 },
+       { 0xf88f, KEY_7 },
+       { 0xf88e, KEY_8 },
+       { 0xf88d, KEY_9 },
+       { 0xf892, KEY_0 },
+       { 0xf896, KEY_CHANNELUP },
+       { 0xf891, KEY_CHANNELDOWN },
+       { 0xf893, KEY_VOLUMEUP },
+       { 0xf88c, KEY_VOLUMEDOWN },
+       { 0xf883, KEY_RECORD },
+       { 0xf898, KEY_PAUSE  },
+       { 0xf899, KEY_OK },
+       { 0xf89a, KEY_SHUFFLE },
+       { 0xf881, KEY_UP },
+       { 0xf890, KEY_LEFT },
+       { 0xf882, KEY_RIGHT },
+       { 0xf888, KEY_DOWN },
+       { 0xf895, KEY_FAVORITES },
+       { 0xf897, KEY_SUBTITLE },
+       { 0xf89d, KEY_ZOOM },
+       { 0xf89f, KEY_EXIT },
+       { 0xf89e, KEY_MENU },
+       { 0xf89c, KEY_EPG },
+       { 0xf880, KEY_PREVIOUS },
+       { 0xf89b, KEY_MODE }
+};
+
+static struct rc_map_table rc_map_su3000_table[] = {
+       { 0x25, KEY_POWER },    /* right-bottom Red */
+       { 0x0a, KEY_MUTE },     /* -/-- */
+       { 0x01, KEY_1 },
+       { 0x02, KEY_2 },
+       { 0x03, KEY_3 },
+       { 0x04, KEY_4 },
+       { 0x05, KEY_5 },
+       { 0x06, KEY_6 },
+       { 0x07, KEY_7 },
+       { 0x08, KEY_8 },
+       { 0x09, KEY_9 },
+       { 0x00, KEY_0 },
+       { 0x20, KEY_UP },       /* CH+ */
+       { 0x21, KEY_DOWN },     /* CH+ */
+       { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
+       { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
+       { 0x1f, KEY_RECORD },
+       { 0x17, KEY_PLAY },
+       { 0x16, KEY_PAUSE },
+       { 0x0b, KEY_STOP },
+       { 0x27, KEY_FASTFORWARD },/* >> */
+       { 0x26, KEY_REWIND },   /* << */
+       { 0x0d, KEY_OK },       /* Mute */
+       { 0x11, KEY_LEFT },     /* VOL- */
+       { 0x10, KEY_RIGHT },    /* VOL+ */
+       { 0x29, KEY_BACK },     /* button under 9 */
+       { 0x2c, KEY_MENU },     /* TTX */
+       { 0x2b, KEY_EPG },      /* EPG */
+       { 0x1e, KEY_RED },      /* OSD */
+       { 0x0e, KEY_GREEN },    /* Window */
+       { 0x2d, KEY_YELLOW },   /* button under << */
+       { 0x0f, KEY_BLUE },     /* bottom yellow button */
+       { 0x14, KEY_AUDIO },    /* Snapshot */
+       { 0x38, KEY_TV },       /* TV/Radio */
+       { 0x0c, KEY_ESC }       /* upper Red button */
+};
+
+static struct rc_map_dvb_usb_table_table keys_tables[] = {
+       { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
+       { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
+       { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
+       { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
+};
+
+static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+       int keymap_size = d->props.rc.legacy.rc_map_size;
+       u8 key[2];
+       struct i2c_msg msg = {
+               .addr = DW2102_RC_QUERY,
+               .flags = I2C_M_RD,
+               .buf = key,
+               .len = 2
+       };
+       int i;
+       /* override keymap */
+       if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
+               keymap = keys_tables[ir_keymap - 1].rc_keys ;
+               keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
+       } else if (ir_keymap > ARRAY_SIZE(keys_tables))
+               return 0; /* none */
+
+       *state = REMOTE_NO_KEY_PRESSED;
+       if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
+               for (i = 0; i < keymap_size ; i++) {
+                       if (rc5_data(&keymap[i]) == msg.buf[0]) {
+                               *state = REMOTE_KEY_PRESSED;
+                               *event = keymap[i].keycode;
+                               break;
+                       }
+
+               }
+
+               if ((*state) == REMOTE_KEY_PRESSED)
+                       deb_rc("%s: found rc key: %x, %x, event: %x\n",
+                                       __func__, key[0], key[1], (*event));
+               else if (key[0] != 0xff)
+                       deb_rc("%s: unknown rc key: %x, %x\n",
+                                       __func__, key[0], key[1]);
+
+       }
+
+       return 0;
+}
+
+enum dw2102_table_entry {
+       CYPRESS_DW2102,
+       CYPRESS_DW2101,
+       CYPRESS_DW2104,
+       TEVII_S650,
+       TERRATEC_CINERGY_S,
+       CYPRESS_DW3101,
+       TEVII_S630,
+       PROF_1100,
+       TEVII_S660,
+       PROF_7500,
+       GENIATECH_SU3000,
+       TERRATEC_CINERGY_S2,
+       TEVII_S480_1,
+       TEVII_S480_2,
+       X3M_SPC1400HD,
+};
+
+static struct usb_device_id dw2102_table[] = {
+       [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
+       [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
+       [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
+       [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
+       [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
+       [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
+       [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
+       [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
+       [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
+       [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
+       [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
+       [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
+       [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
+       [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
+       [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
+       { }
+};
+
+MODULE_DEVICE_TABLE(usb, dw2102_table);
+
+static int dw2102_load_firmware(struct usb_device *dev,
+                       const struct firmware *frmwr)
+{
+       u8 *b, *p;
+       int ret = 0, i;
+       u8 reset;
+       u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
+       const struct firmware *fw;
+       const char *fw_2101 = "dvb-usb-dw2101.fw";
+
+       switch (dev->descriptor.idProduct) {
+       case 0x2101:
+               ret = request_firmware(&fw, fw_2101, &dev->dev);
+               if (ret != 0) {
+                       err(err_str, fw_2101);
+                       return ret;
+               }
+               break;
+       default:
+               fw = frmwr;
+               break;
+       }
+       info("start downloading DW210X firmware");
+       p = kmalloc(fw->size, GFP_KERNEL);
+       reset = 1;
+       /*stop the CPU*/
+       dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
+       dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
+
+       if (p != NULL) {
+               memcpy(p, fw->data, fw->size);
+               for (i = 0; i < fw->size; i += 0x40) {
+                       b = (u8 *) p + i;
+                       if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
+                                       DW210X_WRITE_MSG) != 0x40) {
+                               err("error while transferring firmware");
+                               ret = -EINVAL;
+                               break;
+                       }
+               }
+               /* restart the CPU */
+               reset = 0;
+               if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
+                                       DW210X_WRITE_MSG) != 1) {
+                       err("could not restart the USB controller CPU.");
+                       ret = -EINVAL;
+               }
+               if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
+                                       DW210X_WRITE_MSG) != 1) {
+                       err("could not restart the USB controller CPU.");
+                       ret = -EINVAL;
+               }
+               /* init registers */
+               switch (dev->descriptor.idProduct) {
+               case USB_PID_TEVII_S650:
+                       dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
+                       dw2104_properties.rc.legacy.rc_map_size =
+                                       ARRAY_SIZE(rc_map_tevii_table);
+               case USB_PID_DW2104:
+                       reset = 1;
+                       dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
+                                       DW210X_WRITE_MSG);
+                       /* break omitted intentionally */
+               case USB_PID_DW3101:
+                       reset = 0;
+                       dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
+                                       DW210X_WRITE_MSG);
+                       break;
+               case USB_PID_CINERGY_S:
+               case USB_PID_DW2102:
+                       dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
+                                       DW210X_WRITE_MSG);
+                       dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
+                                       DW210X_READ_MSG);
+                       /* check STV0299 frontend  */
+                       dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
+                                       DW210X_READ_MSG);
+                       if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
+                               dw2102_properties.i2c_algo = &dw2102_i2c_algo;
+                               dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
+                               break;
+                       } else {
+                               /* check STV0288 frontend  */
+                               reset16[0] = 0xd0;
+                               reset16[1] = 1;
+                               reset16[2] = 0;
+                               dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
+                                               DW210X_WRITE_MSG);
+                               dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
+                                               DW210X_READ_MSG);
+                               if (reset16[2] == 0x11) {
+                                       dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
+                                       break;
+                               }
+                       }
+               case 0x2101:
+                       dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
+                                       DW210X_READ_MSG);
+                       dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
+                                       DW210X_READ_MSG);
+                       dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
+                                       DW210X_READ_MSG);
+                       dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
+                                       DW210X_READ_MSG);
+                       break;
+               }
+
+               msleep(100);
+               kfree(p);
+       }
+       return ret;
+}
+
+static struct dvb_usb_device_properties dw2102_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dw2102.fw",
+       .no_reconnect = 1,
+
+       .i2c_algo = &dw2102_serit_i2c_algo,
+
+       .rc.legacy = {
+               .rc_map_table = rc_map_dw210x_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
+               .rc_interval = 150,
+               .rc_query = dw2102_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x81,
+       /* parameter for the MPEG2-data transfer */
+       .num_adapters = 1,
+       .download_firmware = dw2102_load_firmware,
+       .read_mac_address = dw210x_read_mac_address,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = dw2102_frontend_attach,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .num_device_descs = 3,
+       .devices = {
+               {"DVBWorld DVB-S 2102 USB2.0",
+                       {&dw2102_table[CYPRESS_DW2102], NULL},
+                       {NULL},
+               },
+               {"DVBWorld DVB-S 2101 USB2.0",
+                       {&dw2102_table[CYPRESS_DW2101], NULL},
+                       {NULL},
+               },
+               {"TerraTec Cinergy S USB",
+                       {&dw2102_table[TERRATEC_CINERGY_S], NULL},
+                       {NULL},
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dw2104_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dw2104.fw",
+       .no_reconnect = 1,
+
+       .i2c_algo = &dw2104_i2c_algo,
+       .rc.legacy = {
+               .rc_map_table = rc_map_dw210x_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
+               .rc_interval = 150,
+               .rc_query = dw2102_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x81,
+       /* parameter for the MPEG2-data transfer */
+       .num_adapters = 1,
+       .download_firmware = dw2102_load_firmware,
+       .read_mac_address = dw210x_read_mac_address,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = dw2104_frontend_attach,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .num_device_descs = 2,
+       .devices = {
+               { "DVBWorld DW2104 USB2.0",
+                       {&dw2102_table[CYPRESS_DW2104], NULL},
+                       {NULL},
+               },
+               { "TeVii S650 USB2.0",
+                       {&dw2102_table[TEVII_S650], NULL},
+                       {NULL},
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dw3101_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dw3101.fw",
+       .no_reconnect = 1,
+
+       .i2c_algo = &dw3101_i2c_algo,
+       .rc.legacy = {
+               .rc_map_table = rc_map_dw210x_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
+               .rc_interval = 150,
+               .rc_query = dw2102_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x81,
+       /* parameter for the MPEG2-data transfer */
+       .num_adapters = 1,
+       .download_firmware = dw2102_load_firmware,
+       .read_mac_address = dw210x_read_mac_address,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = dw3101_frontend_attach,
+                       .tuner_attach = dw3101_tuner_attach,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .num_device_descs = 1,
+       .devices = {
+               { "DVBWorld DVB-C 3101 USB2.0",
+                       {&dw2102_table[CYPRESS_DW3101], NULL},
+                       {NULL},
+               },
+       }
+};
+
+static struct dvb_usb_device_properties s6x0_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .size_of_priv = sizeof(struct s6x0_state),
+       .firmware = "dvb-usb-s630.fw",
+       .no_reconnect = 1,
+
+       .i2c_algo = &s6x0_i2c_algo,
+       .rc.legacy = {
+               .rc_map_table = rc_map_tevii_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
+               .rc_interval = 150,
+               .rc_query = dw2102_rc_query,
+       },
+
+       .generic_bulk_ctrl_endpoint = 0x81,
+       .num_adapters = 1,
+       .download_firmware = dw2102_load_firmware,
+       .read_mac_address = s6x0_read_mac_address,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = zl100313_frontend_attach,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .num_device_descs = 1,
+       .devices = {
+               {"TeVii S630 USB",
+                       {&dw2102_table[TEVII_S630], NULL},
+                       {NULL},
+               },
+       }
+};
+
+struct dvb_usb_device_properties *p1100;
+static struct dvb_usb_device_description d1100 = {
+       "Prof 1100 USB ",
+       {&dw2102_table[PROF_1100], NULL},
+       {NULL},
+};
+
+struct dvb_usb_device_properties *s660;
+static struct dvb_usb_device_description d660 = {
+       "TeVii S660 USB",
+       {&dw2102_table[TEVII_S660], NULL},
+       {NULL},
+};
+
+static struct dvb_usb_device_description d480_1 = {
+       "TeVii S480.1 USB",
+       {&dw2102_table[TEVII_S480_1], NULL},
+       {NULL},
+};
+
+static struct dvb_usb_device_description d480_2 = {
+       "TeVii S480.2 USB",
+       {&dw2102_table[TEVII_S480_2], NULL},
+       {NULL},
+};
+
+struct dvb_usb_device_properties *p7500;
+static struct dvb_usb_device_description d7500 = {
+       "Prof 7500 USB DVB-S2",
+       {&dw2102_table[PROF_7500], NULL},
+       {NULL},
+};
+
+static struct dvb_usb_device_properties su3000_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .size_of_priv = sizeof(struct su3000_state),
+       .power_ctrl = su3000_power_ctrl,
+       .num_adapters = 1,
+       .identify_state = su3000_identify_state,
+       .i2c_algo = &su3000_i2c_algo,
+
+       .rc.legacy = {
+               .rc_map_table = rc_map_su3000_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
+               .rc_interval = 150,
+               .rc_query = dw2102_rc_query,
+       },
+
+       .read_mac_address = su3000_read_mac_address,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = su3000_streaming_ctrl,
+                       .frontend_attach  = su3000_frontend_attach,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 8,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       }
+               }},
+               }
+       },
+       .num_device_descs = 3,
+       .devices = {
+               { "SU3000HD DVB-S USB2.0",
+                       { &dw2102_table[GENIATECH_SU3000], NULL },
+                       { NULL },
+               },
+               { "Terratec Cinergy S2 USB HD",
+                       { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
+                       { NULL },
+               },
+               { "X3M TV SPC1400HD PCI",
+                       { &dw2102_table[X3M_SPC1400HD], NULL },
+                       { NULL },
+               },
+       }
+};
+
+static int dw2102_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       p1100 = kmemdup(&s6x0_properties,
+                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+       if (!p1100)
+               return -ENOMEM;
+       /* copy default structure */
+       /* fill only different fields */
+       p1100->firmware = "dvb-usb-p1100.fw";
+       p1100->devices[0] = d1100;
+       p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
+       p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
+       p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
+
+       s660 = kmemdup(&s6x0_properties,
+                      sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+       if (!s660) {
+               kfree(p1100);
+               return -ENOMEM;
+       }
+       s660->firmware = "dvb-usb-s660.fw";
+       s660->num_device_descs = 3;
+       s660->devices[0] = d660;
+       s660->devices[1] = d480_1;
+       s660->devices[2] = d480_2;
+       s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
+
+       p7500 = kmemdup(&s6x0_properties,
+                       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+       if (!p7500) {
+               kfree(p1100);
+               kfree(s660);
+               return -ENOMEM;
+       }
+       p7500->firmware = "dvb-usb-p7500.fw";
+       p7500->devices[0] = d7500;
+       p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
+       p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
+       p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
+
+       if (0 == dvb_usb_device_init(intf, &dw2102_properties,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &dw2104_properties,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &dw3101_properties,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &s6x0_properties,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, p1100,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, s660,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, p7500,
+                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &su3000_properties,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return 0;
+
+       return -ENODEV;
+}
+
+static struct usb_driver dw2102_driver = {
+       .name = "dw2102",
+       .probe = dw2102_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table = dw2102_table,
+};
+
+module_usb_driver(dw2102_driver);
+
+MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
+MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
+                               " DVB-C 3101 USB2.0,"
+                               " TeVii S600, S630, S650, S660, S480,"
+                               " Prof 1100, 7500 USB2.0,"
+                               " Geniatech SU3000 devices");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dw2102.h b/drivers/media/usb/dvb-usb/dw2102.h
new file mode 100644 (file)
index 0000000..5cd0b0e
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _DW2102_H_
+#define _DW2102_H_
+
+#define DVB_USB_LOG_PREFIX "dw2102"
+#include "dvb-usb.h"
+
+#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_dw2102_debug, 0x04, args)
+#endif
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
new file mode 100644 (file)
index 0000000..90a70c6
--- /dev/null
@@ -0,0 +1,473 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "friio.h"
+
+struct jdvbt90502_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend frontend;
+       struct jdvbt90502_config config;
+};
+
+/* NOTE: TC90502 has 16bit register-address? */
+/* register 0x0100 is used for reading PLL status, so reg is u16 here */
+static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
+                              const u16 reg, u8 *buf, const size_t count)
+{
+       int ret;
+       u8 wbuf[3];
+       struct i2c_msg msg[2];
+
+       wbuf[0] = reg & 0xFF;
+       wbuf[1] = 0;
+       wbuf[2] = reg >> 8;
+
+       msg[0].addr = state->config.demod_address;
+       msg[0].flags = 0;
+       msg[0].buf = wbuf;
+       msg[0].len = sizeof(wbuf);
+
+       msg[1].addr = msg[0].addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].buf = buf;
+       msg[1].len = count;
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2) {
+               deb_fe(" reg read failed.\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* currently 16bit register-address is not used, so reg is u8 here */
+static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
+                                      const u8 reg, const u8 val)
+{
+       struct i2c_msg msg;
+       u8 wbuf[2];
+
+       wbuf[0] = reg;
+       wbuf[1] = val;
+
+       msg.addr = state->config.demod_address;
+       msg.flags = 0;
+       msg.buf = wbuf;
+       msg.len = sizeof(wbuf);
+
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               deb_fe(" reg write failed.");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
+{
+       struct jdvbt90502_state *state = fe->demodulator_priv;
+       int err, i;
+       for (i = 0; i < len - 1; i++) {
+               err = jdvbt90502_single_reg_write(state,
+                                                 buf[0] + i, buf[i + 1]);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+/* read pll status byte via the demodulator's I2C register */
+/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
+static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
+{
+       int ret;
+
+       /* +1 for reading */
+       u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
+
+       *result = 0;
+
+       ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
+                                         pll_addr_byte);
+       if (ret)
+               goto error;
+
+       ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
+       if (ret)
+               goto error;
+
+       deb_fe("PLL read val:%02x\n", *result);
+       return 0;
+
+error:
+       deb_fe("%s:ret == %d\n", __func__, ret);
+       return -EREMOTEIO;
+}
+
+
+/* set pll frequency via the demodulator's I2C register */
+static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
+{
+       int ret;
+       int retry;
+       u8 res1;
+       u8 res2[9];
+
+       u8 pll_freq_cmd[PLL_CMD_LEN];
+       u8 pll_agc_cmd[PLL_CMD_LEN];
+       struct i2c_msg msg[2];
+       u32 f;
+
+       deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
+              state->frontend.ops.info.frequency_stepsize);
+       /* freq -> oscilator frequency conversion. */
+       /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
+       f = freq / state->frontend.ops.info.frequency_stepsize;
+       /* add 399[1/7 MHZ] = 57MHz for the IF  */
+       f += 399;
+       /* add center frequency shift if necessary */
+       if (f % 7 == 0)
+               f++;
+       pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
+       pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
+       pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
+       pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
+       pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
+       pll_freq_cmd[BANDSWITCH_BYTE] = 0x08;   /* UHF band */
+
+       msg[0].addr = state->config.demod_address;
+       msg[0].flags = 0;
+       msg[0].buf = pll_freq_cmd;
+       msg[0].len = sizeof(pll_freq_cmd);
+
+       ret = i2c_transfer(state->i2c, &msg[0], 1);
+       if (ret != 1)
+               goto error;
+
+       udelay(50);
+
+       pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
+       pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
+       pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
+       pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
+       pll_agc_cmd[CONTROL_BYTE] = 0x9A; /*  AGC_CTRL instead of BANDSWITCH */
+       pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
+       /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
+
+       msg[1].addr = msg[0].addr;
+       msg[1].flags = 0;
+       msg[1].buf = pll_agc_cmd;
+       msg[1].len = sizeof(pll_agc_cmd);
+
+       ret = i2c_transfer(state->i2c, &msg[1], 1);
+       if (ret != 1)
+               goto error;
+
+       /* I don't know what these cmds are for,  */
+       /* but the USB log on a windows box contains them */
+       ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
+       ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
+       if (ret)
+               goto error;
+       udelay(100);
+
+       /* wait for the demod to be ready? */
+#define RETRY_COUNT 5
+       for (retry = 0; retry < RETRY_COUNT; retry++) {
+               ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
+               if (ret)
+                       goto error;
+               /* if (res1 != 0x00) goto error; */
+               ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
+               if (ret)
+                       goto error;
+               if (res2[0] >= 0xA7)
+                       break;
+               msleep(100);
+       }
+       if (retry >= RETRY_COUNT) {
+               deb_fe("%s: FE does not get ready after freq setting.\n",
+                      __func__);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+error:
+       deb_fe("%s:ret == %d\n", __func__, ret);
+       return -EREMOTEIO;
+}
+
+static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
+{
+       u8 result;
+       int ret;
+
+       *state = FE_HAS_SIGNAL;
+
+       ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
+       if (ret) {
+               deb_fe("%s:ret == %d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+
+       *state = FE_HAS_SIGNAL
+               | FE_HAS_CARRIER
+               | FE_HAS_VITERBI
+               | FE_HAS_SYNC;
+
+       if (result & PLL_STATUS_LOCKED)
+               *state |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
+                                          u16 *strength)
+{
+       int ret;
+       u8 rbuf[37];
+
+       *strength = 0;
+
+       /* status register (incl. signal strength) : 0x89  */
+       /* TODO: read just the necessary registers [0x8B..0x8D]? */
+       ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
+                                 rbuf, sizeof(rbuf));
+
+       if (ret) {
+               deb_fe("%s:ret == %d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+
+       /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
+       *strength = (rbuf[3] << 8) + rbuf[4];
+       if (rbuf[2])
+               *strength = 0xffff;
+
+       return 0;
+}
+
+
+/* filter out un-supported properties to notify users */
+static int jdvbt90502_set_property(struct dvb_frontend *fe,
+                                  struct dtv_property *tvp)
+{
+       int r = 0;
+
+       switch (tvp->cmd) {
+       case DTV_DELIVERY_SYSTEM:
+               if (tvp->u.data != SYS_ISDBT)
+                       r = -EINVAL;
+               break;
+       case DTV_CLEAR:
+       case DTV_TUNE:
+       case DTV_FREQUENCY:
+               break;
+       default:
+               r = -EINVAL;
+       }
+       return r;
+}
+
+static int jdvbt90502_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       p->inversion = INVERSION_AUTO;
+       p->bandwidth_hz = 6000000;
+       p->code_rate_HP = FEC_AUTO;
+       p->code_rate_LP = FEC_AUTO;
+       p->modulation = QAM_64;
+       p->transmission_mode = TRANSMISSION_MODE_AUTO;
+       p->guard_interval = GUARD_INTERVAL_AUTO;
+       p->hierarchy = HIERARCHY_AUTO;
+       return 0;
+}
+
+static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       /**
+        * NOTE: ignore all the parameters except frequency.
+        *       others should be fixed to the proper value for ISDB-T,
+        *       but don't check here.
+        */
+
+       struct jdvbt90502_state *state = fe->demodulator_priv;
+       int ret;
+
+       deb_fe("%s: Freq:%d\n", __func__, p->frequency);
+
+       /* for recovery from DTV_CLEAN */
+       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
+       ret = jdvbt90502_pll_set_freq(state, p->frequency);
+       if (ret) {
+               deb_fe("%s:ret == %d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+
+/**
+ * (reg, val) commad list to initialize this module.
+ *  captured on a Windows box.
+ */
+static u8 init_code[][2] = {
+       {0x01, 0x40},
+       {0x04, 0x38},
+       {0x05, 0x40},
+       {0x07, 0x40},
+       {0x0F, 0x4F},
+       {0x11, 0x21},
+       {0x12, 0x0B},
+       {0x13, 0x2F},
+       {0x14, 0x31},
+       {0x16, 0x02},
+       {0x21, 0xC4},
+       {0x22, 0x20},
+       {0x2C, 0x79},
+       {0x2D, 0x34},
+       {0x2F, 0x00},
+       {0x30, 0x28},
+       {0x31, 0x31},
+       {0x32, 0xDF},
+       {0x38, 0x01},
+       {0x39, 0x78},
+       {0x3B, 0x33},
+       {0x3C, 0x33},
+       {0x48, 0x90},
+       {0x51, 0x68},
+       {0x5E, 0x38},
+       {0x71, 0x00},
+       {0x72, 0x08},
+       {0x77, 0x00},
+       {0xC0, 0x21},
+       {0xC1, 0x10},
+       {0xE4, 0x1A},
+       {0xEA, 0x1F},
+       {0x77, 0x00},
+       {0x71, 0x00},
+       {0x71, 0x00},
+       {0x76, 0x0C},
+};
+
+static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
+
+static int jdvbt90502_init(struct dvb_frontend *fe)
+{
+       int i = -1;
+       int ret;
+       struct i2c_msg msg;
+
+       struct jdvbt90502_state *state = fe->demodulator_priv;
+
+       deb_fe("%s called.\n", __func__);
+
+       msg.addr = state->config.demod_address;
+       msg.flags = 0;
+       msg.len = 2;
+       for (i = 0; i < init_code_len; i++) {
+               msg.buf = init_code[i];
+               ret = i2c_transfer(state->i2c, &msg, 1);
+               if (ret != 1)
+                       goto error;
+       }
+       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+       msleep(100);
+
+       return 0;
+
+error:
+       deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
+       return -EREMOTEIO;
+}
+
+
+static void jdvbt90502_release(struct dvb_frontend *fe)
+{
+       struct jdvbt90502_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+
+static struct dvb_frontend_ops jdvbt90502_ops;
+
+struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
+{
+       struct jdvbt90502_state *state = NULL;
+
+       deb_info("%s called.\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = &d->i2c_adap;
+       memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &jdvbt90502_ops,
+              sizeof(jdvbt90502_ops));
+       state->frontend.demodulator_priv = state;
+
+       if (jdvbt90502_init(&state->frontend) < 0)
+               goto error;
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops jdvbt90502_ops = {
+       .delsys = { SYS_ISDBT },
+       .info = {
+               .name                   = "Comtech JDVBT90502 ISDB-T",
+               .frequency_min          = 473000000, /* UHF 13ch, center */
+               .frequency_max          = 767142857, /* UHF 62ch, center */
+               .frequency_stepsize     = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER,
+               .frequency_tolerance    = 0,
+
+               /* NOTE: this driver ignores all parameters but frequency. */
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = jdvbt90502_release,
+
+       .init = jdvbt90502_init,
+       .write = _jdvbt90502_write,
+
+       .set_property = jdvbt90502_set_property,
+
+       .set_frontend = jdvbt90502_set_frontend,
+       .get_frontend = jdvbt90502_get_frontend,
+
+       .read_status = jdvbt90502_read_status,
+       .read_signal_strength = jdvbt90502_read_signal_strength,
+};
diff --git a/drivers/media/usb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c
new file mode 100644 (file)
index 0000000..474a17e
--- /dev/null
@@ -0,0 +1,522 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "friio.h"
+
+/* debug */
+int dvb_usb_friio_debug;
+module_param_named(debug, dvb_usb_friio_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+                "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
+                DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/**
+ * Indirect I2C access to the PLL via FE.
+ * whole I2C protocol data to the PLL is sent via the FE's I2C register.
+ * This is done by a control msg to the FE with the I2C data accompanied, and
+ * a specific USB request number is assigned for that purpose.
+ *
+ * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
+ * TODO: refoctored, smarter i2c functions.
+ */
+static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
+                                 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u16 index = wbuf[0];    /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
+       u16 value = addr << (8 + 1);
+       int wo = (rbuf == NULL || rlen == 0);   /* write only */
+       u8 req, type;
+
+       deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
+                wbuf[1], wbuf[0], wlen - 1);
+
+       if (wo && wlen >= 2) {
+               req = GL861_REQ_I2C_DATA_CTRL_WRITE;
+               type = GL861_WRITE;
+               udelay(20);
+               return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+                                      req, type, value, index,
+                                      &wbuf[1], wlen - 1, 2000);
+       }
+
+       deb_xfer("not supported ctrl-msg, aborting.");
+       return -EINVAL;
+}
+
+/* normal I2C access (without extra data arguments).
+ * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
+ *  or read from the register wbuf[0].
+ * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
+ */
+static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u16 index;
+       u16 value = addr << (8 + 1);
+       int wo = (rbuf == NULL || rlen == 0);   /* write-only */
+       u8 req, type;
+       unsigned int pipe;
+
+       /* special case for the indirect I2C access to the PLL via FE, */
+       if (addr == friio_fe_config.demod_address &&
+           wbuf[0] == JDVBT90502_2ND_I2C_REG)
+               return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
+
+       if (wo) {
+               req = GL861_REQ_I2C_WRITE;
+               type = GL861_WRITE;
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {                /* rw */
+               req = GL861_REQ_I2C_READ;
+               type = GL861_READ;
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       switch (wlen) {
+       case 1:
+               index = wbuf[0];
+               break;
+       case 2:
+               index = wbuf[0];
+               value = value + wbuf[1];
+               break;
+       case 3:
+               /* special case for 16bit register-address */
+               index = (wbuf[2] << 8) | wbuf[0];
+               value = value + wbuf[1];
+               break;
+       default:
+               deb_xfer("wlen = %x, aborting.", wlen);
+               return -EINVAL;
+       }
+       msleep(1);
+       return usb_control_msg(d->udev, pipe, req, type,
+                              value, index, rbuf, rlen, 2000);
+}
+
+/* I2C */
+static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                         int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
+                       if (gl861_i2c_msg(d, msg[i].addr,
+                                         msg[i].buf, msg[i].len,
+                                         msg[i + 1].buf, msg[i + 1].len) < 0)
+                               break;
+                       i++;
+               } else
+                       if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                         msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 gl861_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static int friio_ext_ctl(struct dvb_usb_adapter *adap,
+                        u32 sat_color, int lnb_on)
+{
+       int i;
+       int ret;
+       struct i2c_msg msg;
+       u8 *buf;
+       u32 mask;
+       u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
+
+       buf = kmalloc(2, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       msg.addr = 0x00;
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = buf;
+
+       buf[0] = 0x00;
+
+       /* send 2bit header (&B10) */
+       buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
+       ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+       buf[1] |= FRIIO_CTL_CLK;
+       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+       buf[1] = lnb | FRIIO_CTL_STROBE;
+       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+       buf[1] |= FRIIO_CTL_CLK;
+       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+       /* send 32bit(satur, R, G, B) data in serial */
+       mask = 1 << 31;
+       for (i = 0; i < 32; i++) {
+               buf[1] = lnb | FRIIO_CTL_STROBE;
+               if (sat_color & mask)
+                       buf[1] |= FRIIO_CTL_LED;
+               ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+               buf[1] |= FRIIO_CTL_CLK;
+               ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+               mask >>= 1;
+       }
+
+       /* set the strobe off */
+       buf[1] = lnb;
+       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+       buf[1] |= FRIIO_CTL_CLK;
+       ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+       kfree(buf);
+       return (ret == 70);
+}
+
+
+static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
+
+/* TODO: move these init cmds to the FE's init routine? */
+static u8 streaming_init_cmds[][2] = {
+       {0x33, 0x08},
+       {0x37, 0x40},
+       {0x3A, 0x1F},
+       {0x3B, 0xFF},
+       {0x3C, 0x1F},
+       {0x3D, 0xFF},
+       {0x38, 0x00},
+       {0x35, 0x00},
+       {0x39, 0x00},
+       {0x36, 0x00},
+};
+static int cmdlen = sizeof(streaming_init_cmds) / 2;
+
+/*
+ * Command sequence in this init function is a replay
+ *  of the captured USB commands from the Windows proprietary driver.
+ */
+static int friio_initialize(struct dvb_usb_device *d)
+{
+       int ret;
+       int i;
+       int retry = 0;
+       u8 *rbuf, *wbuf;
+
+       deb_info("%s called.\n", __func__);
+
+       wbuf = kmalloc(3, GFP_KERNEL);
+       if (!wbuf)
+               return -ENOMEM;
+
+       rbuf = kmalloc(2, GFP_KERNEL);
+       if (!rbuf) {
+               kfree(wbuf);
+               return -ENOMEM;
+       }
+
+       /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
+       /* because the i2c device is not set up yet. */
+       wbuf[0] = 0x11;
+       wbuf[1] = 0x02;
+       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+       msleep(2);
+
+       wbuf[0] = 0x11;
+       wbuf[1] = 0x00;
+       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+       msleep(1);
+
+       /* following msgs should be in the FE's init code? */
+       /* cmd sequence to identify the device type? (friio black/white) */
+       wbuf[0] = 0x03;
+       wbuf[1] = 0x80;
+       /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
+       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+                             GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
+                             0x1200, 0x0100, wbuf, 2, 2000);
+       if (ret < 0)
+               goto error;
+
+       msleep(2);
+       wbuf[0] = 0x00;
+       wbuf[2] = 0x01;         /* reg.0x0100 */
+       wbuf[1] = 0x00;
+       ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
+       /* my Friio White returns 0xffff. */
+       if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
+               goto error;
+
+       msleep(2);
+       wbuf[0] = 0x03;
+       wbuf[1] = 0x80;
+       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+                             GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
+                             0x9000, 0x0100, wbuf, 2, 2000);
+       if (ret < 0)
+               goto error;
+
+       msleep(2);
+       wbuf[0] = 0x00;
+       wbuf[2] = 0x01;         /* reg.0x0100 */
+       wbuf[1] = 0x00;
+       ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
+       /* my Friio White returns 0xffff again. */
+       if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
+               goto error;
+
+       msleep(1);
+
+restart:
+       /* ============ start DEMOD init cmds ================== */
+       /* read PLL status to clear the POR bit */
+       wbuf[0] = JDVBT90502_2ND_I2C_REG;
+       wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1;    /* +1 for reading */
+       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+
+       msleep(5);
+       /* note: DEMODULATOR has 16bit register-address. */
+       wbuf[0] = 0x00;
+       wbuf[2] = 0x01;         /* reg addr: 0x0100 */
+       wbuf[1] = 0x00;         /* val: not used */
+       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
+       if (ret < 0)
+               goto error;
+/*
+       msleep(1);
+       wbuf[0] = 0x80;
+       wbuf[1] = 0x00;
+       ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
+       if (ret < 0)
+               goto error;
+ */
+       if (rbuf[0] & 0x80) {   /* still in PowerOnReset state? */
+               if (++retry > 3) {
+                       deb_info("failed to get the correct"
+                                " FE demod status:0x%02x\n", rbuf[0]);
+                       goto error;
+               }
+               msleep(100);
+               goto restart;
+       }
+
+       /* TODO: check return value in rbuf */
+       /* =========== end DEMOD init cmds ===================== */
+       msleep(1);
+
+       wbuf[0] = 0x30;
+       wbuf[1] = 0x04;
+       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+
+       msleep(2);
+       /* following 2 cmds unnecessary? */
+       wbuf[0] = 0x00;
+       wbuf[1] = 0x01;
+       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+
+       wbuf[0] = 0x06;
+       wbuf[1] = 0x0F;
+       ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+       if (ret < 0)
+               goto error;
+
+       /* some streaming ctl cmds (maybe) */
+       msleep(10);
+       for (i = 0; i < cmdlen; i++) {
+               ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
+                                   NULL, 0);
+               if (ret < 0)
+                       goto error;
+               msleep(1);
+       }
+       msleep(20);
+
+       /* change the LED color etc. */
+       ret = friio_streaming_ctrl(&d->adapter[0], 0);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       kfree(wbuf);
+       kfree(rbuf);
+       deb_info("%s:ret == %d\n", __func__, ret);
+       return -EIO;
+}
+
+/* Callbacks for DVB USB */
+
+static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+
+       deb_info("%s called.(%d)\n", __func__, onoff);
+
+       /* set the LED color and saturation (and LNB on) */
+       if (onoff)
+               ret = friio_ext_ctl(adap, 0x6400ff64, 1);
+       else
+               ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
+
+       if (ret != 1) {
+               deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int friio_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (friio_initialize(adap->dev) < 0)
+               return -EIO;
+
+       adap->fe_adap[0].fe = jdvbt90502_attach(adap->dev);
+       if (adap->fe_adap[0].fe == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties friio_properties;
+
+static int friio_probe(struct usb_interface *intf,
+                      const struct usb_device_id *id)
+{
+       struct dvb_usb_device *d;
+       struct usb_host_interface *alt;
+       int ret;
+
+       if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
+               return -ENODEV;
+
+       alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
+       if (alt == NULL) {
+               deb_rc("not alt found!\n");
+               return -ENODEV;
+       }
+       ret = usb_set_interface(interface_to_usbdev(intf),
+                               alt->desc.bInterfaceNumber,
+                               alt->desc.bAlternateSetting);
+       if (ret != 0) {
+               deb_rc("failed to set alt-setting!\n");
+               return ret;
+       }
+
+       ret = dvb_usb_device_init(intf, &friio_properties,
+                                 THIS_MODULE, &d, adapter_nr);
+       if (ret == 0)
+               friio_streaming_ctrl(&d->adapter[0], 1);
+
+       return ret;
+}
+
+
+struct jdvbt90502_config friio_fe_config = {
+       .demod_address = FRIIO_DEMOD_ADDR,
+       .pll_address = FRIIO_PLL_ADDR,
+};
+
+static struct i2c_algorithm gl861_i2c_algo = {
+       .master_xfer   = gl861_i2c_xfer,
+       .functionality = gl861_i2c_func,
+};
+
+static struct usb_device_id friio_table[] = {
+       { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, friio_table);
+
+
+static struct dvb_usb_device_properties friio_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = DEVICE_SPECIFIC,
+
+       .size_of_priv = 0,
+
+       .num_adapters = 1,
+       .adapter = {
+               /* caps:0 =>  no pid filter, 188B TS packet */
+               /* GL861 has a HW pid filter, but no info available. */
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps  = 0,
+
+                       .frontend_attach  = friio_frontend_attach,
+                       .streaming_ctrl = friio_streaming_ctrl,
+
+                       .stream = {
+                               .type = USB_BULK,
+                               /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
+                               .count = 8,
+                               .endpoint = 0x01,
+                               .u = {
+                                       /* GL861 has 6KB buf inside */
+                                       .bulk = {
+                                               .buffersize = 16384,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .i2c_algo = &gl861_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {
+                       .name = "774 Friio ISDB-T USB2.0",
+                       .cold_ids = { NULL },
+                       .warm_ids = { &friio_table[0], NULL },
+               },
+       }
+};
+
+static struct usb_driver friio_driver = {
+       .name           = "dvb_usb_friio",
+       .probe          = friio_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = friio_table,
+};
+
+module_usb_driver(friio_driver);
+
+MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
+MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
+MODULE_VERSION("0.2");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/friio.h b/drivers/media/usb/dvb-usb/friio.h
new file mode 100644 (file)
index 0000000..0f461ca
--- /dev/null
@@ -0,0 +1,99 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_FRIIO_H_
+#define _DVB_USB_FRIIO_H_
+
+/**
+ *      Friio Components
+ *       USB hub:                                AU4254
+ *         USB controller(+ TS dmx & streaming): GL861
+ *         Frontend:                             comtech JDVBT-90502
+ *             (tuner PLL:                       tua6034, I2C addr:(0xC0 >> 1))
+ *             (OFDM demodulator:                TC90502, I2C addr:(0x30 >> 1))
+ *         LED x3 (+LNB) control:                PIC 16F676
+ *         EEPROM:                               24C08
+ *
+ *        (USB smart card reader:                AU9522)
+ *
+ */
+
+#define DVB_USB_LOG_PREFIX "friio"
+#include "dvb-usb.h"
+
+extern int dvb_usb_friio_debug;
+#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_friio_debug, 0x04, args)
+#define deb_fe(args...)   dprintk(dvb_usb_friio_debug, 0x08, args)
+
+/* Vendor requests */
+#define GL861_WRITE            0x40
+#define GL861_READ             0xc0
+
+/* command bytes */
+#define GL861_REQ_I2C_WRITE    0x01
+#define GL861_REQ_I2C_READ     0x02
+/* For control msg with data argument */
+/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
+#define GL861_REQ_I2C_DATA_CTRL_WRITE  0x03
+
+#define GL861_ALTSETTING_COUNT 2
+#define FRIIO_BULK_ALTSETTING  0
+#define FRIIO_ISOC_ALTSETTING  1
+
+/* LED & LNB control via PIC. */
+/* basically, it's serial control with clock and strobe. */
+/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
+/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
+#define FRIIO_CTL_LNB (1 << 0)
+#define FRIIO_CTL_STROBE (1 << 1)
+#define FRIIO_CTL_CLK (1 << 2)
+#define FRIIO_CTL_LED (1 << 3)
+
+/* Front End related */
+
+#define FRIIO_DEMOD_ADDR  (0x30 >> 1)
+#define FRIIO_PLL_ADDR  (0xC0 >> 1)
+
+#define JDVBT90502_PLL_CLK     4000000
+#define JDVBT90502_PLL_DIVIDER 28
+
+#define JDVBT90502_2ND_I2C_REG 0xFE
+
+/* byte index for pll i2c command data structure*/
+/* see datasheet for tua6034 */
+#define DEMOD_REDIRECT_REG 0
+#define ADDRESS_BYTE       1
+#define DIVIDER_BYTE1      2
+#define DIVIDER_BYTE2      3
+#define CONTROL_BYTE       4
+#define BANDSWITCH_BYTE    5
+#define AGC_CTRL_BYTE      5
+#define PLL_CMD_LEN        6
+
+/* bit masks for PLL STATUS response */
+#define PLL_STATUS_POR_MODE   0x80 /* 1: Power on Reset (test) Mode */
+#define PLL_STATUS_LOCKED     0x40 /* 1: locked */
+#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
+#define PLL_STATUS_TESTMODE   0x07 /* digital output level (5 level) */
+  /* 0.15Vcc step   0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
+
+
+struct jdvbt90502_config {
+       u8 demod_address; /* i2c addr for demodulator IC */
+       u8 pll_address;   /* PLL addr on the secondary i2c*/
+};
+extern struct jdvbt90502_config friio_fe_config;
+
+extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
+#endif
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
new file mode 100644 (file)
index 0000000..67957dd
--- /dev/null
@@ -0,0 +1,369 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+struct gp8psk_fe_state {
+       struct dvb_frontend fe;
+       struct dvb_usb_device *d;
+       u8 lock;
+       u16 snr;
+       unsigned long next_status_check;
+       unsigned long status_check_interval;
+};
+
+static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 status;
+       gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
+       return status & bmDCtuned;
+}
+
+static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
+}
+
+static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
+{
+       u8 buf[6];
+       if (time_after(jiffies,st->next_status_check)) {
+               gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
+               gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
+               st->snr = (buf[1]) << 8 | buf[0];
+               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       gp8psk_fe_update_status(st);
+
+       if (st->lock)
+               *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+       else
+               *status = 0;
+
+       if (*status & FE_HAS_LOCK)
+               st->status_check_interval = 1000;
+       else
+               st->status_check_interval = 100;
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       (void) fe;
+       *ber = 0;
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       (void) fe;
+       *unc = 0;
+       return 0;
+}
+
+static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       gp8psk_fe_update_status(st);
+       /* snr is reported in dBu*256 */
+       *snr = st->snr;
+       return 0;
+}
+
+static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       gp8psk_fe_update_status(st);
+       /* snr is reported in dBu*256 */
+       /* snr / 38.4 ~= 100% strength */
+       /* snr * 17 returns 100% strength as 65535 */
+       if (st->snr > 0xf00)
+               *strength = 0xffff;
+       else
+               *strength = (st->snr << 4) + st->snr; /* snr*17 */
+       return 0;
+}
+
+static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 800;
+       return 0;
+}
+
+static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 cmd[10];
+       u32 freq = c->frequency * 1000;
+       int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
+
+       deb_fe("%s()\n", __func__);
+
+       cmd[4] = freq         & 0xff;
+       cmd[5] = (freq >> 8)  & 0xff;
+       cmd[6] = (freq >> 16) & 0xff;
+       cmd[7] = (freq >> 24) & 0xff;
+
+       /* backwards compatibility: DVB-S + 8-PSK were used for Turbo-FEC */
+       if (c->delivery_system == SYS_DVBS && c->modulation == PSK_8)
+               c->delivery_system = SYS_TURBO;
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               if (c->modulation != QPSK) {
+                       deb_fe("%s: unsupported modulation selected (%d)\n",
+                               __func__, c->modulation);
+                       return -EOPNOTSUPP;
+               }
+               c->fec_inner = FEC_AUTO;
+               break;
+       case SYS_DVBS2: /* kept for backwards compatibility */
+               deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
+               break;
+       case SYS_TURBO:
+               deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
+               break;
+
+       default:
+               deb_fe("%s: unsupported delivery system selected (%d)\n",
+                       __func__, c->delivery_system);
+               return -EOPNOTSUPP;
+       }
+
+       cmd[0] =  c->symbol_rate        & 0xff;
+       cmd[1] = (c->symbol_rate >>  8) & 0xff;
+       cmd[2] = (c->symbol_rate >> 16) & 0xff;
+       cmd[3] = (c->symbol_rate >> 24) & 0xff;
+       switch (c->modulation) {
+       case QPSK:
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (gp8psk_tuned_to_DCII(fe))
+                               gp8psk_bcm4500_reload(state->d);
+               switch (c->fec_inner) {
+               case FEC_1_2:
+                       cmd[9] = 0; break;
+               case FEC_2_3:
+                       cmd[9] = 1; break;
+               case FEC_3_4:
+                       cmd[9] = 2; break;
+               case FEC_5_6:
+                       cmd[9] = 3; break;
+               case FEC_7_8:
+                       cmd[9] = 4; break;
+               case FEC_AUTO:
+                       cmd[9] = 5; break;
+               default:
+                       cmd[9] = 5; break;
+               }
+               if (c->delivery_system == SYS_TURBO)
+                       cmd[8] = ADV_MOD_TURBO_QPSK;
+               else
+                       cmd[8] = ADV_MOD_DVB_QPSK;
+               break;
+       case PSK_8: /* PSK_8 is for compatibility with DN */
+               cmd[8] = ADV_MOD_TURBO_8PSK;
+               switch (c->fec_inner) {
+               case FEC_2_3:
+                       cmd[9] = 0; break;
+               case FEC_3_4:
+                       cmd[9] = 1; break;
+               case FEC_3_5:
+                       cmd[9] = 2; break;
+               case FEC_5_6:
+                       cmd[9] = 3; break;
+               case FEC_8_9:
+                       cmd[9] = 4; break;
+               default:
+                       cmd[9] = 0; break;
+               }
+               break;
+       case QAM_16: /* QAM_16 is for compatibility with DN */
+               cmd[8] = ADV_MOD_TURBO_16QAM;
+               cmd[9] = 0;
+               break;
+       default: /* Unknown modulation */
+               deb_fe("%s: unsupported modulation selected (%d)\n",
+                       __func__, c->modulation);
+               return -EOPNOTSUPP;
+       }
+
+       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+               gp8psk_set_tuner_mode(fe, 0);
+       gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
+
+       state->lock = 0;
+       state->next_status_check = jiffies;
+       state->status_check_interval = 200;
+
+       return 0;
+}
+
+static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+       deb_fe("%s\n",__func__);
+
+       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+                       m->msg, m->msg_len)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
+                                   fe_sec_mini_cmd_t burst)
+{
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       u8 cmd;
+
+       deb_fe("%s\n",__func__);
+
+       /* These commands are certainly wrong */
+       cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
+
+       if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+                       &cmd, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+       if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+                (tone == SEC_TONE_ON), 0, NULL, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+                        voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+       return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
+}
+
+static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+       u8 cmd = sw_cmd & 0x7f;
+
+       if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+                       NULL, 0)) {
+               return -EINVAL;
+       }
+       if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+                       0, NULL, 0)) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void gp8psk_fe_release(struct dvb_frontend* fe)
+{
+       struct gp8psk_fe_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops gp8psk_fe_ops;
+
+struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+{
+       struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+       if (s == NULL)
+               goto error;
+
+       s->d = d;
+       memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.demodulator_priv = s;
+
+       goto success;
+error:
+       return NULL;
+success:
+       return &s->fe;
+}
+
+
+static struct dvb_frontend_ops gp8psk_fe_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "Genpix DVB-S",
+               .frequency_min          = 800000,
+               .frequency_max          = 2250000,
+               .frequency_stepsize     = 100,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       /*
+                        * FE_CAN_QAM_16 is for compatibility
+                        * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
+                        */
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
+       },
+
+       .release = gp8psk_fe_release,
+
+       .init = NULL,
+       .sleep = NULL,
+
+       .set_frontend = gp8psk_fe_set_frontend,
+
+       .get_tune_settings = gp8psk_fe_get_tune_settings,
+
+       .read_status = gp8psk_fe_read_status,
+       .read_ber = gp8psk_fe_read_ber,
+       .read_signal_strength = gp8psk_fe_read_signal_strength,
+       .read_snr = gp8psk_fe_read_snr,
+       .read_ucblocks = gp8psk_fe_read_unc_blocks,
+
+       .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
+       .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
+       .set_tone = gp8psk_fe_set_tone,
+       .set_voltage = gp8psk_fe_set_voltage,
+       .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
+       .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
+};
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
new file mode 100644 (file)
index 0000000..5d0384d
--- /dev/null
@@ -0,0 +1,328 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+/* debug */
+static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
+int dvb_usb_gp8psk_debug;
+module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+       return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+       return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+       u8 fpga_vers, fw_vers[6];
+
+       if (!gp8psk_get_fw_version(d, fw_vers))
+               info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
+               fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+               2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+       else
+               info("failed to get FW version");
+
+       if (!gp8psk_get_fpga_version(d, &fpga_vers))
+               info("FPGA Version = %i", fpga_vers);
+       else
+               info("failed to get FPGA version");
+}
+
+int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+       int ret = 0,try = 0;
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       while (ret >= 0 && ret != blen && try < 3) {
+               ret = usb_control_msg(d->udev,
+                       usb_rcvctrlpipe(d->udev,0),
+                       req,
+                       USB_TYPE_VENDOR | USB_DIR_IN,
+                       value,index,b,blen,
+                       2000);
+               deb_info("reading number %d (ret: %d)\n",try,ret);
+               try++;
+       }
+
+       if (ret < 0 || ret != blen) {
+               warn("usb in %d operation failed.", req);
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       if (usb_control_msg(d->udev,
+                       usb_sndctrlpipe(d->udev,0),
+                       req,
+                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                       value,index,b,blen,
+                       2000) != blen) {
+               warn("usb out operation failed.");
+               ret = -EIO;
+       } else
+               ret = 0;
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
+{
+       int ret;
+       const struct firmware *fw = NULL;
+       const u8 *ptr;
+       u8 *buf;
+       if ((ret = request_firmware(&fw, bcm4500_firmware,
+                                       &d->udev->dev)) != 0) {
+               err("did not find the bcm4500 firmware file. (%s) "
+                       "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+                       bcm4500_firmware,ret);
+               return ret;
+       }
+
+       ret = -EINVAL;
+
+       if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
+               goto out_rel_fw;
+
+       info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
+
+       ptr = fw->data;
+       buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto out_rel_fw;
+       }
+
+       while (ptr[0] != 0xff) {
+               u16 buflen = ptr[0] + 4;
+               if (ptr + buflen >= fw->data + fw->size) {
+                       err("failed to load bcm4500 firmware.");
+                       goto out_free;
+               }
+               memcpy(buf, ptr, buflen);
+               if (dvb_usb_generic_write(d, buf, buflen)) {
+                       err("failed to load bcm4500 firmware.");
+                       goto out_free;
+               }
+               ptr += buflen;
+       }
+
+       ret = 0;
+
+out_free:
+       kfree(buf);
+out_rel_fw:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 status, buf;
+       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
+
+       if (onoff) {
+               gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+               if (! (status & bm8pskStarted)) {  /* started */
+                       if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
+                               gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
+                       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+                               return -EINVAL;
+                       gp8psk_info(d);
+               }
+
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
+                               if(gp8psk_load_bcm4500fw(d))
+                                       return -EINVAL;
+
+               if (! (status & bmIntersilOn)) /* LNB Power */
+                       if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
+                                       &buf, 1))
+                               return -EINVAL;
+
+               /* Set DVB mode to 1 */
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
+                               return -EINVAL;
+               /* Abort possible TS (if previous tune crashed) */
+               if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
+                       return -EINVAL;
+       } else {
+               /* Turn off LNB power */
+               if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
+                       return -EINVAL;
+               /* Turn off 8psk power */
+               if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+                       return -EINVAL;
+               if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
+                       gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
+       }
+       return 0;
+}
+
+int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
+{
+       u8 buf;
+       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
+       /* Turn off 8psk power */
+       if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+               return -EINVAL;
+       /* Turn On 8psk power */
+       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+               return -EINVAL;
+       /* load BCM4500 firmware */
+       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+               if (gp8psk_load_bcm4500fw(d))
+                       return -EINVAL;
+       return 0;
+}
+
+static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
+}
+
+static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
+       return 0;
+}
+
+static struct dvb_usb_device_properties gp8psk_properties;
+
+static int gp8psk_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       int ret;
+       struct usb_device *udev = interface_to_usbdev(intf);
+       ret = dvb_usb_device_init(intf, &gp8psk_properties,
+                                 THIS_MODULE, NULL, adapter_nr);
+       if (ret == 0) {
+               info("found Genpix USB device pID = %x (hex)",
+                       le16_to_cpu(udev->descriptor.idProduct));
+       }
+       return ret;
+}
+
+static struct usb_device_id gp8psk_usb_table [] = {
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
+/*         { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
+           { 0 },
+};
+MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
+
+static struct dvb_usb_device_properties gp8psk_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-gp8psk-01.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = gp8psk_streaming_ctrl,
+                       .frontend_attach  = gp8psk_frontend_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .power_ctrl       = gp8psk_power_ctrl,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 4,
+       .devices = {
+               { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
+                 .cold_ids = { &gp8psk_usb_table[0], NULL },
+                 .warm_ids = { &gp8psk_usb_table[1], NULL },
+               },
+               { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[2], NULL },
+               },
+               { .name = "Genpix SkyWalker-1 DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[3], NULL },
+               },
+               { .name = "Genpix SkyWalker-2 DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[4], NULL },
+               },
+               { NULL },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver gp8psk_usb_driver = {
+       .name           = "dvb_usb_gp8psk",
+       .probe          = gp8psk_usb_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = gp8psk_usb_table,
+};
+
+module_usb_driver(gp8psk_usb_driver);
+
+MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
+MODULE_DESCRIPTION("Driver for Genpix DVB-S");
+MODULE_VERSION("1.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
new file mode 100644 (file)
index 0000000..ed32b9d
--- /dev/null
@@ -0,0 +1,100 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_GP8PSK_H_
+#define _DVB_USB_GP8PSK_H_
+
+#define DVB_USB_LOG_PREFIX "gp8psk"
+#include "dvb-usb.h"
+
+extern int dvb_usb_gp8psk_debug;
+#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
+#define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN                     0xC0
+#define TH_COMMAND_OUT                    0xC1
+
+/* gp8psk commands */
+
+#define GET_8PSK_CONFIG                 0x80    /* in */
+#define SET_8PSK_CONFIG                 0x81
+#define I2C_WRITE                      0x83
+#define I2C_READ                       0x84
+#define ARM_TRANSFER                    0x85
+#define TUNE_8PSK                       0x86
+#define GET_SIGNAL_STRENGTH             0x87    /* in */
+#define LOAD_BCM4500                    0x88
+#define BOOT_8PSK                       0x89    /* in */
+#define START_INTERSIL                  0x8A    /* in */
+#define SET_LNB_VOLTAGE                 0x8B
+#define SET_22KHZ_TONE                  0x8C
+#define SEND_DISEQC_COMMAND             0x8D
+#define SET_DVB_MODE                    0x8E
+#define SET_DN_SWITCH                   0x8F
+#define GET_SIGNAL_LOCK                 0x90    /* in */
+#define GET_FW_VERS                    0x92
+#define GET_SERIAL_NUMBER               0x93    /* in */
+#define USE_EXTRA_VOLT                  0x94
+#define GET_FPGA_VERS                  0x95
+#define CW3K_INIT                      0x9d
+
+/* PSK_configuration bits */
+#define bm8pskStarted                   0x01
+#define bm8pskFW_Loaded                 0x02
+#define bmIntersilOn                    0x04
+#define bmDVBmode                       0x08
+#define bm22kHz                         0x10
+#define bmSEL18V                        0x20
+#define bmDCtuned                       0x40
+#define bmArmed                         0x80
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
+
+#define GET_USB_SPEED                     0x07
+
+#define RESET_FX2                         0x13
+
+#define FW_VERSION_READ                   0x0B
+#define VENDOR_STRING_READ                0x0C
+#define PRODUCT_STRING_READ               0x0D
+#define FW_BCD_VERSION_READ               0x14
+
+/* firmware revision id's */
+#define GP8PSK_FW_REV1                 0x020604
+#define GP8PSK_FW_REV2                 0x020704
+#define GP8PSK_FW_VERS(_fw_vers)       ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
+
+extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
+extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen);
+extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
new file mode 100644 (file)
index 0000000..288af29
--- /dev/null
@@ -0,0 +1,1099 @@
+/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+
+#include "m920x.h"
+
+#include "mt352.h"
+#include "mt352_priv.h"
+#include "qt1010.h"
+#include "tda1004x.h"
+#include "tda827x.h"
+
+#include <media/tuner.h>
+#include "tuner-simple.h"
+#include <asm/unaligned.h>
+
+/* debug */
+static int dvb_usb_m920x_debug;
+module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
+
+static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
+                            u16 index, void *data, int size)
+{
+       int ret;
+
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+                             request, USB_TYPE_VENDOR | USB_DIR_IN,
+                             value, index, data, size, 2000);
+       if (ret < 0) {
+               printk(KERN_INFO "m920x_read = error: %d\n", ret);
+               return ret;
+       }
+
+       if (ret != size) {
+               deb("m920x_read = no data\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static inline int m920x_write(struct usb_device *udev, u8 request,
+                             u16 value, u16 index)
+{
+       int ret;
+
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                             request, USB_TYPE_VENDOR | USB_DIR_OUT,
+                             value, index, NULL, 0, 2000);
+
+       return ret;
+}
+
+static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
+{
+       int ret = 0, i, epi, flags = 0;
+       int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
+
+       /* Remote controller init. */
+       if (d->props.rc.legacy.rc_query) {
+               deb("Initialising remote control\n");
+               while (rc_seq->address) {
+                       if ((ret = m920x_write(d->udev, M9206_CORE,
+                                              rc_seq->data,
+                                              rc_seq->address)) != 0) {
+                               deb("Initialising remote control failed\n");
+                               return ret;
+                       }
+
+                       rc_seq++;
+               }
+
+               deb("Initialising remote control success\n");
+       }
+
+       for (i = 0; i < d->props.num_adapters; i++)
+               flags |= d->adapter[i].props.fe[0].caps;
+
+       /* Some devices(Dposh) might crash if we attempt touch at all. */
+       if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
+               for (i = 0; i < d->props.num_adapters; i++) {
+                       epi = d->adapter[i].props.fe[0].stream.endpoint - 0x81;
+
+                       if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
+                               printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
+                               return -EINVAL;
+                       }
+
+                       adap_enabled[epi] = 1;
+               }
+
+               for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
+                       if (adap_enabled[i])
+                               continue;
+
+                       if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
+                               return ret;
+
+                       if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
+                               return ret;
+               }
+       }
+
+       return ret;
+}
+
+static int m920x_init_ep(struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_interface *alt;
+
+       if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
+               deb("No alt found!\n");
+               return -ENODEV;
+       }
+
+       return usb_set_interface(udev, alt->desc.bInterfaceNumber,
+                                alt->desc.bAlternateSetting);
+}
+
+static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       struct m920x_state *m = d->priv;
+       int i, ret = 0;
+       u8 *rc_state;
+
+       rc_state = kmalloc(2, GFP_KERNEL);
+       if (!rc_state)
+               return -ENOMEM;
+
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
+               goto out;
+
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
+               goto out;
+
+       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
+               if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
+                       *event = d->props.rc.legacy.rc_map_table[i].keycode;
+
+                       switch(rc_state[0]) {
+                       case 0x80:
+                               *state = REMOTE_NO_KEY_PRESSED;
+                               goto out;
+
+                       case 0x88: /* framing error or "invalid code" */
+                       case 0x99:
+                       case 0xc0:
+                       case 0xd8:
+                               *state = REMOTE_NO_KEY_PRESSED;
+                               m->rep_count = 0;
+                               goto out;
+
+                       case 0x93:
+                       case 0x92:
+                       case 0x83: /* pinnacle PCTV310e */
+                       case 0x82:
+                               m->rep_count = 0;
+                               *state = REMOTE_KEY_PRESSED;
+                               goto out;
+
+                       case 0x91:
+                       case 0x81: /* pinnacle PCTV310e */
+                               /* prevent immediate auto-repeat */
+                               if (++m->rep_count > 2)
+                                       *state = REMOTE_KEY_REPEAT;
+                               else
+                                       *state = REMOTE_NO_KEY_PRESSED;
+                               goto out;
+
+                       default:
+                               deb("Unexpected rc state %02x\n", rc_state[0]);
+                               *state = REMOTE_NO_KEY_PRESSED;
+                               goto out;
+                       }
+               }
+
+       if (rc_state[1] != 0)
+               deb("Unknown rc key %02x\n", rc_state[1]);
+
+       *state = REMOTE_NO_KEY_PRESSED;
+
+ out:
+       kfree(rc_state);
+       return ret;
+}
+
+/* I2C */
+static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i, j;
+       int ret = 0;
+
+       if (!num)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
+                       /* For a 0 byte message, I think sending the address
+                        * to index 0x80|0x40 would be the correct thing to
+                        * do.  However, zero byte messages are only used for
+                        * probing, and since we don't know how to get the
+                        * slave's ack, we can't probe. */
+                       ret = -ENOTSUPP;
+                       goto unlock;
+               }
+               /* Send START & address/RW bit */
+               if (!(msg[i].flags & I2C_M_NOSTART)) {
+                       if ((ret = m920x_write(d->udev, M9206_I2C,
+                                       (msg[i].addr << 1) |
+                                       (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
+                               goto unlock;
+                       /* Should check for ack here, if we knew how. */
+               }
+               if (msg[i].flags & I2C_M_RD) {
+                       for (j = 0; j < msg[i].len; j++) {
+                               /* Last byte of transaction?
+                                * Send STOP, otherwise send ACK. */
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
+
+                               if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
+                                                     0x20 | stop,
+                                                     &msg[i].buf[j], 1)) != 0)
+                                       goto unlock;
+                       }
+               } else {
+                       for (j = 0; j < msg[i].len; j++) {
+                               /* Last byte of transaction? Then send STOP. */
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
+
+                               if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
+                                       goto unlock;
+                               /* Should check for ack here too. */
+                       }
+               }
+       }
+       ret = num;
+
+ unlock:
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static u32 m920x_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm m920x_i2c_algo = {
+       .master_xfer   = m920x_i2c_xfer,
+       .functionality = m920x_i2c_func,
+};
+
+/* pid filter */
+static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
+{
+       int ret = 0;
+
+       if (pid >= 0x8000)
+               return -EINVAL;
+
+       pid |= 0x8000;
+
+       if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
+               return ret;
+
+       if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
+               return ret;
+
+       return ret;
+}
+
+static int m920x_update_filters(struct dvb_usb_adapter *adap)
+{
+       struct m920x_state *m = adap->dev->priv;
+       int enabled = m->filtering_enabled[adap->id];
+       int i, ret = 0, filter = 0;
+       int ep = adap->props.fe[0].stream.endpoint;
+
+       for (i = 0; i < M9206_MAX_FILTERS; i++)
+               if (m->filters[adap->id][i] == 8192)
+                       enabled = 0;
+
+       /* Disable all filters */
+       if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
+               return ret;
+
+       for (i = 0; i < M9206_MAX_FILTERS; i++)
+               if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
+                       return ret;
+
+       /* Set */
+       if (enabled) {
+               for (i = 0; i < M9206_MAX_FILTERS; i++) {
+                       if (m->filters[adap->id][i] == 0)
+                               continue;
+
+                       if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
+                               return ret;
+
+                       filter++;
+               }
+       }
+
+       return ret;
+}
+
+static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct m920x_state *m = adap->dev->priv;
+
+       m->filtering_enabled[adap->id] = onoff ? 1 : 0;
+
+       return m920x_update_filters(adap);
+}
+
+static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
+{
+       struct m920x_state *m = adap->dev->priv;
+
+       m->filters[adap->id][index] = onoff ? pid : 0;
+
+       return m920x_update_filters(adap);
+}
+
+static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
+{
+       u16 value, index, size;
+       u8 *read, *buff;
+       int i, pass, ret = 0;
+
+       buff = kmalloc(65536, GFP_KERNEL);
+       if (buff == NULL)
+               return -ENOMEM;
+
+       read = kmalloc(4, GFP_KERNEL);
+       if (!read) {
+               kfree(buff);
+               return -ENOMEM;
+       }
+
+       if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
+               goto done;
+       deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
+
+       if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
+               goto done;
+       deb("%x\n", read[0]);
+
+       for (pass = 0; pass < 2; pass++) {
+               for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
+                       value = get_unaligned_le16(fw->data + i);
+                       i += sizeof(u16);
+
+                       index = get_unaligned_le16(fw->data + i);
+                       i += sizeof(u16);
+
+                       size = get_unaligned_le16(fw->data + i);
+                       i += sizeof(u16);
+
+                       if (pass == 1) {
+                               /* Will stall if using fw->data ... */
+                               memcpy(buff, fw->data + i, size);
+
+                               ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+                                                     M9206_FW,
+                                                     USB_TYPE_VENDOR | USB_DIR_OUT,
+                                                     value, index, buff, size, 20);
+                               if (ret != size) {
+                                       deb("error while uploading fw!\n");
+                                       ret = -EIO;
+                                       goto done;
+                               }
+                               msleep(3);
+                       }
+                       i += size;
+               }
+               if (i != fw->size) {
+                       deb("bad firmware file!\n");
+                       ret = -EINVAL;
+                       goto done;
+               }
+       }
+
+       msleep(36);
+
+       /* m920x will disconnect itself from the bus after this. */
+       (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
+       deb("firmware uploaded!\n");
+
+ done:
+       kfree(read);
+       kfree(buff);
+
+       return ret;
+}
+
+/* Callbacks for DVB USB */
+static int m920x_identify_state(struct usb_device *udev,
+                               struct dvb_usb_device_properties *props,
+                               struct dvb_usb_device_description **desc,
+                               int *cold)
+{
+       struct usb_host_interface *alt;
+
+       alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
+       *cold = (alt == NULL) ? 1 : 0;
+
+       return 0;
+}
+
+/* demod configurations */
+static int m920x_mt352_demod_init(struct dvb_frontend *fe)
+{
+       int ret;
+       u8 config[] = { CONFIG, 0x3d };
+       u8 clock[] = { CLOCK_CTL, 0x30 };
+       u8 reset[] = { RESET, 0x80 };
+       u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
+       u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
+       u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
+       u8 unk1[] = { 0x93, 0x1a };
+       u8 unk2[] = { 0xb5, 0x7a };
+
+       deb("Demod init!\n");
+
+       if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
+               return ret;
+       if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
+               return ret;
+
+       return 0;
+}
+
+static struct mt352_config m920x_mt352_config = {
+       .demod_address = 0x0f,
+       .no_tuner = 1,
+       .demod_init = m920x_mt352_demod_init,
+};
+
+static struct tda1004x_config m920x_tda10046_08_config = {
+       .demod_address = 0x08,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL,
+};
+
+static struct tda1004x_config m920x_tda10046_0b_config = {
+       .demod_address = 0x0b,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL, /* uses firmware EEPROM */
+};
+
+/* tuner configurations */
+static struct qt1010_config m920x_qt1010_config = {
+       .i2c_address = 0x62
+};
+
+/* Callbacks for DVB USB */
+static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach,
+                                        &m920x_mt352_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
+                                        &m920x_tda10046_08_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
+                                        &m920x_tda10046_0b_config,
+                                        &adap->dev->i2c_adap);
+       if ((adap->fe_adap[0].fe) == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       if (dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__func__);
+
+       if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
+                  &adap->dev->i2c_adap, 0x61,
+                  TUNER_PHILIPS_FMD1216ME_MK3);
+       return 0;
+}
+
+/* device-specific initialization */
+static struct m920x_inits megasky_rc_init [] = {
+       { M9206_RC_INIT2, 0xa8 },
+       { M9206_RC_INIT1, 0x51 },
+       { } /* terminating entry */
+};
+
+static struct m920x_inits tvwalkertwin_rc_init [] = {
+       { M9206_RC_INIT2, 0x00 },
+       { M9206_RC_INIT1, 0xef },
+       { 0xff28,         0x00 },
+       { 0xff23,         0x00 },
+       { 0xff21,         0x30 },
+       { } /* terminating entry */
+};
+
+static struct m920x_inits pinnacle310e_init[] = {
+       /* without these the tuner don't work */
+       { 0xff20,         0x9b },
+       { 0xff22,         0x70 },
+
+       /* rc settings */
+       { 0xff50,         0x80 },
+       { M9206_RC_INIT1, 0x00 },
+       { M9206_RC_INIT2, 0xff },
+       { } /* terminating entry */
+};
+
+/* ir keymaps */
+static struct rc_map_table rc_map_megasky_table[] = {
+       { 0x0012, KEY_POWER },
+       { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
+       { 0x0002, KEY_CHANNELUP },
+       { 0x0005, KEY_CHANNELDOWN },
+       { 0x0003, KEY_VOLUMEUP },
+       { 0x0006, KEY_VOLUMEDOWN },
+       { 0x0004, KEY_MUTE },
+       { 0x0007, KEY_OK }, /* TS */
+       { 0x0008, KEY_STOP },
+       { 0x0009, KEY_MENU }, /* swap */
+       { 0x000a, KEY_REWIND },
+       { 0x001b, KEY_PAUSE },
+       { 0x001f, KEY_FASTFORWARD },
+       { 0x000c, KEY_RECORD },
+       { 0x000d, KEY_CAMERA }, /* screenshot */
+       { 0x000e, KEY_COFFEE }, /* "MTS" */
+};
+
+static struct rc_map_table rc_map_tvwalkertwin_table[] = {
+       { 0x0001, KEY_ZOOM }, /* Full Screen */
+       { 0x0002, KEY_CAMERA }, /* snapshot */
+       { 0x0003, KEY_MUTE },
+       { 0x0004, KEY_REWIND },
+       { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
+       { 0x0006, KEY_FASTFORWARD },
+       { 0x0007, KEY_RECORD },
+       { 0x0008, KEY_STOP },
+       { 0x0009, KEY_TIME }, /* Timeshift */
+       { 0x000c, KEY_COFFEE }, /* Recall */
+       { 0x000e, KEY_CHANNELUP },
+       { 0x0012, KEY_POWER },
+       { 0x0015, KEY_MENU }, /* source */
+       { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
+       { 0x001a, KEY_CHANNELDOWN },
+       { 0x001b, KEY_VOLUMEDOWN },
+       { 0x001e, KEY_VOLUMEUP },
+};
+
+static struct rc_map_table rc_map_pinnacle310e_table[] = {
+       { 0x16, KEY_POWER },
+       { 0x17, KEY_FAVORITES },
+       { 0x0f, KEY_TEXT },
+       { 0x48, KEY_PROGRAM },          /* preview */
+       { 0x1c, KEY_EPG },
+       { 0x04, KEY_LIST },             /* record list */
+       { 0x03, KEY_1 },
+       { 0x01, KEY_2 },
+       { 0x06, KEY_3 },
+       { 0x09, KEY_4 },
+       { 0x1d, KEY_5 },
+       { 0x1f, KEY_6 },
+       { 0x0d, KEY_7 },
+       { 0x19, KEY_8 },
+       { 0x1b, KEY_9 },
+       { 0x15, KEY_0 },
+       { 0x0c, KEY_CANCEL },
+       { 0x4a, KEY_CLEAR },
+       { 0x13, KEY_BACK },
+       { 0x00, KEY_TAB },
+       { 0x4b, KEY_UP },
+       { 0x4e, KEY_LEFT },
+       { 0x52, KEY_RIGHT },
+       { 0x51, KEY_DOWN },
+       { 0x4f, KEY_ENTER },            /* could also be KEY_OK */
+       { 0x1e, KEY_VOLUMEUP },
+       { 0x0a, KEY_VOLUMEDOWN },
+       { 0x05, KEY_CHANNELUP },
+       { 0x02, KEY_CHANNELDOWN },
+       { 0x11, KEY_RECORD },
+       { 0x14, KEY_PLAY },
+       { 0x4c, KEY_PAUSE },
+       { 0x1a, KEY_STOP },
+       { 0x40, KEY_REWIND },
+       { 0x12, KEY_FASTFORWARD },
+       { 0x41, KEY_PREVIOUSSONG },     /* Replay */
+       { 0x42, KEY_NEXTSONG },         /* Skip */
+       { 0x54, KEY_CAMERA },           /* Capture */
+/*     { 0x50, KEY_SAP },      */              /* Sap */
+       { 0x47, KEY_CYCLEWINDOWS },     /* Pip */
+       { 0x4d, KEY_SCREEN },           /* FullScreen */
+       { 0x08, KEY_SUBTITLE },
+       { 0x0e, KEY_MUTE },
+/*     { 0x49, KEY_LR },       */              /* L/R */
+       { 0x07, KEY_SLEEP },            /* Hibernate */
+       { 0x08, KEY_VIDEO },            /* A/V */
+       { 0x0e, KEY_MENU },             /* Recall */
+       { 0x45, KEY_ZOOMIN },
+       { 0x46, KEY_ZOOMOUT },
+       { 0x18, KEY_RED },              /* Red */
+       { 0x53, KEY_GREEN },            /* Green */
+       { 0x5e, KEY_YELLOW },           /* Yellow */
+       { 0x5f, KEY_BLUE },             /* Blue */
+};
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties megasky_properties;
+static struct dvb_usb_device_properties digivox_mini_ii_properties;
+static struct dvb_usb_device_properties tvwalkertwin_properties;
+static struct dvb_usb_device_properties dposh_properties;
+static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
+
+static int m920x_probe(struct usb_interface *intf,
+                      const struct usb_device_id *id)
+{
+       struct dvb_usb_device *d = NULL;
+       int ret;
+       struct m920x_inits *rc_init_seq = NULL;
+       int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
+
+       deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
+
+       if (bInterfaceNumber == 0) {
+               /* Single-tuner device, or first interface on
+                * multi-tuner device
+                */
+
+               ret = dvb_usb_device_init(intf, &megasky_properties,
+                                         THIS_MODULE, &d, adapter_nr);
+               if (ret == 0) {
+                       rc_init_seq = megasky_rc_init;
+                       goto found;
+               }
+
+               ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
+                                         THIS_MODULE, &d, adapter_nr);
+               if (ret == 0) {
+                       /* No remote control, so no rc_init_seq */
+                       goto found;
+               }
+
+               /* This configures both tuners on the TV Walker Twin */
+               ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
+                                         THIS_MODULE, &d, adapter_nr);
+               if (ret == 0) {
+                       rc_init_seq = tvwalkertwin_rc_init;
+                       goto found;
+               }
+
+               ret = dvb_usb_device_init(intf, &dposh_properties,
+                                         THIS_MODULE, &d, adapter_nr);
+               if (ret == 0) {
+                       /* Remote controller not supported yet. */
+                       goto found;
+               }
+
+               ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
+                                         THIS_MODULE, &d, adapter_nr);
+               if (ret == 0) {
+                       rc_init_seq = pinnacle310e_init;
+                       goto found;
+               }
+
+               return ret;
+       } else {
+               /* Another interface on a multi-tuner device */
+
+               /* The LifeView TV Walker Twin gets here, but struct
+                * tvwalkertwin_properties already configured both
+                * tuners, so there is nothing for us to do here
+                */
+       }
+
+ found:
+       if ((ret = m920x_init_ep(intf)) < 0)
+               return ret;
+
+       if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
+               return ret;
+
+       return ret;
+}
+
+static struct usb_device_id m920x_table [] = {
+               { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_MSI_DIGI_VOX_MINI_II) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
+               { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
+               { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, m920x_table);
+
+static struct dvb_usb_device_properties megasky_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-megasky-02.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_megasky_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_megasky_table),
+               .rc_query         = m920x_rc_query,
+       },
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                               .bulk = {
+                                       .buffersize = 512,
+                               }
+                       }
+               },
+               }},
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "MSI Mega Sky 580 DVB-T USB2.0",
+                       { &m920x_table[0], NULL },
+                       { NULL },
+               }
+       }
+};
+
+static struct dvb_usb_device_properties digivox_mini_ii_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-digivox-02.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                               .bulk = {
+                                       .buffersize = 0x4000,
+                               }
+                       }
+               },
+               }},
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "MSI DIGI VOX mini II DVB-T USB2.0",
+                       { &m920x_table[1], NULL },
+                       { NULL },
+               },
+       }
+};
+
+/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
+ *
+ * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
+ * TDA10046 #0 is located at i2c address 0x08
+ * TDA10046 #1 is located at i2c address 0x0b
+ * TDA8275A #0 is located at i2c address 0x60
+ * TDA8275A #1 is located at i2c address 0x61
+ */
+static struct dvb_usb_device_properties tvwalkertwin_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-tvwalkert.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_tvwalkertwin_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_tvwalkertwin_table),
+               .rc_query         = m920x_rc_query,
+       },
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 2,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               }},
+               }},{
+               .num_frontends = 1,
+               .fe = {{
+
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_0b_frontend_attach,
+               .tuner_attach     = m920x_tda8275_61_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x82,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               }},
+               },
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   .name = "LifeView TV Walker Twin DVB-T USB2.0",
+                   .cold_ids = { &m920x_table[2], NULL },
+                   .warm_ids = { &m920x_table[3], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dposh_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dposh-01.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+               /* Hardware pid filters don't work with this device/firmware */
+
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               },
+               }},
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+                {   .name = "Dposh DVB-T USB2.0",
+                    .cold_ids = { &m920x_table[4], NULL },
+                    .warm_ids = { &m920x_table[5], NULL },
+                },
+        }
+};
+
+static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .download_firmware = NULL,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_pinnacle310e_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_pinnacle310e_table),
+               .rc_query         = m920x_rc_query,
+       },
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_fmd1216me_tuner_attach,
+
+               .stream = {
+                       .type = USB_ISOC,
+                       .count = 5,
+                       .endpoint = 0x84,
+                       .u = {
+                               .isoc = {
+                                       .framesperurb = 128,
+                                       .framesize = 564,
+                                       .interval = 1,
+                               }
+                       }
+               },
+               }},
+       } },
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Pinnacle PCTV 310e",
+                       { &m920x_table[6], NULL },
+                       { NULL },
+               }
+       }
+};
+
+static struct usb_driver m920x_driver = {
+       .name           = "dvb_usb_m920x",
+       .probe          = m920x_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = m920x_table,
+};
+
+module_usb_driver(m920x_driver);
+
+MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
+MODULE_DESCRIPTION("DVB Driver for ULI M920x");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/usb/dvb-usb/m920x.h b/drivers/media/usb/dvb-usb/m920x.h
new file mode 100644 (file)
index 0000000..3c06151
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef _DVB_USB_M920X_H_
+#define _DVB_USB_M920X_H_
+
+#define DVB_USB_LOG_PREFIX "m920x"
+#include "dvb-usb.h"
+
+#define deb(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
+
+#define M9206_CORE     0x22
+#define M9206_RC_STATE 0xff51
+#define M9206_RC_KEY   0xff52
+#define M9206_RC_INIT1 0xff54
+#define M9206_RC_INIT2 0xff55
+#define M9206_FW_GO    0xff69
+
+#define M9206_I2C      0x23
+#define M9206_FILTER   0x25
+#define M9206_FW       0x30
+
+#define M9206_MAX_FILTERS 8
+#define M9206_MAX_ADAPTERS 4
+
+/*
+sequences found in logs:
+[index value]
+0x80 write addr
+(0x00 out byte)*
+0x40 out byte
+
+0x80 write addr
+(0x00 out byte)*
+0x80 read addr
+(0x21 in byte)*
+0x60 in byte
+
+this sequence works:
+0x80 read addr
+(0x21 in byte)*
+0x60 in byte
+
+Guess at API of the I2C function:
+I2C operation is done one byte at a time with USB control messages.  The
+index the messages is sent to is made up of a set of flags that control
+the I2C bus state:
+0x80:  Send START condition.  After a START condition, one would normally
+       always send the 7-bit slave I2C address as the 7 MSB, followed by
+       the read/write bit as the LSB.
+0x40:  Send STOP condition.  This should be set on the last byte of an
+       I2C transaction.
+0x20:  Read a byte from the slave.  As opposed to writing a byte to the
+       slave.  The slave will normally not produce any data unless you
+       set the R/W bit to 1 when sending the slave's address after the
+       START condition.
+0x01:  Respond with ACK, as opposed to a NACK.  For a multi-byte read,
+       the master should send an ACK, that is pull SDA low during the 9th
+       clock cycle, after every byte but the last.  This flags only makes
+       sense when bit 0x20 is set, indicating a read.
+
+What any other bits might mean, or how to get the slave's ACK/NACK
+response to a write, is unknown.
+*/
+
+struct m920x_state {
+       u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS];
+       int filtering_enabled[M9206_MAX_ADAPTERS];
+       int rep_count;
+};
+
+/* Initialisation data for the m920x
+ */
+
+struct m920x_inits {
+       u16 address;
+       u8  data;
+};
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
new file mode 100644 (file)
index 0000000..6c55384
--- /dev/null
@@ -0,0 +1,233 @@
+/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_rc(args...) dprintk(debug,0x01,args)
+#define deb_ee(args...) dprintk(debug,0x02,args)
+
+/* Hauppauge NOVA-T USB2 keys */
+static struct rc_map_table rc_map_haupp_table[] = {
+       { 0x1e00, KEY_0 },
+       { 0x1e01, KEY_1 },
+       { 0x1e02, KEY_2 },
+       { 0x1e03, KEY_3 },
+       { 0x1e04, KEY_4 },
+       { 0x1e05, KEY_5 },
+       { 0x1e06, KEY_6 },
+       { 0x1e07, KEY_7 },
+       { 0x1e08, KEY_8 },
+       { 0x1e09, KEY_9 },
+       { 0x1e0a, KEY_KPASTERISK },
+       { 0x1e0b, KEY_RED },
+       { 0x1e0c, KEY_RADIO },
+       { 0x1e0d, KEY_MENU },
+       { 0x1e0e, KEY_GRAVE }, /* # */
+       { 0x1e0f, KEY_MUTE },
+       { 0x1e10, KEY_VOLUMEUP },
+       { 0x1e11, KEY_VOLUMEDOWN },
+       { 0x1e12, KEY_CHANNEL },
+       { 0x1e14, KEY_UP },
+       { 0x1e15, KEY_DOWN },
+       { 0x1e16, KEY_LEFT },
+       { 0x1e17, KEY_RIGHT },
+       { 0x1e18, KEY_VIDEO },
+       { 0x1e19, KEY_AUDIO },
+       { 0x1e1a, KEY_IMAGES },
+       { 0x1e1b, KEY_EPG },
+       { 0x1e1c, KEY_TV },
+       { 0x1e1e, KEY_NEXT },
+       { 0x1e1f, KEY_BACK },
+       { 0x1e20, KEY_CHANNELUP },
+       { 0x1e21, KEY_CHANNELDOWN },
+       { 0x1e24, KEY_LAST }, /* Skip backwards */
+       { 0x1e25, KEY_OK },
+       { 0x1e29, KEY_BLUE},
+       { 0x1e2e, KEY_GREEN },
+       { 0x1e30, KEY_PAUSE },
+       { 0x1e32, KEY_REWIND },
+       { 0x1e34, KEY_FASTFORWARD },
+       { 0x1e35, KEY_PLAY },
+       { 0x1e36, KEY_STOP },
+       { 0x1e37, KEY_RECORD },
+       { 0x1e38, KEY_YELLOW },
+       { 0x1e3b, KEY_GOTO },
+       { 0x1e3d, KEY_POWER },
+};
+
+/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
+ * is delivered. No workaround yet, maybe a new firmware.
+ */
+static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
+       u16 raw;
+       int i;
+       struct dibusb_device_state *st = d->priv;
+
+       dvb_usb_generic_rw(d,cmd,2,key,5,0);
+
+       *state = REMOTE_NO_KEY_PRESSED;
+       switch (key[0]) {
+               case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
+                       raw = ((key[1] << 8) | key[2]) >> 3;
+                       toggle = !!(raw & 0x800);
+                       data = raw & 0x3f;
+                       custom = (raw >> 6) & 0x1f;
+
+                       deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
+
+                       for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
+                               if (rc5_data(&rc_map_haupp_table[i]) == data &&
+                                       rc5_custom(&rc_map_haupp_table[i]) == custom) {
+
+                                       deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
+                                                                rc5_custom(&rc_map_haupp_table[i]));
+
+                                       *event = rc_map_haupp_table[i].keycode;
+                                       *state = REMOTE_KEY_PRESSED;
+                                       if (st->old_toggle == toggle) {
+                                               if (st->last_repeat_count++ < 2)
+                                                       *state = REMOTE_NO_KEY_PRESSED;
+                                       } else {
+                                               st->last_repeat_count = 0;
+                                               st->old_toggle = toggle;
+                                       }
+                                       break;
+                               }
+                       }
+
+                       break;
+               case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
+               default:
+                       break;
+       }
+
+       return 0;
+}
+
+static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
+{
+       int i;
+       u8 b;
+
+       mac[0] = 0x00;
+       mac[1] = 0x0d;
+       mac[2] = 0xfe;
+
+       /* this is a complete guess, but works for my box */
+       for (i = 136; i < 139; i++) {
+               dibusb_read_eeprom_byte(d,i, &b);
+
+               mac[5 - (i - 136)] = b;
+       }
+
+       return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_device_properties nova_t_properties;
+
+static int nova_t_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &nova_t_properties,
+                                  THIS_MODULE, NULL, adapter_nr);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id nova_t_table [] = {
+/* 00 */       { USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_COLD) },
+/* 01 */       { USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_WARM) },
+                       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, nova_t_table);
+
+static struct dvb_usb_device_properties nova_t_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-nova-t-usb2-02.fw",
+
+       .num_adapters     = 1,
+       .adapter          = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .pid_filter       = dibusb_pid_filter,
+                       .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+                       .frontend_attach  = dibusb_dib3000mc_frontend_attach,
+                       .tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                                       .stream = {
+                                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .size_of_priv     = sizeof(struct dibusb_device_state),
+
+       .power_ctrl       = dibusb2_0_power_ctrl,
+       .read_mac_address = nova_t_read_mac_address,
+
+       .rc.legacy = {
+               .rc_interval      = 100,
+               .rc_map_table     = rc_map_haupp_table,
+               .rc_map_size      = ARRAY_SIZE(rc_map_haupp_table),
+               .rc_query         = nova_t_rc_query,
+       },
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Hauppauge WinTV-NOVA-T usb2",
+                       { &nova_t_table[0], NULL },
+                       { &nova_t_table[1], NULL },
+               },
+               { NULL },
+       }
+};
+
+static struct usb_driver nova_t_driver = {
+       .name           = "dvb_usb_nova_t_usb2",
+       .probe          = nova_t_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = nova_t_table,
+};
+
+module_usb_driver(nova_t_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
new file mode 100644 (file)
index 0000000..c8a9504
--- /dev/null
@@ -0,0 +1,583 @@
+/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
+*
+* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
+* Copyright (C) 2006 Marco Gittler (g.marco@freenet.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, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#define DVB_USB_LOG_PREFIX "opera"
+
+#include "dvb-usb.h"
+#include "stv0299.h"
+
+#define OPERA_READ_MSG 0
+#define OPERA_WRITE_MSG 1
+#define OPERA_I2C_TUNER 0xd1
+
+#define READ_FX2_REG_REQ  0xba
+#define READ_MAC_ADDR 0x08
+#define OPERA_WRITE_FX2 0xbb
+#define OPERA_TUNER_REQ 0xb1
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+
+#define ADDR_B600_VOLTAGE_13V (0x02)
+#define ADDR_B601_VOLTAGE_18V (0x03)
+#define ADDR_B1A6_STREAM_CTRL (0x04)
+#define ADDR_B880_READ_REMOTE (0x05)
+
+struct opera1_state {
+       u32 last_key_pressed;
+};
+struct rc_map_opera_table {
+       u32 keycode;
+       u32 event;
+};
+
+static int dvb_usb_opera1_debug;
+module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+                "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
+                DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+
+static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
+                           u8 * data, u16 len, int flags)
+{
+       int ret;
+       u8 tmp;
+       u8 *buf;
+       unsigned int pipe = (flags == OPERA_READ_MSG) ?
+               usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
+       u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       if (flags == OPERA_WRITE_MSG)
+               memcpy(buf, data, len);
+       ret = usb_control_msg(dev, pipe, request,
+                       request_type | USB_TYPE_VENDOR, value, 0x0,
+                       buf, len, 2000);
+
+       if (request == OPERA_TUNER_REQ) {
+               tmp = buf[0];
+               if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                           OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
+                           0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
+                       ret = 0;
+                       goto out;
+               }
+               buf[0] = tmp;
+       }
+       if (flags == OPERA_READ_MSG)
+               memcpy(data, buf, len);
+out:
+       kfree(buf);
+       return ret;
+}
+
+/* I2C */
+
+static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
+                                 u8 * buf, u16 len)
+{
+       int ret = 0;
+       u8 request;
+       u16 value;
+
+       if (!dev) {
+               info("no usb_device");
+               return -EINVAL;
+       }
+       if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
+               return -EAGAIN;
+
+       switch (addr>>1){
+               case ADDR_B600_VOLTAGE_13V:
+                       request=0xb6;
+                       value=0x00;
+                       break;
+               case ADDR_B601_VOLTAGE_18V:
+                       request=0xb6;
+                       value=0x01;
+                       break;
+               case ADDR_B1A6_STREAM_CTRL:
+                       request=0xb1;
+                       value=0xa6;
+                       break;
+               case ADDR_B880_READ_REMOTE:
+                       request=0xb8;
+                       value=0x80;
+                       break;
+               default:
+                       request=0xb1;
+                       value=addr;
+       }
+       ret = opera1_xilinx_rw(dev->udev, request,
+               value, buf, len,
+               addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
+
+       mutex_unlock(&dev->usb_mutex);
+       return ret;
+}
+
+static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                          int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i = 0, tmp = 0;
+
+       if (!d)
+               return -ENODEV;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               if ((tmp = opera1_usb_i2c_msgxfer(d,
+                                       (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
+                                       msg[i].buf,
+                                       msg[i].len
+                                       )) != msg[i].len) {
+                       break;
+               }
+               if (dvb_usb_opera1_debug & 0x10)
+                       info("sending i2c mesage %d %d", tmp, msg[i].len);
+       }
+       mutex_unlock(&d->i2c_mutex);
+       return num;
+}
+
+static u32 opera1_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm opera1_i2c_algo = {
+       .master_xfer = opera1_i2c_xfer,
+       .functionality = opera1_i2c_func,
+};
+
+static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       static u8 command_13v[1]={0x00};
+       static u8 command_18v[1]={0x01};
+       struct i2c_msg msg[] = {
+               {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
+       };
+       struct dvb_usb_adapter *udev_adap =
+           (struct dvb_usb_adapter *)(fe->dvb->priv);
+       if (voltage == SEC_VOLTAGE_18) {
+               msg[0].addr = ADDR_B601_VOLTAGE_18V;
+               msg[0].buf = command_18v;
+       }
+       i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+       return 0;
+}
+
+static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
+                                         u32 ratio)
+{
+       stv0299_writereg(fe, 0x13, 0x98);
+       stv0299_writereg(fe, 0x14, 0x95);
+       stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
+       return 0;
+
+}
+static u8 opera1_inittab[] = {
+       0x00, 0xa1,
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,
+       0x05, 0x05,
+       0x06, 0x02,
+       0x07, 0x00,
+       0x0b, 0x00,
+       0x0c, 0x01,
+       0x0d, 0x81,
+       0x0e, 0x44,
+       0x0f, 0x19,
+       0x10, 0x3f,
+       0x11, 0x84,
+       0x12, 0xda,
+       0x13, 0x98,
+       0x14, 0x95,
+       0x15, 0xc9,
+       0x16, 0xeb,
+       0x17, 0x00,
+       0x18, 0x19,
+       0x19, 0x8b,
+       0x1a, 0x00,
+       0x1b, 0x82,
+       0x1c, 0x7f,
+       0x1d, 0x00,
+       0x1e, 0x00,
+       REG_1F_SYMBOLRATE_BYTE0, 0x06,
+       REG_20_SYMBOLRATE_BYTE1, 0x50,
+       REG_21_SYMBOLRATE_BYTE2, 0x10,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x24, 0x37,
+       0x25, 0xbc,
+       0x26, 0x00,
+       0x27, 0x00,
+       0x28, 0x00,
+       0x29, 0x1e,
+       0x2a, 0x14,
+       0x2b, 0x1f,
+       0x2c, 0x09,
+       0x2d, 0x0a,
+       0x2e, 0x00,
+       0x2f, 0x00,
+       0x30, 0x00,
+       0x31, 0x1f,
+       0x32, 0x19,
+       0x33, 0xfc,
+       0x34, 0x13,
+       0xff, 0xff,
+};
+
+static struct stv0299_config opera1_stv0299_config = {
+       .demod_address = 0xd0>>1,
+       .min_delay_ms = 100,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_0,
+       .volt13_op0_op1 = STV0299_VOLT13_OP0,
+       .inittab = opera1_inittab,
+       .set_symbol_rate = opera1_stv0299_set_symbol_rate,
+};
+
+static int opera1_frontend_attach(struct dvb_usb_adapter *d)
+{
+       d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
+                                     &d->dev->i2c_adap);
+       if ((d->fe_adap[0].fe) != NULL) {
+               d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage;
+               return 0;
+       }
+       info("not attached stv0299");
+       return -EIO;
+}
+
+static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       dvb_attach(
+               dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1,
+               &adap->dev->i2c_adap, DVB_PLL_OPERA1
+       );
+       return 0;
+}
+
+static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 val = onoff ? 0x01 : 0x00;
+
+       if (dvb_usb_opera1_debug)
+               info("power %s", onoff ? "on" : "off");
+       return opera1_xilinx_rw(d->udev, 0xb7, val,
+                               &val, 1, OPERA_WRITE_MSG);
+}
+
+static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       static u8 buf_start[2] = { 0xff, 0x03 };
+       static u8 buf_stop[2] = { 0xff, 0x00 };
+       struct i2c_msg start_tuner[] = {
+               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
+       };
+       if (dvb_usb_opera1_debug)
+               info("streaming %s", onoff ? "on" : "off");
+       i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
+       return 0;
+}
+
+static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+                            int onoff)
+{
+       u8 b_pid[3];
+       struct i2c_msg msg[] = {
+               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+       };
+       if (dvb_usb_opera1_debug)
+               info("pidfilter index: %d pid: %d %s", index, pid,
+                       onoff ? "on" : "off");
+       b_pid[0] = (2 * index) + 4;
+       b_pid[1] = onoff ? (pid & 0xff) : (0x00);
+       b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
+       i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+       return 0;
+}
+
+static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
+{
+       int u = 0x04;
+       u8 b_pid[3];
+       struct i2c_msg msg[] = {
+               {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+       };
+       if (dvb_usb_opera1_debug)
+               info("%s hw-pidfilter", onoff ? "enable" : "disable");
+       for (; u < 0x7e; u += 2) {
+               b_pid[0] = u;
+               b_pid[1] = 0;
+               b_pid[2] = 0x80;
+               i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+       }
+       return 0;
+}
+
+static struct rc_map_table rc_map_opera1_table[] = {
+       {0x5fa0, KEY_1},
+       {0x51af, KEY_2},
+       {0x5da2, KEY_3},
+       {0x41be, KEY_4},
+       {0x0bf5, KEY_5},
+       {0x43bd, KEY_6},
+       {0x47b8, KEY_7},
+       {0x49b6, KEY_8},
+       {0x05fa, KEY_9},
+       {0x45ba, KEY_0},
+       {0x09f6, KEY_CHANNELUP},        /*chanup */
+       {0x1be5, KEY_CHANNELDOWN},      /*chandown */
+       {0x5da3, KEY_VOLUMEDOWN},       /*voldown */
+       {0x5fa1, KEY_VOLUMEUP},         /*volup */
+       {0x07f8, KEY_SPACE},            /*tab */
+       {0x1fe1, KEY_OK},               /*play ok */
+       {0x1be4, KEY_ZOOM},             /*zoom */
+       {0x59a6, KEY_MUTE},             /*mute */
+       {0x5ba5, KEY_RADIO},            /*tv/f */
+       {0x19e7, KEY_RECORD},           /*rec */
+       {0x01fe, KEY_STOP},             /*Stop */
+       {0x03fd, KEY_PAUSE},            /*pause */
+       {0x03fc, KEY_SCREEN},           /*<- -> */
+       {0x07f9, KEY_CAMERA},           /*capture */
+       {0x47b9, KEY_ESC},              /*exit */
+       {0x43bc, KEY_POWER2},           /*power */
+};
+
+static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
+{
+       struct opera1_state *opst = dev->priv;
+       u8 rcbuffer[32];
+       const u16 startmarker1 = 0x10ed;
+       const u16 startmarker2 = 0x11ec;
+       struct i2c_msg read_remote[] = {
+               {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
+       };
+       int i = 0;
+       u32 send_key = 0;
+
+       if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
+               for (i = 0; i < 32; i++) {
+                       if (rcbuffer[i])
+                               send_key |= 1;
+                       if (i < 31)
+                               send_key = send_key << 1;
+               }
+               if (send_key & 0x8000)
+                       send_key = (send_key << 1) | (send_key >> 15 & 0x01);
+
+               if (send_key == 0xffff && opst->last_key_pressed != 0) {
+                       *state = REMOTE_KEY_REPEAT;
+                       *event = opst->last_key_pressed;
+                       return 0;
+               }
+               for (; send_key != 0;) {
+                       if (send_key >> 16 == startmarker2) {
+                               break;
+                       } else if (send_key >> 16 == startmarker1) {
+                               send_key =
+                                       (send_key & 0xfffeffff) | (startmarker1 << 16);
+                               break;
+                       } else
+                               send_key >>= 1;
+               }
+
+               if (send_key == 0)
+                       return 0;
+
+               send_key = (send_key & 0xffff) | 0x0100;
+
+               for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
+                       if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
+                               *state = REMOTE_KEY_PRESSED;
+                               *event = rc_map_opera1_table[i].keycode;
+                               opst->last_key_pressed =
+                                       rc_map_opera1_table[i].keycode;
+                               break;
+                       }
+                       opst->last_key_pressed = 0;
+               }
+       } else
+               *state = REMOTE_NO_KEY_PRESSED;
+       return 0;
+}
+
+static struct usb_device_id opera1_table[] = {
+       {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
+       {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, opera1_table);
+
+static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+       u8 command[] = { READ_MAC_ADDR };
+       opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
+       opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
+       return 0;
+}
+static int opera1_xilinx_load_firmware(struct usb_device *dev,
+                                      const char *filename)
+{
+       const struct firmware *fw = NULL;
+       u8 *b, *p;
+       int ret = 0, i,fpgasize=40;
+       u8 testval;
+       info("start downloading fpga firmware %s",filename);
+
+       if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
+               err("did not find the firmware file. (%s) "
+                       "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+                       filename);
+               return ret;
+       } else {
+               p = kmalloc(fw->size, GFP_KERNEL);
+               opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
+               if (p != NULL && testval != 0x67) {
+
+                       u8 reset = 0, fpga_command = 0;
+                       memcpy(p, fw->data, fw->size);
+                       /* clear fpga ? */
+                       opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
+                                        OPERA_WRITE_MSG);
+                       for (i = 0; i < fw->size;) {
+                               if ( (fw->size - i) <fpgasize){
+                                   fpgasize=fw->size-i;
+                               }
+                               b = (u8 *) p + i;
+                               if (opera1_xilinx_rw
+                                       (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
+                                               OPERA_WRITE_MSG) != fpgasize
+                                       ) {
+                                       err("error while transferring firmware");
+                                       ret = -EINVAL;
+                                       break;
+                               }
+                               i = i + fpgasize;
+                       }
+                       /* restart the CPU */
+                       if (ret || opera1_xilinx_rw
+                                       (dev, 0xa0, 0xe600, &reset, 1,
+                                       OPERA_WRITE_MSG) != 1) {
+                               err("could not restart the USB controller CPU.");
+                               ret = -EINVAL;
+                       }
+               }
+       }
+       kfree(p);
+       release_firmware(fw);
+       return ret;
+}
+
+static struct dvb_usb_device_properties opera1_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-opera-01.fw",
+       .size_of_priv = sizeof(struct opera1_state),
+
+       .power_ctrl = opera1_power_ctrl,
+       .i2c_algo = &opera1_i2c_algo,
+
+       .rc.legacy = {
+               .rc_map_table = rc_map_opera1_table,
+               .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
+               .rc_interval = 200,
+               .rc_query = opera1_rc_query,
+       },
+       .read_mac_address = opera1_read_mac_address,
+       .generic_bulk_ctrl_endpoint = 0x00,
+       /* parameter for the MPEG2-data transfer */
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = opera1_frontend_attach,
+                       .streaming_ctrl = opera1_streaming_ctrl,
+                       .tuner_attach = opera1_tuner_attach,
+                       .caps =
+                               DVB_USB_ADAP_HAS_PID_FILTER |
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter = opera1_pid_filter,
+                       .pid_filter_ctrl = opera1_pid_filter_control,
+                       .pid_filter_count = 252,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 10,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .num_device_descs = 1,
+       .devices = {
+               {"Opera1 DVB-S USB2.0",
+                       {&opera1_table[0], NULL},
+                       {&opera1_table[1], NULL},
+               },
+       }
+};
+
+static int opera1_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+
+       if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
+               udev->descriptor.idVendor == USB_VID_OPERA1 &&
+               opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
+           ) {
+               return -EINVAL;
+       }
+
+       if (0 != dvb_usb_device_init(intf, &opera1_properties,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return -EINVAL;
+       return 0;
+}
+
+static struct usb_driver opera1_driver = {
+       .name = "opera1",
+       .probe = opera1_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table = opera1_table,
+};
+
+module_usb_driver(opera1_driver);
+
+MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
+MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
+MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
new file mode 100644 (file)
index 0000000..02e8785
--- /dev/null
@@ -0,0 +1,1063 @@
+/*
+ * PCTV 452e DVB driver
+ *
+ * Copyright (c) 2006-2008 Dominik Kuhlen <dkuhlen@gmx.net>
+ *
+ * TT connect S2-3650-CI Common Interface support, MAC readout
+ * Copyright (C) 2008 Michael H. Schimek <mschimek@gmx.at>
+ *
+ * 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.
+ */
+
+/* dvb usb framework */
+#define DVB_USB_LOG_PREFIX "pctv452e"
+#include "dvb-usb.h"
+
+/* Demodulator */
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+/* Tuner */
+#include "stb6100.h"
+#include "stb6100_cfg.h"
+/* FE Power */
+#include "lnbp22.h"
+
+#include "dvb_ca_en50221.h"
+#include "ttpci-eeprom.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 ISOC_INTERFACE_ALTERNATIVE 3
+
+#define SYNC_BYTE_OUT 0xaa
+#define SYNC_BYTE_IN  0x55
+
+/* guessed: (copied from ttusb-budget) */
+#define PCTV_CMD_RESET 0x15
+/* command to poll IR receiver */
+#define PCTV_CMD_IR    0x1b
+/* command to send I2C  */
+#define PCTV_CMD_I2C   0x31
+
+#define I2C_ADDR_STB0899 (0xd0 >> 1)
+#define I2C_ADDR_STB6100 (0xc0 >> 1)
+#define I2C_ADDR_LNBP22  (0x10 >> 1)
+#define I2C_ADDR_24C16   (0xa0 >> 1)
+#define I2C_ADDR_24C64   (0xa2 >> 1)
+
+
+/* pctv452e sends us this amount of data for each issued usb-command */
+#define PCTV_ANSWER_LEN 64
+/* Wait up to 1000ms for device  */
+#define PCTV_TIMEOUT 1000
+
+
+#define PCTV_LED_GPIO   STB0899_GPIO01
+#define PCTV_LED_GREEN  0x82
+#define PCTV_LED_ORANGE 0x02
+
+#define ci_dbg(format, arg...)                         \
+do {                                                   \
+       if (0)                                          \
+               printk(KERN_DEBUG DVB_USB_LOG_PREFIX    \
+                       ": " format "\n" , ## arg);     \
+} while (0)
+
+enum {
+       TT3650_CMD_CI_TEST = 0x40,
+       TT3650_CMD_CI_RD_CTRL,
+       TT3650_CMD_CI_WR_CTRL,
+       TT3650_CMD_CI_RD_ATTR,
+       TT3650_CMD_CI_WR_ATTR,
+       TT3650_CMD_CI_RESET,
+       TT3650_CMD_CI_SET_VIDEO_PORT
+};
+
+
+static struct stb0899_postproc pctv45e_postproc[] = {
+       { PCTV_LED_GPIO, STB0899_GPIOPULLUP },
+       { 0, 0 }
+};
+
+/*
+ * stores all private variables for communication with the PCTV452e DVB-S2
+ */
+struct pctv452e_state {
+       struct dvb_ca_en50221 ca;
+       struct mutex ca_mutex;
+
+       u8 c;      /* transaction counter, wraps around...  */
+       u8 initialized; /* set to 1 if 0x15 has been sent */
+       u16 last_rc_key;
+};
+
+static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
+                        unsigned int write_len, unsigned int read_len)
+{
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       u8 buf[64];
+       u8 id;
+       unsigned int rlen;
+       int ret;
+
+       BUG_ON(NULL == data && 0 != (write_len | read_len));
+       BUG_ON(write_len > 64 - 4);
+       BUG_ON(read_len > 64 - 4);
+
+       id = state->c++;
+
+       buf[0] = SYNC_BYTE_OUT;
+       buf[1] = id;
+       buf[2] = cmd;
+       buf[3] = write_len;
+
+       memcpy(buf + 4, data, write_len);
+
+       rlen = (read_len > 0) ? 64 : 0;
+       ret = dvb_usb_generic_rw(d, buf, 4 + write_len,
+                                 buf, rlen, /* delay_ms */ 0);
+       if (0 != ret)
+               goto failed;
+
+       ret = -EIO;
+       if (SYNC_BYTE_IN != buf[0] || id != buf[1])
+               goto failed;
+
+       memcpy(data, buf + 4, read_len);
+
+       return 0;
+
+failed:
+       err("CI error %d; %02X %02X %02X -> %*ph.",
+            ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
+
+       return ret;
+}
+
+static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca,
+                               u8 cmd, u8 *data, unsigned int write_len,
+                               unsigned int read_len)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       int ret;
+
+       mutex_lock(&state->ca_mutex);
+       ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
+       mutex_unlock(&state->ca_mutex);
+
+       return ret;
+}
+
+static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
+                                int slot, int address)
+{
+       u8 buf[3];
+       int ret;
+
+       if (0 != slot)
+               return -EINVAL;
+
+       buf[0] = (address >> 8) & 0x0F;
+       buf[1] = address;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
+
+       ci_dbg("%s %04x -> %d 0x%02x",
+               __func__, address, ret, buf[2]);
+
+       if (ret < 0)
+               return ret;
+
+       return buf[2];
+}
+
+static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
+                                int slot, int address, u8 value)
+{
+       u8 buf[3];
+
+       ci_dbg("%s %d 0x%04x 0x%02x",
+               __func__, slot, address, value);
+
+       if (0 != slot)
+               return -EINVAL;
+
+       buf[0] = (address >> 8) & 0x0F;
+       buf[1] = address;
+       buf[2] = value;
+
+       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
+}
+
+static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca,
+                                int                    slot,
+                                u8                     address)
+{
+       u8 buf[2];
+       int ret;
+
+       if (0 != slot)
+               return -EINVAL;
+
+       buf[0] = address & 3;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
+
+       ci_dbg("%s 0x%02x -> %d 0x%02x",
+               __func__, address, ret, buf[1]);
+
+       if (ret < 0)
+               return ret;
+
+       return buf[1];
+}
+
+static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca,
+                                int                    slot,
+                                u8                     address,
+                                u8                     value)
+{
+       u8 buf[2];
+
+       ci_dbg("%s %d 0x%02x 0x%02x",
+               __func__, slot, address, value);
+
+       if (0 != slot)
+               return -EINVAL;
+
+       buf[0] = address;
+       buf[1] = value;
+
+       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
+}
+
+static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca,
+                                int                    slot,
+                                int                    enable)
+{
+       u8 buf[1];
+       int ret;
+
+       ci_dbg("%s %d %d", __func__, slot, enable);
+
+       if (0 != slot)
+               return -EINVAL;
+
+       enable = !!enable;
+       buf[0] = enable;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
+       if (ret < 0)
+               return ret;
+
+       if (enable != buf[0]) {
+               err("CI not %sabled.", enable ? "en" : "dis");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       return tt3650_ci_set_video_port(ca, slot, /* enable */ 0);
+}
+
+static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       return tt3650_ci_set_video_port(ca, slot, /* enable */ 1);
+}
+
+static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       u8 buf[1];
+       int ret;
+
+       ci_dbg("%s %d", __func__, slot);
+
+       if (0 != slot)
+               return -EINVAL;
+
+       buf[0] = 0;
+
+       mutex_lock(&state->ca_mutex);
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
+       if (0 != ret)
+               goto failed;
+
+       msleep(500);
+
+       buf[0] = 1;
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
+       if (0 != ret)
+               goto failed;
+
+       msleep(500);
+
+       buf[0] = 0; /* FTA */
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
+
+ failed:
+       mutex_unlock(&state->ca_mutex);
+
+       return ret;
+}
+
+static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca,
+                                int                    slot,
+                                int                    open)
+{
+       u8 buf[1];
+       int ret;
+
+       if (0 != slot)
+               return -EINVAL;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
+       if (0 != ret)
+               return ret;
+
+       if (1 == buf[0])
+               return DVB_CA_EN50221_POLL_CAM_PRESENT |
+                       DVB_CA_EN50221_POLL_CAM_READY;
+
+       return 0;
+
+}
+
+static void tt3650_ci_uninit(struct dvb_usb_device *d)
+{
+       struct pctv452e_state *state;
+
+       ci_dbg("%s", __func__);
+
+       if (NULL == d)
+               return;
+
+       state = (struct pctv452e_state *)d->priv;
+       if (NULL == state)
+               return;
+
+       if (NULL == state->ca.data)
+               return;
+
+       /* Error ignored. */
+       tt3650_ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0);
+
+       dvb_ca_en50221_release(&state->ca);
+
+       memset(&state->ca, 0, sizeof(state->ca));
+}
+
+static int tt3650_ci_init(struct dvb_usb_adapter *a)
+{
+       struct dvb_usb_device *d = a->dev;
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       int ret;
+
+       ci_dbg("%s", __func__);
+
+       mutex_init(&state->ca_mutex);
+
+       state->ca.owner = THIS_MODULE;
+       state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
+       state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
+       state->ca.read_cam_control = tt3650_ci_read_cam_control;
+       state->ca.write_cam_control = tt3650_ci_write_cam_control;
+       state->ca.slot_reset = tt3650_ci_slot_reset;
+       state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
+       state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
+       state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
+       state->ca.data = d;
+
+       ret = dvb_ca_en50221_init(&a->dvb_adap,
+                                  &state->ca,
+                                  /* flags */ 0,
+                                  /* n_slots */ 1);
+       if (0 != ret) {
+               err("Cannot initialize CI: Error %d.", ret);
+               memset(&state->ca, 0, sizeof(state->ca));
+               return ret;
+       }
+
+       info("CI initialized.");
+
+       return 0;
+}
+
+#define CMD_BUFFER_SIZE 0x28
+static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                               const u8 *snd_buf, u8 snd_len,
+                               u8 *rcv_buf, u8 rcv_len)
+{
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       u8 buf[64];
+       u8 id;
+       int ret;
+
+       id = state->c++;
+
+       ret = -EINVAL;
+       if (snd_len > 64 - 7 || rcv_len > 64 - 7)
+               goto failed;
+
+       buf[0] = SYNC_BYTE_OUT;
+       buf[1] = id;
+       buf[2] = PCTV_CMD_I2C;
+       buf[3] = snd_len + 3;
+       buf[4] = addr << 1;
+       buf[5] = snd_len;
+       buf[6] = rcv_len;
+
+       memcpy(buf + 7, snd_buf, snd_len);
+
+       ret = dvb_usb_generic_rw(d, buf, 7 + snd_len,
+                                 buf, /* rcv_len */ 64,
+                                 /* delay_ms */ 0);
+       if (ret < 0)
+               goto failed;
+
+       /* TT USB protocol error. */
+       ret = -EIO;
+       if (SYNC_BYTE_IN != buf[0] || id != buf[1])
+               goto failed;
+
+       /* I2C device didn't respond as expected. */
+       ret = -EREMOTEIO;
+       if (buf[5] < snd_len || buf[6] < rcv_len)
+               goto failed;
+
+       memcpy(rcv_buf, buf + 7, rcv_len);
+
+       return rcv_len;
+
+failed:
+       err("I2C error %d; %02X %02X  %02X %02X %02X -> "
+            "%02X %02X  %02X %02X %02X.",
+            ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len,
+            buf[0], buf[1], buf[4], buf[5], buf[6]);
+
+       return ret;
+}
+
+static int pctv452e_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg,
+                               int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adapter);
+       int i;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
+               int ret;
+
+               if (msg[i].flags & I2C_M_RD) {
+                       addr = msg[i].addr;
+                       snd_buf = NULL;
+                       snd_len = 0;
+                       rcv_buf = msg[i].buf;
+                       rcv_len = msg[i].len;
+               } else {
+                       addr = msg[i].addr;
+                       snd_buf = msg[i].buf;
+                       snd_len = msg[i].len;
+                       rcv_buf = NULL;
+                       rcv_len = 0;
+               }
+
+               ret = pctv452e_i2c_msg(d, addr, snd_buf, snd_len, rcv_buf,
+                                       rcv_len);
+               if (ret < rcv_len)
+                       break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 pctv452e_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
+{
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 };
+       u8 rx[PCTV_ANSWER_LEN];
+       int ret;
+
+       info("%s: %d\n", __func__, i);
+
+       if (!i)
+               return 0;
+
+       if (state->initialized)
+               return 0;
+
+       /* hmm where shoud this should go? */
+       ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
+       if (ret != 0)
+               info("%s: Warning set interface returned: %d\n",
+                       __func__, ret);
+
+       /* this is a one-time initialization, dont know where to put */
+       b0[1] = state->c++;
+       /* reset board */
+       ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
+       if (ret)
+               return ret;
+
+       b0[1] = state->c++;
+       b0[4] = 1;
+       /* reset board (again?) */
+       ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
+       if (ret)
+               return ret;
+
+       state->initialized = 1;
+
+       return 0;
+}
+
+static int pctv452e_rc_query(struct dvb_usb_device *d)
+{
+       struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
+       u8 b[CMD_BUFFER_SIZE];
+       u8 rx[PCTV_ANSWER_LEN];
+       int ret, i;
+       u8 id = state->c++;
+
+       /* prepare command header  */
+       b[0] = SYNC_BYTE_OUT;
+       b[1] = id;
+       b[2] = PCTV_CMD_IR;
+       b[3] = 0;
+
+       /* send ir request */
+       ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
+       if (ret != 0)
+               return ret;
+
+       if (debug > 3) {
+               info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
+               for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
+                       info(" %02x", rx[i+3]);
+
+               info("\n");
+       }
+
+       if ((rx[3] == 9) &&  (rx[12] & 0x01)) {
+               /* got a "press" event */
+               state->last_rc_key = (rx[7] << 8) | rx[6];
+               if (debug > 2)
+                       info("%s: cmd=0x%02x sys=0x%02x\n",
+                               __func__, rx[6], rx[7]);
+
+               rc_keydown(d->rc_dev, state->last_rc_key, 0);
+       } else if (state->last_rc_key) {
+               rc_keyup(d->rc_dev);
+               state->last_rc_key = 0;
+       }
+
+       return 0;
+}
+
+static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+       const u8 mem_addr[] = { 0x1f, 0xcc };
+       u8 encoded_mac[20];
+       int ret;
+
+       ret = -EAGAIN;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               goto failed;
+
+       ret = pctv452e_i2c_msg(d, I2C_ADDR_24C16,
+                               mem_addr + 1, /* snd_len */ 1,
+                               encoded_mac, /* rcv_len */ 20);
+       if (-EREMOTEIO == ret)
+               /* Caution! A 24C16 interprets 0xA2 0x1F 0xCC as a
+                  byte write if /WC is low. */
+               ret = pctv452e_i2c_msg(d, I2C_ADDR_24C64,
+                                       mem_addr, 2,
+                                       encoded_mac, 20);
+
+       mutex_unlock(&d->i2c_mutex);
+
+       if (20 != ret)
+               goto failed;
+
+       ret = ttpci_eeprom_decode_mac(mac, encoded_mac);
+       if (0 != ret)
+               goto failed;
+
+       return 0;
+
+failed:
+       memset(mac, 0, 6);
+
+       return ret;
+}
+
+static const struct stb0899_s1_reg pctv452e_init_dev[] = {
+       { STB0899_DISCNTRL1,    0x26 },
+       { STB0899_DISCNTRL2,    0x80 },
+       { STB0899_DISRX_ST0,    0x04 },
+       { STB0899_DISRX_ST1,    0x20 },
+       { STB0899_DISPARITY,    0x00 },
+       { STB0899_DISFIFO,      0x00 },
+       { STB0899_DISF22,       0x99 },
+       { STB0899_DISF22RX,     0x85 }, /* 0xa8 */
+       { STB0899_ACRPRESC,     0x11 },
+       { STB0899_ACRDIV1,      0x0a },
+       { STB0899_ACRDIV2,      0x05 },
+       { STB0899_DACR1 ,       0x00 },
+       { STB0899_DACR2 ,       0x00 },
+       { STB0899_OUTCFG,       0x00 },
+       { STB0899_MODECFG,      0x00 }, /* Inversion */
+       { STB0899_IRQMSK_3,     0xf3 },
+       { STB0899_IRQMSK_2,     0xfc },
+       { STB0899_IRQMSK_1,     0xff },
+       { STB0899_IRQMSK_0,     0xff },
+       { STB0899_I2CCFG,       0x88 },
+       { STB0899_I2CRPT,       0x58 },
+       { STB0899_GPIO00CFG,    0x82 },
+       { STB0899_GPIO01CFG,    0x82 }, /* LED: 0x02 green, 0x82 orange */
+       { 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 DVB-S; 0x1c DVB-S2 (1c, rjkm) */
+       { STB0899_GPIO22,       0x82 },
+       { STB0899_GPIO21,       0x91 },
+       { STB0899_DIRCLKCFG,    0x82 },
+       { STB0899_CLKOUT27CFG,  0x7e },
+       { STB0899_STDBYCFG,     0x82 },
+       { STB0899_CS0CFG,       0x82 },
+       { STB0899_CS1CFG,       0x82 },
+       { STB0899_DISEQCOCFG,   0x20 },
+       { STB0899_NCOARSE,      0x15 }, /* 0x15 27Mhz, F/3 198MHz, F/6 108MHz */
+       { STB0899_SYNTCTRL,     0x00 }, /* 0x00 CLKI, 0x02 XTALI */
+       { STB0899_FILTCTRL,     0x00 },
+       { STB0899_SYSCTRL,      0x00 },
+       { STB0899_STOPCLK1,     0x20 }, /* orig: 0x00 budget-ci: 0x20 */
+       { STB0899_STOPCLK2,     0x00 },
+       { STB0899_INTBUFCTRL,   0x0a },
+       { STB0899_AGC2I1,       0x00 },
+       { STB0899_AGC2I2,       0x00 },
+       { STB0899_AGCIQIN,      0x00 },
+       { STB0899_TSTRES,       0x40 }, /* rjkm */
+       { 0xffff,               0xff },
+};
+
+static const struct stb0899_s1_reg pctv452e_init_s1_demod[] = {
+       { 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 },
+};
+
+static struct stb0899_config stb0899_config = {
+       .init_dev       = pctv452e_init_dev,
+       .init_s2_demod  = stb0899_s2_init_2,
+       .init_s1_demod  = pctv452e_init_s1_demod,
+       .init_s2_fec    = stb0899_s2_init_4,
+       .init_tst       = stb0899_s1_init_5,
+
+       .demod_address   = I2C_ADDR_STB0899, /* I2C Address */
+       .block_sync_mode = STB0899_SYNC_FORCED, /* ? */
+
+       .xtal_freq       = 27000000,     /* Assume Hz ? */
+       .inversion       = IQ_SWAP_ON,       /* ? */
+
+       .lo_clk   = 76500000,
+       .hi_clk   = 99000000,
+
+       .ts_output_mode  = 0,   /* Use parallel mode */
+       .clock_polarity  = 0,
+       .data_clk_parity = 0,
+       .fec_mode       = 0,
+
+       .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,
+
+       /* helper for switching LED green/orange */
+       .postproc = pctv45e_postproc
+};
+
+static struct stb6100_config stb6100_config = {
+       .tuner_address = I2C_ADDR_STB6100,
+       .refclock      = 27000000
+};
+
+
+static struct i2c_algorithm pctv452e_i2c_algo = {
+       .master_xfer   = pctv452e_i2c_xfer,
+       .functionality = pctv452e_i2c_func
+};
+
+static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
+{
+       struct usb_device_id *id;
+
+       a->fe_adap[0].fe = dvb_attach(stb0899_attach, &stb0899_config,
+                                               &a->dev->i2c_adap);
+       if (!a->fe_adap[0].fe)
+               return -ENODEV;
+       if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
+                                       &a->dev->i2c_adap)) == 0)
+               err("Cannot attach lnbp22\n");
+
+       id = a->dev->desc->warm_ids[0];
+       if (USB_VID_TECHNOTREND == id->idVendor
+           && USB_PID_TECHNOTREND_CONNECT_S2_3650_CI == id->idProduct)
+               /* Error ignored. */
+               tt3650_ci_init(a);
+
+       return 0;
+}
+
+static int pctv452e_tuner_attach(struct dvb_usb_adapter *a)
+{
+       if (!a->fe_adap[0].fe)
+               return -ENODEV;
+       if (dvb_attach(stb6100_attach, a->fe_adap[0].fe, &stb6100_config,
+                                       &a->dev->i2c_adap) == 0) {
+               err("%s failed\n", __func__);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static struct usb_device_id pctv452e_usb_table[] = {
+       {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_452E)},
+       {USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2_3600)},
+       {USB_DEVICE(USB_VID_TECHNOTREND,
+                               USB_PID_TECHNOTREND_CONNECT_S2_3650_CI)},
+       {}
+};
+MODULE_DEVICE_TABLE(usb, pctv452e_usb_table);
+
+static struct dvb_usb_device_properties pctv452e_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
+       .usb_ctrl = DEVICE_SPECIFIC,
+
+       .size_of_priv     = sizeof(struct pctv452e_state),
+
+       .power_ctrl       = pctv452e_power_ctrl,
+
+       .rc.core = {
+               .rc_codes       = RC_MAP_DIB0700_RC5_TABLE,
+               .allowed_protos = RC_TYPE_UNKNOWN,
+               .rc_query       = pctv452e_rc_query,
+               .rc_interval    = 100,
+       },
+
+       .num_adapters     = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach  = pctv452e_frontend_attach,
+                       .tuner_attach     = pctv452e_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type     = USB_ISOC,
+                               .count    = 4,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize    = 940,
+                                               .interval     = 1
+                                       }
+                               }
+                       },
+               } },
+       } },
+
+       .i2c_algo = &pctv452e_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 1, /* allow generice rw function */
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "PCTV HDTV USB",
+                 .cold_ids = { NULL, NULL }, /* this is a warm only device */
+                 .warm_ids = { &pctv452e_usb_table[0], NULL }
+               },
+               { 0 },
+       }
+};
+
+static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
+       .usb_ctrl = DEVICE_SPECIFIC,
+
+       .size_of_priv           = sizeof(struct pctv452e_state),
+
+       .power_ctrl             = pctv452e_power_ctrl,
+       .read_mac_address       = pctv452e_read_mac_address,
+
+       .rc.core = {
+               .rc_codes       = RC_MAP_TT_1500,
+               .allowed_protos = RC_TYPE_UNKNOWN,
+               .rc_query       = pctv452e_rc_query,
+               .rc_interval    = 100,
+       },
+
+       .num_adapters           = 1,
+       .adapter = {{
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach = pctv452e_frontend_attach,
+                       .tuner_attach = pctv452e_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize = 940,
+                                               .interval = 1
+                                       }
+                               }
+                       },
+
+               } },
+       } },
+
+       .i2c_algo = &pctv452e_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 1, /* allow generic rw function*/
+
+       .num_device_descs = 2,
+       .devices = {
+               { .name = "Technotrend TT Connect S2-3600",
+                 .cold_ids = { NULL, NULL }, /* this is a warm only device */
+                 .warm_ids = { &pctv452e_usb_table[1], NULL }
+               },
+               { .name = "Technotrend TT Connect S2-3650-CI",
+                 .cold_ids = { NULL, NULL },
+                 .warm_ids = { &pctv452e_usb_table[2], NULL }
+               },
+               { 0 },
+       }
+};
+
+static void pctv452e_usb_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+
+       tt3650_ci_uninit(d);
+       dvb_usb_device_exit(intf);
+}
+
+static int pctv452e_usb_probe(struct usb_interface *intf,
+                               const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &pctv452e_properties,
+                                       THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &tt_connect_s2_3600_properties,
+                                       THIS_MODULE, NULL, adapter_nr))
+               return 0;
+
+       return -ENODEV;
+}
+
+static struct usb_driver pctv452e_usb_driver = {
+       .name       = "pctv452e",
+       .probe      = pctv452e_usb_probe,
+       .disconnect = pctv452e_usb_disconnect,
+       .id_table   = pctv452e_usb_table,
+};
+
+module_usb_driver(pctv452e_usb_driver);
+
+MODULE_AUTHOR("Dominik Kuhlen <dkuhlen@gmx.net>");
+MODULE_AUTHOR("Andre Weidemann <Andre.Weidemann@web.de>");
+MODULE_AUTHOR("Michael H. Schimek <mschimek@gmx.at>");
+MODULE_DESCRIPTION("Pinnacle PCTV HDTV USB DVB / TT connect S2-3600 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
new file mode 100644 (file)
index 0000000..acefaa8
--- /dev/null
@@ -0,0 +1,789 @@
+/*
+ * Linux driver for Technisat DVB-S/S2 USB 2.0 device
+ *
+ * Copyright (C) 2010 Patrick Boettcher,
+ *                    Kernel Labs Inc. PO Box 745, St James, NY 11780
+ *
+ * Development was sponsored by Technisat Digital UK Limited, whose
+ * registered office is Witan Gate House 500 - 600 Witan Gate West,
+ * Milton Keynes, MK9 1SH
+ *
+ * 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.
+ *
+ *
+ * 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.
+ *
+ * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
+ * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  NEITHER THE COPYRIGHT HOLDER
+ * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
+ * GNU General Public License for more details.
+ */
+
+#define DVB_USB_LOG_PREFIX "technisat-usb2"
+#include "dvb-usb.h"
+
+#include "stv6110x.h"
+#include "stv090x.h"
+
+/* module parameters */
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,
+               "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
+               DVB_USB_DEBUG_STATUS);
+
+/* disables all LED control command and
+ * also does not start the signal polling thread */
+static int disable_led_control;
+module_param(disable_led_control, int, 0444);
+MODULE_PARM_DESC(disable_led_control,
+               "disable LED control of the device "
+               "(default: 0 - LED control is active).");
+
+/* device private data */
+struct technisat_usb2_state {
+       struct dvb_usb_device *dev;
+       struct delayed_work green_led_work;
+       u8 power_state;
+
+       u16 last_scan_code;
+};
+
+/* debug print helpers */
+#define deb_info(args...)    dprintk(debug, 0x01, args)
+#define deb_eeprom(args...)  dprintk(debug, 0x02, args)
+#define deb_i2c(args...)     dprintk(debug, 0x04, args)
+#define deb_rc(args...)      dprintk(debug, 0x08, args)
+
+/* vendor requests */
+#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
+#define SET_FRONT_END_RESET_VENDOR_REQUEST         0xB4
+#define GET_VERSION_INFO_VENDOR_REQUEST            0xB5
+#define SET_GREEN_LED_VENDOR_REQUEST               0xB6
+#define SET_RED_LED_VENDOR_REQUEST                 0xB7
+#define GET_IR_DATA_VENDOR_REQUEST                 0xB8
+#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST       0xB9
+#define SET_USB_REENUMERATION                      0xBA
+
+/* i2c-access methods */
+#define I2C_SPEED_100KHZ_BIT 0x40
+
+#define I2C_STATUS_NAK 7
+#define I2C_STATUS_OK 8
+
+static int technisat_usb2_i2c_access(struct usb_device *udev,
+               u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+       u8 b[64];
+       int ret, actual_length;
+
+       deb_i2c("i2c-access: %02x, tx: ", device_addr);
+       debug_dump(tx, txlen, deb_i2c);
+       deb_i2c(" ");
+
+       if (txlen > 62) {
+               err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
+                               device_addr);
+               txlen = 62;
+       }
+       if (rxlen > 62) {
+               err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
+                               device_addr);
+               txlen = 62;
+       }
+
+       b[0] = I2C_SPEED_100KHZ_BIT;
+       b[1] = device_addr << 1;
+
+       if (rx != NULL) {
+               b[0] |= rxlen;
+               b[1] |= 1;
+       }
+
+       memcpy(&b[2], tx, txlen);
+       ret = usb_bulk_msg(udev,
+                       usb_sndbulkpipe(udev, 0x01),
+                       b, 2 + txlen,
+                       NULL, 1000);
+
+       if (ret < 0) {
+               err("i2c-error: out failed %02x = %d", device_addr, ret);
+               return -ENODEV;
+       }
+
+       ret = usb_bulk_msg(udev,
+                       usb_rcvbulkpipe(udev, 0x01),
+                       b, 64, &actual_length, 1000);
+       if (ret < 0) {
+               err("i2c-error: in failed %02x = %d", device_addr, ret);
+               return -ENODEV;
+       }
+
+       if (b[0] != I2C_STATUS_OK) {
+               err("i2c-error: %02x = %d", device_addr, b[0]);
+               /* handle tuner-i2c-nak */
+               if (!(b[0] == I2C_STATUS_NAK &&
+                               device_addr == 0x60
+                               /* && device_is_technisat_usb2 */))
+                       return -ENODEV;
+       }
+
+       deb_i2c("status: %d, ", b[0]);
+
+       if (rx != NULL) {
+               memcpy(rx, &b[2], rxlen);
+
+               deb_i2c("rx (%d): ", rxlen);
+               debug_dump(rx, rxlen, deb_i2c);
+       }
+
+       deb_i2c("\n");
+
+       return 0;
+}
+
+static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+                               int num)
+{
+       int ret = 0, i;
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+       /* Ensure nobody else hits the i2c bus while we're sending our
+          sequence of messages, (such as the remote control thread) */
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
+                       ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
+                                               msg[i].buf, msg[i].len,
+                                               msg[i+1].buf, msg[i+1].len);
+                       if (ret != 0)
+                               break;
+                       i++;
+               } else {
+                       ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
+                                               msg[i].buf, msg[i].len,
+                                               NULL, 0);
+                       if (ret != 0)
+                               break;
+               }
+       }
+
+       if (ret == 0)
+               ret = i;
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm technisat_usb2_i2c_algo = {
+       .master_xfer   = technisat_usb2_i2c_xfer,
+       .functionality = technisat_usb2_i2c_func,
+};
+
+#if 0
+static void technisat_usb2_frontend_reset(struct usb_device *udev)
+{
+       usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                       SET_FRONT_END_RESET_VENDOR_REQUEST,
+                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                       10, 0,
+                       NULL, 0, 500);
+}
+#endif
+
+/* LED control */
+enum technisat_usb2_led_state {
+       LED_OFF,
+       LED_BLINK,
+       LED_ON,
+       LED_UNDEFINED
+};
+
+static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
+{
+       int ret;
+
+       u8 led[8] = {
+               red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+               0
+       };
+
+       if (disable_led_control && state != LED_OFF)
+               return 0;
+
+       switch (state) {
+       case LED_ON:
+               led[1] = 0x82;
+               break;
+       case LED_BLINK:
+               led[1] = 0x82;
+               if (red) {
+                       led[2] = 0x02;
+                       led[3] = 10;
+                       led[4] = 10;
+               } else {
+                       led[2] = 0xff;
+                       led[3] = 50;
+                       led[4] = 50;
+               }
+               led[5] = 1;
+               break;
+
+       default:
+       case LED_OFF:
+               led[1] = 0x80;
+               break;
+       }
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+               red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_OUT,
+               0, 0,
+               led, sizeof(led), 500);
+
+       mutex_unlock(&d->i2c_mutex);
+       return ret;
+}
+
+static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
+{
+       int ret;
+       u8 b = 0;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+               SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_OUT,
+               (red << 8) | green, 0,
+               &b, 1, 500);
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static void technisat_usb2_green_led_control(struct work_struct *work)
+{
+       struct technisat_usb2_state *state =
+               container_of(work, struct technisat_usb2_state, green_led_work.work);
+       struct dvb_frontend *fe = state->dev->adapter[0].fe_adap[0].fe;
+
+       if (state->power_state == 0)
+               goto schedule;
+
+       if (fe != NULL) {
+               enum fe_status status;
+
+               if (fe->ops.read_status(fe, &status) != 0)
+                       goto schedule;
+
+               if (status & FE_HAS_LOCK) {
+                       u32 ber;
+
+                       if (fe->ops.read_ber(fe, &ber) != 0)
+                               goto schedule;
+
+                       if (ber > 1000)
+                               technisat_usb2_set_led(state->dev, 0, LED_BLINK);
+                       else
+                               technisat_usb2_set_led(state->dev, 0, LED_ON);
+               } else
+                       technisat_usb2_set_led(state->dev, 0, LED_OFF);
+       }
+
+schedule:
+       schedule_delayed_work(&state->green_led_work,
+                       msecs_to_jiffies(500));
+}
+
+/* method to find out whether the firmware has to be downloaded or not */
+static int technisat_usb2_identify_state(struct usb_device *udev,
+               struct dvb_usb_device_properties *props,
+               struct dvb_usb_device_description **desc, int *cold)
+{
+       int ret;
+       u8 version[3];
+
+       /* first select the interface */
+       if (usb_set_interface(udev, 0, 1) != 0)
+               err("could not set alternate setting to 0");
+       else
+               info("set alternate setting");
+
+       *cold = 0; /* by default do not download a firmware - just in case something is wrong */
+
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+               GET_VERSION_INFO_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_IN,
+               0, 0,
+               version, sizeof(version), 500);
+
+       if (ret < 0)
+               *cold = 1;
+       else {
+               info("firmware version: %d.%d", version[1], version[2]);
+               *cold = 0;
+       }
+
+       return 0;
+}
+
+/* power control */
+static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
+{
+       struct technisat_usb2_state *state = d->priv;
+
+       state->power_state = level;
+
+       if (disable_led_control)
+               return 0;
+
+       /* green led is turned off in any case - will be turned on when tuning */
+       technisat_usb2_set_led(d, 0, LED_OFF);
+       /* red led is turned on all the time */
+       technisat_usb2_set_led(d, 1, LED_ON);
+       return 0;
+}
+
+/* mac address reading - from the eeprom */
+#if 0
+static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
+{
+       u8 reg;
+       u8 b[16];
+       int i, j;
+
+       /* full EEPROM dump */
+       for (j = 0; j < 256 * 4; j += 16) {
+               reg = j;
+               if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
+                       break;
+
+               deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
+               for (i = 0; i < 16; i++)
+                       deb_eeprom("%02x ", b[i]);
+               deb_eeprom("\n");
+       }
+}
+#endif
+
+static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
+{
+       u8 lrc = 0;
+       while (--length)
+               lrc ^= *b++;
+       return lrc;
+}
+
+static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
+       u16 offset, u8 *b, u16 length, u8 tries)
+{
+       u8 bo = offset & 0xff;
+       struct i2c_msg msg[] = {
+               {
+                       .addr = 0x50 | ((offset >> 8) & 0x3),
+                       .buf = &bo,
+                       .len = 1
+               }, {
+                       .addr = 0x50 | ((offset >> 8) & 0x3),
+                       .flags  = I2C_M_RD,
+                       .buf = b,
+                       .len = length
+               }
+       };
+
+       while (tries--) {
+               int status;
+
+               if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
+                       break;
+
+               status =
+                       technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
+
+               if (status)
+                       return 0;
+       }
+
+       return -EREMOTEIO;
+}
+
+#define EEPROM_MAC_START 0x3f8
+#define EEPROM_MAC_TOTAL 8
+static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
+               u8 mac[])
+{
+       u8 buf[EEPROM_MAC_TOTAL];
+
+       if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
+                               buf, EEPROM_MAC_TOTAL, 4) != 0)
+               return -ENODEV;
+
+       memcpy(mac, buf, 6);
+       return 0;
+}
+
+/* frontend attach */
+static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
+               fe_sec_voltage_t voltage)
+{
+       int i;
+       u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
+
+       gpio[2] = 1; /* high - voltage ? */
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               gpio[0] = 1;
+               break;
+       case SEC_VOLTAGE_18:
+               gpio[0] = 1;
+               gpio[1] = 1;
+               break;
+       default:
+       case SEC_VOLTAGE_OFF:
+               break;
+       }
+
+       for (i = 0; i < 3; i++)
+               if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
+                       return -EREMOTEIO;
+       return 0;
+}
+
+static struct stv090x_config technisat_usb2_stv090x_config = {
+       .device         = STV0903,
+       .demod_mode     = STV090x_SINGLE,
+       .clk_mode       = STV090x_CLK_EXT,
+
+       .xtal           = 8000000,
+       .address        = 0x68,
+
+       .ts1_mode       = STV090x_TSMODE_DVBCI,
+       .ts1_clk        = 13400000,
+       .ts1_tei        = 1,
+
+       .repeater_level = STV090x_RPTLEVEL_64,
+
+       .tuner_bbgain   = 6,
+};
+
+static struct stv6110x_config technisat_usb2_stv6110x_config = {
+       .addr           = 0x60,
+       .refclk         = 16000000,
+       .clk_div        = 2,
+};
+
+static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
+{
+       struct usb_device *udev = a->dev->udev;
+       int ret;
+
+       a->fe_adap[0].fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
+                       &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
+
+       if (a->fe_adap[0].fe) {
+               struct stv6110x_devctl *ctl;
+
+               ctl = dvb_attach(stv6110x_attach,
+                               a->fe_adap[0].fe,
+                               &technisat_usb2_stv6110x_config,
+                               &a->dev->i2c_adap);
+
+               if (ctl) {
+                       technisat_usb2_stv090x_config.tuner_init          = ctl->tuner_init;
+                       technisat_usb2_stv090x_config.tuner_sleep         = ctl->tuner_sleep;
+                       technisat_usb2_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode;
+                       technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+                       technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+                       technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+                       technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+                       technisat_usb2_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain;
+                       technisat_usb2_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain;
+                       technisat_usb2_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk;
+                       technisat_usb2_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 (a->fe_adap[0].fe->ops.init)
+                               a->fe_adap[0].fe->ops.init(a->fe_adap[0].fe);
+
+                       if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
+                               return -EAGAIN;
+
+                       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                       SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
+                                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                                       0, 0,
+                                       NULL, 0, 500);
+                       mutex_unlock(&a->dev->i2c_mutex);
+
+                       if (ret != 0)
+                               err("could not set IF_CLK to external");
+
+                       a->fe_adap[0].fe->ops.set_voltage = technisat_usb2_set_voltage;
+
+                       /* if everything was successful assign a nice name to the frontend */
+                       strlcpy(a->fe_adap[0].fe->ops.info.name, a->dev->desc->name,
+                                       sizeof(a->fe_adap[0].fe->ops.info.name));
+               } else {
+                       dvb_frontend_detach(a->fe_adap[0].fe);
+                       a->fe_adap[0].fe = NULL;
+               }
+       }
+
+       technisat_usb2_set_led_timer(a->dev, 1, 1);
+
+       return a->fe_adap[0].fe == NULL ? -ENODEV : 0;
+}
+
+/* Remote control */
+
+/* the device is giving providing raw IR-signals to the host mapping
+ * it only to one remote control is just the default implementation
+ */
+#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
+#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
+
+#define FIRMWARE_CLOCK_TICK 83333
+#define FIRMWARE_CLOCK_DIVISOR 256
+
+#define IR_PERCENT_TOLERANCE 15
+
+#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+static int technisat_usb2_get_ir(struct dvb_usb_device *d)
+{
+       u8 buf[62], *b;
+       int ret;
+       struct ir_raw_event ev;
+
+       buf[0] = GET_IR_DATA_VENDOR_REQUEST;
+       buf[1] = 0x08;
+       buf[2] = 0x8f;
+       buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
+       buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+       ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+                       GET_IR_DATA_VENDOR_REQUEST,
+                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                       0, 0,
+                       buf, 5, 500);
+       if (ret < 0)
+               goto unlock;
+
+       buf[1] = 0;
+       buf[2] = 0;
+       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+                       GET_IR_DATA_VENDOR_REQUEST,
+                       USB_TYPE_VENDOR | USB_DIR_IN,
+                       0x8080, 0,
+                       buf, sizeof(buf), 500);
+
+unlock:
+       mutex_unlock(&d->i2c_mutex);
+
+       if (ret < 0)
+               return ret;
+
+       if (ret == 1)
+               return 0; /* no key pressed */
+
+       /* decoding */
+       b = buf+1;
+
+#if 0
+       deb_rc("RC: %d ", ret);
+       debug_dump(b, ret, deb_rc);
+#endif
+
+       ev.pulse = 0;
+       while (1) {
+               ev.pulse = !ev.pulse;
+               ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
+               ir_raw_event_store(d->rc_dev, &ev);
+
+               b++;
+               if (*b == 0xff) {
+                       ev.pulse = 0;
+                       ev.duration = 888888*2;
+                       ir_raw_event_store(d->rc_dev, &ev);
+                       break;
+               }
+       }
+
+       ir_raw_event_handle(d->rc_dev);
+
+       return 1;
+}
+
+static int technisat_usb2_rc_query(struct dvb_usb_device *d)
+{
+       int ret = technisat_usb2_get_ir(d);
+
+       if (ret < 0)
+               return ret;
+
+       if (ret == 0)
+               return 0;
+
+       if (!disable_led_control)
+               technisat_usb2_set_led(d, 1, LED_BLINK);
+
+       return 0;
+}
+
+/* DVB-USB and USB stuff follows */
+static struct usb_device_id technisat_usb2_id_table[] = {
+       { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
+       { 0 }           /* Terminating entry */
+};
+
+/* device description */
+static struct dvb_usb_device_properties technisat_usb2_devices = {
+       .caps              = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = CYPRESS_FX2,
+
+       .identify_state    = technisat_usb2_identify_state,
+       .firmware          = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
+
+       .size_of_priv      = sizeof(struct technisat_usb2_state),
+
+       .i2c_algo          = &technisat_usb2_i2c_algo,
+
+       .power_ctrl        = technisat_usb2_power_ctrl,
+       .read_mac_address  = technisat_usb2_read_mac_address,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach  = technisat_usb2_frontend_attach,
+
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 8,
+                               .endpoint = 0x2,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 32,
+                                               .framesize = 2048,
+                                               .interval = 3,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv = 0,
+               },
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Technisat SkyStar USB HD (DVB-S/S2)",
+                       { &technisat_usb2_id_table[0], NULL },
+                       { NULL },
+               },
+       },
+
+       .rc.core = {
+               .rc_interval = 100,
+               .rc_codes    = RC_MAP_TECHNISAT_USB2,
+               .module_name = "technisat-usb2",
+               .rc_query    = technisat_usb2_rc_query,
+               .allowed_protos = RC_TYPE_ALL,
+               .driver_type    = RC_DRIVER_IR_RAW,
+       }
+};
+
+static int technisat_usb2_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct dvb_usb_device *dev;
+
+       if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
+                               &dev, adapter_nr) != 0)
+               return -ENODEV;
+
+       if (dev) {
+               struct technisat_usb2_state *state = dev->priv;
+               state->dev = dev;
+
+               if (!disable_led_control) {
+                       INIT_DELAYED_WORK(&state->green_led_work,
+                                       technisat_usb2_green_led_control);
+                       schedule_delayed_work(&state->green_led_work,
+                                       msecs_to_jiffies(500));
+               }
+       }
+
+       return 0;
+}
+
+static void technisat_usb2_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *dev = usb_get_intfdata(intf);
+
+       /* work and stuff was only created when the device is is hot-state */
+       if (dev != NULL) {
+               struct technisat_usb2_state *state = dev->priv;
+               if (state != NULL)
+                       cancel_delayed_work_sync(&state->green_led_work);
+       }
+
+       dvb_usb_device_exit(intf);
+}
+
+static struct usb_driver technisat_usb2_driver = {
+       .name       = "dvb_usb_technisat_usb2",
+       .probe      = technisat_usb2_probe,
+       .disconnect = technisat_usb2_disconnect,
+       .id_table   = technisat_usb2_id_table,
+};
+
+module_usb_driver(technisat_usb2_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
new file mode 100644 (file)
index 0000000..e53a106
--- /dev/null
@@ -0,0 +1,820 @@
+/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
+ * (e.g. Pinnacle 400e DVB-S USB2.0).
+ *
+ * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
+ *
+ * TDA8263 + TDA10086
+ *
+ * I2C addresses:
+ * 0x08 - LNBP21PD   - LNB power supply
+ * 0x0e - TDA10086   - Demodulator
+ * 0x50 - FX2 eeprom
+ * 0x60 - TDA8263    - Tuner
+ * 0x78 ???
+ *
+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
+ * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
+ * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#define DVB_USB_LOG_PREFIX "ttusb2"
+#include "dvb-usb.h"
+
+#include "ttusb2.h"
+
+#include "tda826x.h"
+#include "tda10086.h"
+#include "tda1002x.h"
+#include "tda10048.h"
+#include "tda827x.h"
+#include "lnbp21.h"
+/* CA */
+#include "dvb_ca_en50221.h"
+
+/* debug */
+static int dvb_usb_ttusb2_debug;
+#define deb_info(args...)   dprintk(dvb_usb_ttusb2_debug,0x01,args)
+module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
+static int dvb_usb_ttusb2_debug_ci;
+module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644);
+MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define ci_dbg(format, arg...)                \
+do {                                          \
+       if (dvb_usb_ttusb2_debug_ci)                                    \
+               printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
+                       ": %s " format "\n" , __func__, ## arg);       \
+} while (0)
+
+enum {
+       TT3650_CMD_CI_TEST = 0x40,
+       TT3650_CMD_CI_RD_CTRL,
+       TT3650_CMD_CI_WR_CTRL,
+       TT3650_CMD_CI_RD_ATTR,
+       TT3650_CMD_CI_WR_ATTR,
+       TT3650_CMD_CI_RESET,
+       TT3650_CMD_CI_SET_VIDEO_PORT
+};
+
+struct ttusb2_state {
+       struct dvb_ca_en50221 ca;
+       struct mutex ca_mutex;
+       u8 id;
+       u16 last_rc_key;
+};
+
+static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
+               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       struct ttusb2_state *st = d->priv;
+       u8 *s, *r = NULL;
+       int ret = 0;
+
+       s = kzalloc(wlen+4, GFP_KERNEL);
+       if (!s)
+               return -ENOMEM;
+
+       r = kzalloc(64, GFP_KERNEL);
+       if (!r) {
+               kfree(s);
+               return -ENOMEM;
+       }
+
+       s[0] = 0xaa;
+       s[1] = ++st->id;
+       s[2] = cmd;
+       s[3] = wlen;
+       memcpy(&s[4],wbuf,wlen);
+
+       ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
+
+       if (ret  != 0 ||
+               r[0] != 0x55 ||
+               r[1] != s[1] ||
+               r[2] != cmd ||
+               (rlen > 0 && r[3] != rlen)) {
+               warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
+               kfree(s);
+               kfree(r);
+               return -EIO;
+       }
+
+       if (rlen > 0)
+               memcpy(rbuf, &r[4], rlen);
+
+       kfree(s);
+       kfree(r);
+
+       return 0;
+}
+
+/* ci */
+static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
+{
+       int ret;
+       u8 rx[60];/* (64 -4) */
+       ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
+       if (!ret)
+               memcpy(data, rx, read_len);
+       return ret;
+}
+
+static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
+{
+       struct dvb_usb_device *d = ca->data;
+       struct ttusb2_state *state = d->priv;
+       int ret;
+
+       mutex_lock(&state->ca_mutex);
+       ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
+       mutex_unlock(&state->ca_mutex);
+
+       return ret;
+}
+
+static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
+{
+       u8 buf[3];
+       int ret = 0;
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = (address >> 8) & 0x0F;
+       buf[1] = address;
+
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
+
+       ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]);
+
+       if (ret < 0)
+               return ret;
+
+       return buf[2];
+}
+
+static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
+{
+       u8 buf[3];
+
+       ci_dbg("%d 0x%04x 0x%02x", slot, address, value);
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = (address >> 8) & 0x0F;
+       buf[1] = address;
+       buf[2] = value;
+
+       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
+}
+
+static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
+{
+       u8 buf[2];
+       int ret;
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = address & 3;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
+
+       ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]);
+
+       if (ret < 0)
+               return ret;
+
+       return buf[1];
+}
+
+static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
+{
+       u8 buf[2];
+
+       ci_dbg("%d 0x%02x 0x%02x", slot, address, value);
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = address;
+       buf[1] = value;
+
+       return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
+}
+
+static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable)
+{
+       u8 buf[1];
+       int ret;
+
+       ci_dbg("%d %d", slot, enable);
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = enable;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
+       if (ret < 0)
+               return ret;
+
+       if (enable != buf[0]) {
+               err("CI not %sabled.", enable ? "en" : "dis");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+       return tt3650_ci_set_video_port(ca, slot, 0);
+}
+
+static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+       return tt3650_ci_set_video_port(ca, slot, 1);
+}
+
+static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+       struct dvb_usb_device *d = ca->data;
+       struct ttusb2_state *state = d->priv;
+       u8 buf[1];
+       int ret;
+
+       ci_dbg("%d", slot);
+
+       if (slot)
+               return -EINVAL;
+
+       buf[0] = 0;
+
+       mutex_lock(&state->ca_mutex);
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
+       if (ret)
+               goto failed;
+
+       msleep(500);
+
+       buf[0] = 1;
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
+       if (ret)
+               goto failed;
+
+       msleep(500);
+
+       buf[0] = 0; /* FTA */
+
+       ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
+
+       msleep(1100);
+
+ failed:
+       mutex_unlock(&state->ca_mutex);
+
+       return ret;
+}
+
+static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       u8 buf[1];
+       int ret;
+
+       if (slot)
+               return -EINVAL;
+
+       ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
+       if (ret)
+               return ret;
+
+       if (1 == buf[0]) {
+               return DVB_CA_EN50221_POLL_CAM_PRESENT |
+                       DVB_CA_EN50221_POLL_CAM_READY;
+       }
+       return 0;
+}
+
+static void tt3650_ci_uninit(struct dvb_usb_device *d)
+{
+       struct ttusb2_state *state;
+
+       ci_dbg("");
+
+       if (NULL == d)
+               return;
+
+       state = d->priv;
+       if (NULL == state)
+               return;
+
+       if (NULL == state->ca.data)
+               return;
+
+       dvb_ca_en50221_release(&state->ca);
+
+       memset(&state->ca, 0, sizeof(state->ca));
+}
+
+static int tt3650_ci_init(struct dvb_usb_adapter *a)
+{
+       struct dvb_usb_device *d = a->dev;
+       struct ttusb2_state *state = d->priv;
+       int ret;
+
+       ci_dbg("");
+
+       mutex_init(&state->ca_mutex);
+
+       state->ca.owner = THIS_MODULE;
+       state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
+       state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
+       state->ca.read_cam_control = tt3650_ci_read_cam_control;
+       state->ca.write_cam_control = tt3650_ci_write_cam_control;
+       state->ca.slot_reset = tt3650_ci_slot_reset;
+       state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
+       state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
+       state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
+       state->ca.data = d;
+
+       ret = dvb_ca_en50221_init(&a->dvb_adap,
+                                 &state->ca,
+                                 /* flags */ 0,
+                                 /* n_slots */ 1);
+       if (ret) {
+               err("Cannot initialize CI: Error %d.", ret);
+               memset(&state->ca, 0, sizeof(state->ca));
+               return ret;
+       }
+
+       info("CI initialized.");
+
+       return 0;
+}
+
+static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       static u8 obuf[60], ibuf[60];
+       int i, write_read, read;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       if (num > 2)
+               warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+       for (i = 0; i < num; i++) {
+               write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+               read = msg[i].flags & I2C_M_RD;
+
+               obuf[0] = (msg[i].addr << 1) | (write_read | read);
+               if (read)
+                       obuf[1] = 0;
+               else
+                       obuf[1] = msg[i].len;
+
+               /* read request */
+               if (write_read)
+                       obuf[2] = msg[i+1].len;
+               else if (read)
+                       obuf[2] = msg[i].len;
+               else
+                       obuf[2] = 0;
+
+               memcpy(&obuf[3], msg[i].buf, msg[i].len);
+
+               if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
+                       err("i2c transfer failed.");
+                       break;
+               }
+
+               if (write_read) {
+                       memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len);
+                       i++;
+               } else if (read)
+                       memcpy(msg[i].buf, &ibuf[3], msg[i].len);
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ttusb2_i2c_algo = {
+       .master_xfer   = ttusb2_i2c_xfer,
+       .functionality = ttusb2_i2c_func,
+};
+
+/* command to poll IR receiver (copied from pctv452e.c) */
+#define CMD_GET_IR_CODE     0x1b
+
+/* IR */
+static int tt3650_rc_query(struct dvb_usb_device *d)
+{
+       int ret;
+       u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
+       struct ttusb2_state *st = d->priv;
+       ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
+       if (ret != 0)
+               return ret;
+
+       if (rx[8] & 0x01) {
+               /* got a "press" event */
+               st->last_rc_key = (rx[3] << 8) | rx[2];
+               deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
+               rc_keydown(d->rc_dev, st->last_rc_key, 0);
+       } else if (st->last_rc_key) {
+               rc_keyup(d->rc_dev);
+               st->last_rc_key = 0;
+       }
+
+       return 0;
+}
+
+
+/* Callbacks for DVB USB */
+static int ttusb2_identify_state (struct usb_device *udev, struct
+               dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
+               int *cold)
+{
+       *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
+       return 0;
+}
+
+static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b = onoff;
+       ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
+       return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
+}
+
+
+static struct tda10086_config tda10086_config = {
+       .demod_address = 0x0e,
+       .invert = 0,
+       .diseqc_tone = 1,
+       .xtal_freq = TDA10086_XTAL_16M,
+};
+
+static struct tda10023_config tda10023_config = {
+       .demod_address = 0x0c,
+       .invert = 0,
+       .xtal = 16000000,
+       .pll_m = 11,
+       .pll_p = 3,
+       .pll_n = 1,
+       .deltaf = 0xa511,
+};
+
+static struct tda10048_config tda10048_config = {
+       .demod_address    = 0x10 >> 1,
+       .output_mode      = TDA10048_PARALLEL_OUTPUT,
+       .inversion        = TDA10048_INVERSION_ON,
+       .dtv6_if_freq_khz = TDA10048_IF_4000,
+       .dtv7_if_freq_khz = TDA10048_IF_4500,
+       .dtv8_if_freq_khz = TDA10048_IF_5000,
+       .clk_freq_khz     = TDA10048_CLK_16000,
+       .no_firmware      = 1,
+       .set_pll          = true ,
+       .pll_m            = 5,
+       .pll_n            = 3,
+       .pll_p            = 0,
+};
+
+static struct tda827x_config tda827x_config = {
+       .config = 0,
+};
+
+static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev,0,3) < 0)
+               err("set interface to alts=3 failed");
+
+       if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
+               deb_info("TDA10086 attach failed\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+       return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
+}
+
+static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
+{
+       if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
+               err("set interface to alts=3 failed");
+
+       if (adap->fe_adap[0].fe == NULL) {
+               /* FE 0 DVB-C */
+               adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
+                       &tda10023_config, &adap->dev->i2c_adap, 0x48);
+
+               if (adap->fe_adap[0].fe == NULL) {
+                       deb_info("TDA10023 attach failed\n");
+                       return -ENODEV;
+               }
+               tt3650_ci_init(adap);
+       } else {
+               adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
+                       &tda10048_config, &adap->dev->i2c_adap);
+
+               if (adap->fe_adap[1].fe == NULL) {
+                       deb_info("TDA10048 attach failed\n");
+                       return -ENODEV;
+               }
+
+               /* tuner is behind TDA10023 I2C-gate */
+               adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
+
+       }
+
+       return 0;
+}
+
+static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_frontend *fe;
+
+       /* MFE: select correct FE to attach tuner since that's called twice */
+       if (adap->fe_adap[1].fe == NULL)
+               fe = adap->fe_adap[0].fe;
+       else
+               fe = adap->fe_adap[1].fe;
+
+       /* attach tuner */
+       if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
+               printk(KERN_ERR "%s: No tda827x found!\n", __func__);
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
+{
+       if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
+               deb_info("TDA8263 attach failed\n");
+               return -ENODEV;
+       }
+
+       if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
+               deb_info("LNBP21 attach failed\n");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ttusb2_properties;
+static struct dvb_usb_device_properties ttusb2_properties_s2400;
+static struct dvb_usb_device_properties ttusb2_properties_ct3650;
+
+static void ttusb2_usb_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+
+       tt3650_ci_uninit(d);
+       dvb_usb_device_exit(intf);
+}
+
+static int ttusb2_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
+                                    THIS_MODULE, NULL, adapter_nr) ||
+           0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return 0;
+       return -ENODEV;
+}
+
+static struct usb_device_id ttusb2_table [] = {
+       { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
+       { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
+       { USB_DEVICE(USB_VID_TECHNOTREND,
+               USB_PID_TECHNOTREND_CONNECT_S2400) },
+       { USB_DEVICE(USB_VID_TECHNOTREND,
+               USB_PID_TECHNOTREND_CONNECT_CT3650) },
+       {}              /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, ttusb2_table);
+
+static struct dvb_usb_device_properties ttusb2_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-pctv-400e-01.fw",
+
+       .size_of_priv = sizeof(struct ttusb2_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = NULL, // ttusb2_streaming_ctrl,
+
+                       .frontend_attach  = ttusb2_frontend_tda10086_attach,
+                       .tuner_attach     = ttusb2_tuner_tda826x_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize = 940,
+                                               .interval = 1,
+                                       }
+                               }
+                       }
+               }},
+               }
+       },
+
+       .power_ctrl       = ttusb2_power_ctrl,
+       .identify_state   = ttusb2_identify_state,
+
+       .i2c_algo         = &ttusb2_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 2,
+       .devices = {
+               {   "Pinnacle 400e DVB-S USB2.0",
+                       { &ttusb2_table[0], NULL },
+                       { NULL },
+               },
+               {   "Pinnacle 450e DVB-S USB2.0",
+                       { &ttusb2_table[1], NULL },
+                       { NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-tt-s2400-01.fw",
+
+       .size_of_priv = sizeof(struct ttusb2_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = NULL,
+
+                       .frontend_attach  = ttusb2_frontend_tda10086_attach,
+                       .tuner_attach     = ttusb2_tuner_tda826x_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize = 940,
+                                               .interval = 1,
+                                       }
+                               }
+                       }
+               }},
+               }
+       },
+
+       .power_ctrl       = ttusb2_power_ctrl,
+       .identify_state   = ttusb2_identify_state,
+
+       .i2c_algo         = &ttusb2_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Technotrend TT-connect S-2400",
+                       { &ttusb2_table[2], NULL },
+                       { NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+
+       .size_of_priv = sizeof(struct ttusb2_state),
+
+       .rc.core = {
+               .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
+               .rc_codes         = RC_MAP_TT_1500,
+               .rc_query         = tt3650_rc_query,
+               .allowed_protos   = RC_TYPE_UNKNOWN,
+       },
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 2,
+               .fe = {{
+                       .streaming_ctrl   = NULL,
+
+                       .frontend_attach  = ttusb2_frontend_tda10023_attach,
+                       .tuner_attach = ttusb2_tuner_tda827x_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize = 940,
+                                               .interval = 1,
+                                       }
+                               }
+                       }
+               }, {
+                       .streaming_ctrl   = NULL,
+
+                       .frontend_attach  = ttusb2_frontend_tda10023_attach,
+                       .tuner_attach = ttusb2_tuner_tda827x_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_ISOC,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .isoc = {
+                                               .framesperurb = 4,
+                                               .framesize = 940,
+                                               .interval = 1,
+                                       }
+                               }
+                       }
+               }},
+               },
+       },
+
+       .power_ctrl       = ttusb2_power_ctrl,
+       .identify_state   = ttusb2_identify_state,
+
+       .i2c_algo         = &ttusb2_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "Technotrend TT-connect CT-3650",
+                       .warm_ids = { &ttusb2_table[3], NULL },
+               },
+       }
+};
+
+static struct usb_driver ttusb2_driver = {
+       .name           = "dvb_usb_ttusb2",
+       .probe          = ttusb2_probe,
+       .disconnect     = ttusb2_usb_disconnect,
+       .id_table       = ttusb2_table,
+};
+
+module_usb_driver(ttusb2_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.h b/drivers/media/usb/dvb-usb/ttusb2.h
new file mode 100644 (file)
index 0000000..52a63af
--- /dev/null
@@ -0,0 +1,70 @@
+/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
+ * (e.g. Pinnacle 400e DVB-S USB2.0).
+ *
+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
+ * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
+ * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_TTUSB2_H_
+#define _DVB_USB_TTUSB2_H_
+
+/* TTUSB protocol
+ *
+ * always to messages (out/in)
+ * out message:
+ * 0xaa <id> <cmdbyte> <datalen> <data...>
+ *
+ * in message (complete block is always 0x40 bytes long)
+ * 0x55 <id> <cmdbyte> <datalen> <data...>
+ *
+ * id is incremented for each transaction
+ */
+
+#define CMD_DSP_DOWNLOAD    0x13
+/* out data: <byte>[28]
+ * last block must be empty */
+
+#define CMD_DSP_BOOT        0x14
+/* out data: nothing */
+
+#define CMD_POWER           0x15
+/* out data: <on=1/off=0> */
+
+#define CMD_LNB             0x16
+/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */
+
+#define CMD_GET_VERSION     0x17
+/* in  data: <version_byte>[5] */
+
+#define CMD_DISEQC          0x18
+/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */
+
+#define CMD_PID_ENABLE      0x22
+/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */
+
+#define CMD_PID_DISABLE     0x23
+/* out data: <index> */
+
+#define CMD_FILTER_ENABLE   0x24
+/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */
+
+#define CMD_FILTER_DISABLE  0x25
+/* out data: <index> */
+
+#define CMD_GET_DSP_VERSION 0x26
+/* in  data: <version_byte>[28] */
+
+#define CMD_I2C_XFER        0x31
+/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen]
+ * in  data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */
+
+#define CMD_I2C_BITRATE     0x32
+/* out data: <default=0> */
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
new file mode 100644 (file)
index 0000000..9b04229
--- /dev/null
@@ -0,0 +1,151 @@
+/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+#include "mt352.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int umt_mt352_demod_init(struct dvb_frontend *fe)
+{
+       static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
+       static u8 mt352_reset[] = { 0x50, 0x80 };
+       static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
+       static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
+       static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
+
+       static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
+       static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
+       static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
+       static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
+       static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
+
+       static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
+       static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
+
+       mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+       udelay(2000);
+       mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+       mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
+
+       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_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
+       mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
+       mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
+       mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
+       mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
+
+       mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+       mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+
+       return 0;
+}
+
+static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct mt352_config umt_config;
+
+       memset(&umt_config,0,sizeof(struct mt352_config));
+       umt_config.demod_init = umt_mt352_demod_init;
+       umt_config.demod_address = 0xf;
+
+       adap->fe_adap[0].fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
+
+       return 0;
+}
+
+static int umt_tuner_attach (struct dvb_usb_adapter *adap)
+{
+       dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_TUA6034);
+       return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_device_properties umt_properties;
+
+static int umt_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       if (0 == dvb_usb_device_init(intf, &umt_properties,
+                                    THIS_MODULE, NULL, adapter_nr))
+               return 0;
+       return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id umt_table [] = {
+/* 00 */       { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
+/* 01 */       { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
+                       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, umt_table);
+
+static struct dvb_usb_device_properties umt_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-umt-010-02.fw",
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .streaming_ctrl   = dibusb2_0_streaming_ctrl,
+                       .frontend_attach  = umt_mt352_frontend_attach,
+                       .tuner_attach     = umt_tuner_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = MAX_NO_URBS_FOR_DATA_STREAM,
+                               .endpoint = 0x06,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 512,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               {       "Hanftek UMT-010 DVB-T USB2.0",
+                       { &umt_table[0], NULL },
+                       { &umt_table[1], NULL },
+               },
+       }
+};
+
+static struct usb_driver umt_driver = {
+       .name           = "dvb_usb_umt_010",
+       .probe          = umt_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table       = umt_table,
+};
+
+module_usb_driver(umt_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/usb-urb.c b/drivers/media/usb/dvb-usb/usb-urb.c
new file mode 100644 (file)
index 0000000..d62ee0f
--- /dev/null
@@ -0,0 +1,254 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb-usb-common.h"
+
+/* URB stuff for streaming */
+static void usb_urb_complete(struct urb *urb)
+{
+       struct usb_data_stream *stream = urb->context;
+       int ptype = usb_pipetype(urb->pipe);
+       int i;
+       u8 *b;
+
+       deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+               ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+               urb->status,urb->actual_length,urb->transfer_buffer_length,
+               urb->number_of_packets,urb->error_count);
+
+       switch (urb->status) {
+               case 0:         /* success */
+               case -ETIMEDOUT:    /* NAK */
+                       break;
+               case -ECONNRESET:   /* kill */
+               case -ENOENT:
+               case -ESHUTDOWN:
+                       return;
+               default:        /* error */
+                       deb_ts("urb completition error %d.\n", urb->status);
+                       break;
+       }
+
+       b = (u8 *) urb->transfer_buffer;
+       switch (ptype) {
+               case PIPE_ISOCHRONOUS:
+                       for (i = 0; i < urb->number_of_packets; i++) {
+
+                               if (urb->iso_frame_desc[i].status != 0)
+                                       deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+                               else if (urb->iso_frame_desc[i].actual_length > 0)
+                                       stream->complete(stream, b + 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;
+                       }
+                       debug_dump(b,20,deb_uxfer);
+                       break;
+               case PIPE_BULK:
+                       if (urb->actual_length > 0)
+                               stream->complete(stream, b, urb->actual_length);
+                       break;
+               default:
+                       err("unknown endpoint type in completition handler.");
+                       return;
+       }
+       usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+int usb_urb_kill(struct usb_data_stream *stream)
+{
+       int i;
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               deb_ts("killing URB no. %d.\n",i);
+
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+       return 0;
+}
+
+int usb_urb_submit(struct usb_data_stream *stream)
+{
+       int i,ret;
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               deb_ts("submitting URB no. %d\n",i);
+               if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
+                       err("could not submit URB no. %d - get them all back",i);
+                       usb_urb_kill(stream);
+                       return ret;
+               }
+               stream->urbs_submitted++;
+       }
+       return 0;
+}
+
+static int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+       if (stream->state & USB_STATE_URB_BUF) {
+               while (stream->buf_num) {
+                       stream->buf_num--;
+                       deb_mem("freeing buffer %d\n",stream->buf_num);
+                       usb_free_coherent(stream->udev, stream->buf_size,
+                                         stream->buf_list[stream->buf_num],
+                                         stream->dma_addr[stream->buf_num]);
+               }
+       }
+
+       stream->state &= ~USB_STATE_URB_BUF;
+
+       return 0;
+}
+
+static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
+{
+       stream->buf_num = 0;
+       stream->buf_size = size;
+
+       deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
+
+       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+               deb_mem("allocating buffer %d\n",stream->buf_num);
+               if (( stream->buf_list[stream->buf_num] =
+                                       usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
+                                       &stream->dma_addr[stream->buf_num]) ) == NULL) {
+                       deb_mem("not enough memory for urb-buffer allocation.\n");
+                       usb_free_stream_buffers(stream);
+                       return -ENOMEM;
+               }
+               deb_mem("buffer %d: %p (dma: %Lu)\n",
+                       stream->buf_num,
+stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]);
+               memset(stream->buf_list[stream->buf_num],0,size);
+               stream->state |= USB_STATE_URB_BUF;
+       }
+       deb_mem("allocation successful\n");
+
+       return 0;
+}
+
+static int usb_bulk_urb_init(struct usb_data_stream *stream)
+{
+       int i, j;
+
+       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+                                       stream->props.u.bulk.buffersize)) < 0)
+               return i;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       deb_mem("not enough memory for urb_alloc_urb!.\n");
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+               usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
+                               usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
+                               stream->buf_list[i],
+                               stream->props.u.bulk.buffersize,
+                               usb_urb_complete, stream);
+
+               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+static int usb_isoc_urb_init(struct usb_data_stream *stream)
+{
+       int i,j;
+
+       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+                                       stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
+               return i;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               struct urb *urb;
+               int frame_offset = 0;
+
+               stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       deb_mem("not enough memory for urb_alloc_urb!\n");
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+
+               urb = stream->urb_list[i];
+
+               urb->dev = stream->udev;
+               urb->context = stream;
+               urb->complete = usb_urb_complete;
+               urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
+               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+               urb->interval = stream->props.u.isoc.interval;
+               urb->number_of_packets = stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer_length = stream->buf_size;
+               urb->transfer_buffer = stream->buf_list[i];
+               urb->transfer_dma = stream->dma_addr[i];
+
+               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
+                       frame_offset += stream->props.u.isoc.framesize;
+               }
+
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
+{
+       if (stream == NULL || props == NULL)
+               return -EINVAL;
+
+       memcpy(&stream->props, props, sizeof(*props));
+
+       usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
+
+       if (stream->complete == NULL) {
+               err("there is no data callback - this doesn't make sense.");
+               return -EINVAL;
+       }
+
+       switch (stream->props.type) {
+               case USB_BULK:
+                       return usb_bulk_urb_init(stream);
+               case USB_ISOC:
+                       return usb_isoc_urb_init(stream);
+               default:
+                       err("unknown URB-type for data transfer.");
+                       return -EINVAL;
+       }
+}
+
+int usb_urb_exit(struct usb_data_stream *stream)
+{
+       int i;
+
+       usb_urb_kill(stream);
+
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               if (stream->urb_list[i] != NULL) {
+                       deb_mem("freeing URB no. %d.\n",i);
+                       /* free the URBs */
+                       usb_free_urb(stream->urb_list[i]);
+               }
+       }
+       stream->urbs_initialized = 0;
+
+       usb_free_stream_buffers(stream);
+       return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
new file mode 100644 (file)
index 0000000..5eab468
--- /dev/null
@@ -0,0 +1,379 @@
+/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
+ * DVB-S receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ *                    Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This file can be removed soon, after the DST-driver is rewritten to provice
+ * the frontend-controlling separately.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp702x.h"
+
+struct vp702x_fe_state {
+       struct dvb_frontend fe;
+       struct dvb_usb_device *d;
+
+       struct dvb_frontend_ops ops;
+
+       fe_sec_voltage_t voltage;
+       fe_sec_tone_mode_t tone_mode;
+
+       u8 lnb_buf[8];
+
+       u8 lock;
+       u8 sig;
+       u8 snr;
+
+       unsigned long next_status_check;
+       unsigned long status_check_interval;
+};
+
+static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
+{
+       struct vp702x_device_state *dst = st->d->priv;
+       u8 *buf;
+
+       if (time_after(jiffies, st->next_status_check)) {
+               mutex_lock(&dst->buf_mutex);
+               buf = dst->buf;
+
+               vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
+               st->lock = buf[4];
+
+               vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
+               st->snr = buf[0];
+
+               vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
+               st->sig = buf[0];
+
+               mutex_unlock(&dst->buf_mutex);
+               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+       }
+       return 0;
+}
+
+static u8 vp702x_chksum(u8 *buf,int f, int count)
+{
+       u8 s = 0;
+       int i;
+       for (i = f; i < f+count; i++)
+               s += buf[i];
+       return ~s+1;
+}
+
+static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       vp702x_fe_refresh_state(st);
+       deb_fe("%s\n",__func__);
+
+       if (st->lock == 0)
+               *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+       else
+               *status = 0;
+
+       if (*status & FE_HAS_LOCK)
+               st->status_check_interval = 1000;
+       else
+               st->status_check_interval = 250;
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       vp702x_fe_refresh_state(st);
+       *ber = 0;
+       return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       vp702x_fe_refresh_state(st);
+       *unc = 0;
+       return 0;
+}
+
+static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       vp702x_fe_refresh_state(st);
+
+       *strength = (st->sig << 8) | st->sig;
+       return 0;
+}
+
+static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       u8 _snr;
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       vp702x_fe_refresh_state(st);
+
+       _snr = (st->snr & 0x1f) * 0xff / 0x1f;
+       *snr = (_snr << 8) | _snr;
+       return 0;
+}
+
+static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       deb_fe("%s\n",__func__);
+       tune->min_delay_ms = 2000;
+       return 0;
+}
+
+static int vp702x_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       struct vp702x_device_state *dst = st->d->priv;
+       u32 freq = fep->frequency/1000;
+       /*CalFrequency*/
+/*     u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
+       u64 sr;
+       u8 *cmd;
+
+       mutex_lock(&dst->buf_mutex);
+
+       cmd = dst->buf;
+       memset(cmd, 0, 10);
+
+       cmd[0] = (freq >> 8) & 0x7f;
+       cmd[1] =  freq       & 0xff;
+       cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
+
+       sr = (u64) (fep->symbol_rate/1000) << 20;
+       do_div(sr,88000);
+       cmd[3] = (sr >> 12) & 0xff;
+       cmd[4] = (sr >> 4)  & 0xff;
+       cmd[5] = (sr << 4)  & 0xf0;
+
+       deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n",
+                       fep->frequency, freq, freq, fep->symbol_rate,
+                       (unsigned long) sr, (unsigned long) sr);
+
+/*     if (fep->inversion == INVERSION_ON)
+               cmd[6] |= 0x80; */
+
+       if (st->voltage == SEC_VOLTAGE_18)
+               cmd[6] |= 0x40;
+
+/*     if (fep->symbol_rate > 8000000)
+               cmd[6] |= 0x20;
+
+       if (fep->frequency < 1531000)
+               cmd[6] |= 0x04;
+
+       if (st->tone_mode == SEC_TONE_ON)
+               cmd[6] |= 0x01;*/
+
+       cmd[7] = vp702x_chksum(cmd,0,7);
+
+       st->status_check_interval = 250;
+       st->next_status_check = jiffies;
+
+       vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
+
+       if (cmd[2] == 0 && cmd[3] == 0)
+               deb_fe("tuning failed.\n");
+       else
+               deb_fe("tuning succeeded.\n");
+
+       mutex_unlock(&dst->buf_mutex);
+
+       return 0;
+}
+
+static int vp702x_fe_init(struct dvb_frontend *fe)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       deb_fe("%s\n",__func__);
+       vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
+       return 0;
+}
+
+static int vp702x_fe_sleep(struct dvb_frontend *fe)
+{
+       deb_fe("%s\n",__func__);
+       return 0;
+}
+
+static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       u8 *cmd;
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       struct vp702x_device_state *dst = st->d->priv;
+
+       deb_fe("%s\n",__func__);
+
+       if (m->msg_len > 4)
+               return -EINVAL;
+
+       mutex_lock(&dst->buf_mutex);
+
+       cmd = dst->buf;
+       cmd[1] = SET_DISEQC_CMD;
+       cmd[2] = m->msg_len;
+       memcpy(&cmd[3], m->msg, m->msg_len);
+       cmd[7] = vp702x_chksum(cmd, 0, 7);
+
+       vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
+
+       if (cmd[2] == 0 && cmd[3] == 0)
+               deb_fe("diseqc cmd failed.\n");
+       else
+               deb_fe("diseqc cmd succeeded.\n");
+
+       mutex_unlock(&dst->buf_mutex);
+
+       return 0;
+}
+
+static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+       deb_fe("%s\n",__func__);
+       return 0;
+}
+
+static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       struct vp702x_device_state *dst = st->d->priv;
+       u8 *buf;
+
+       deb_fe("%s\n",__func__);
+
+       st->tone_mode = tone;
+
+       if (tone == SEC_TONE_ON)
+               st->lnb_buf[2] = 0x02;
+       else
+               st->lnb_buf[2] = 0x00;
+
+       st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
+
+       mutex_lock(&dst->buf_mutex);
+
+       buf = dst->buf;
+       memcpy(buf, st->lnb_buf, 8);
+
+       vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
+       if (buf[2] == 0 && buf[3] == 0)
+               deb_fe("set_tone cmd failed.\n");
+       else
+               deb_fe("set_tone cmd succeeded.\n");
+
+       mutex_unlock(&dst->buf_mutex);
+
+       return 0;
+}
+
+static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
+               voltage)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       struct vp702x_device_state *dst = st->d->priv;
+       u8 *buf;
+       deb_fe("%s\n",__func__);
+
+       st->voltage = voltage;
+
+       if (voltage != SEC_VOLTAGE_OFF)
+               st->lnb_buf[4] = 0x01;
+       else
+               st->lnb_buf[4] = 0x00;
+
+       st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
+
+       mutex_lock(&dst->buf_mutex);
+
+       buf = dst->buf;
+       memcpy(buf, st->lnb_buf, 8);
+
+       vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
+       if (buf[2] == 0 && buf[3] == 0)
+               deb_fe("set_voltage cmd failed.\n");
+       else
+               deb_fe("set_voltage cmd succeeded.\n");
+
+       mutex_unlock(&dst->buf_mutex);
+       return 0;
+}
+
+static void vp702x_fe_release(struct dvb_frontend* fe)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       kfree(st);
+}
+
+static struct dvb_frontend_ops vp702x_fe_ops;
+
+struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
+{
+       struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
+       if (s == NULL)
+               goto error;
+
+       s->d = d;
+
+       memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
+       s->fe.demodulator_priv = s;
+
+       s->lnb_buf[1] = SET_LNB_POWER;
+       s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
+
+       return &s->fe;
+error:
+       return NULL;
+}
+
+
+static struct dvb_frontend_ops vp702x_fe_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name           = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
+               .frequency_min       = 950000,
+               .frequency_max       = 2150000,
+               .frequency_stepsize  = 1000,   /* kHz for QPSK frontends */
+               .frequency_tolerance = 0,
+               .symbol_rate_min     = 1000000,
+               .symbol_rate_max     = 45000000,
+               .symbol_rate_tolerance = 500,  /* ppm */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+               FE_CAN_QPSK |
+               FE_CAN_FEC_AUTO
+       },
+       .release = vp702x_fe_release,
+
+       .init  = vp702x_fe_init,
+       .sleep = vp702x_fe_sleep,
+
+       .set_frontend = vp702x_fe_set_frontend,
+       .get_tune_settings = vp702x_fe_get_tune_settings,
+
+       .read_status = vp702x_fe_read_status,
+       .read_ber = vp702x_fe_read_ber,
+       .read_signal_strength = vp702x_fe_read_signal_strength,
+       .read_snr = vp702x_fe_read_snr,
+       .read_ucblocks = vp702x_fe_read_unc_blocks,
+
+       .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
+       .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
+       .set_tone = vp702x_fe_set_tone,
+       .set_voltage = vp702x_fe_set_voltage,
+};
diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
new file mode 100644 (file)
index 0000000..07c673a
--- /dev/null
@@ -0,0 +1,444 @@
+/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
+ * receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ *                    Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp702x.h"
+#include <linux/mutex.h>
+
+/* debug */
+int dvb_usb_vp702x_debug;
+module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct vp702x_adapter_state {
+       int pid_filter_count;
+       int pid_filter_can_bypass;
+       u8  pid_filter_state;
+};
+
+static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
+                                    u16 value, u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       ret = usb_control_msg(d->udev,
+               usb_rcvctrlpipe(d->udev, 0),
+               req,
+               USB_TYPE_VENDOR | USB_DIR_IN,
+               value, index, b, blen,
+               2000);
+
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
+               ret = -EIO;
+       } else
+               ret = 0;
+
+
+       deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       return ret;
+}
+
+int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
+                           u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       mutex_lock(&d->usb_mutex);
+       ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
+                                     u16 index, u8 *b, int blen)
+{
+       int ret;
+       deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
+       debug_dump(b,blen,deb_xfer);
+
+       if ((ret = usb_control_msg(d->udev,
+                       usb_sndctrlpipe(d->udev,0),
+                       req,
+                       USB_TYPE_VENDOR | USB_DIR_OUT,
+                       value,index,b,blen,
+                       2000)) != blen) {
+               warn("usb out operation failed. (%d)",ret);
+               return -EIO;
+       } else
+               return 0;
+}
+
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
+{
+       int ret;
+
+       mutex_lock(&d->usb_mutex);
+       ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
+{
+       int ret;
+
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+               return ret;
+
+       ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
+       msleep(msec);
+       ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
+                               int olen, u8 *i, int ilen, int msec)
+{
+       struct vp702x_device_state *st = d->priv;
+       int ret = 0;
+       u8 *buf;
+       int buflen = max(olen + 2, ilen + 1);
+
+       ret = mutex_lock_interruptible(&st->buf_mutex);
+       if (ret < 0)
+               return ret;
+
+       if (buflen > st->buf_len) {
+               buf = kmalloc(buflen, GFP_KERNEL);
+               if (!buf) {
+                       mutex_unlock(&st->buf_mutex);
+                       return -ENOMEM;
+               }
+               info("successfully reallocated a bigger buffer");
+               kfree(st->buf);
+               st->buf = buf;
+               st->buf_len = buflen;
+       } else {
+               buf = st->buf;
+       }
+
+       buf[0] = 0x00;
+       buf[1] = cmd;
+       memcpy(&buf[2], o, olen);
+
+       ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
+
+       if (ret == 0)
+               memcpy(i, &buf[1], ilen);
+       mutex_unlock(&st->buf_mutex);
+
+       return ret;
+}
+
+static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
+{
+       int ret;
+       struct vp702x_device_state *st = adap->dev->priv;
+       u8 *buf;
+
+       mutex_lock(&st->buf_mutex);
+
+       buf = st->buf;
+       memset(buf, 0, 16);
+
+       ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
+                       0, buf, 16);
+       mutex_unlock(&st->buf_mutex);
+       return ret;
+}
+
+static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
+{
+       int ret;
+       struct vp702x_device_state *st = adap->dev->priv;
+       u8 *buf;
+
+       mutex_lock(&st->buf_mutex);
+
+       buf = st->buf;
+       memset(buf, 0, 16);
+       ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
+                       0, buf, 16);
+
+       mutex_unlock(&st->buf_mutex);
+
+       return ret;
+}
+
+static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
+{
+       struct vp702x_adapter_state *st = adap->priv;
+       struct vp702x_device_state *dst = adap->dev->priv;
+       u8 *buf;
+
+       if (onoff)
+               st->pid_filter_state |=  (1 << id);
+       else {
+               st->pid_filter_state &= ~(1 << id);
+               pid = 0xffff;
+       }
+
+       id = 0x10 + id*2;
+
+       vp702x_set_pld_state(adap, st->pid_filter_state);
+
+       mutex_lock(&dst->buf_mutex);
+
+       buf = dst->buf;
+       memset(buf, 0, 16);
+       vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
+       vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
+
+       mutex_unlock(&dst->buf_mutex);
+
+       return 0;
+}
+
+
+static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
+{
+       struct vp702x_adapter_state *st = adap->priv;
+       struct vp702x_device_state *dst = adap->dev->priv;
+       int i;
+       u8 *b;
+
+       st->pid_filter_count = 8;
+       st->pid_filter_can_bypass = 1;
+       st->pid_filter_state = 0x00;
+
+       vp702x_set_pld_mode(adap, 1); /* bypass */
+
+       for (i = 0; i < st->pid_filter_count; i++)
+               vp702x_set_pid(adap, 0xffff, i, 1);
+
+       mutex_lock(&dst->buf_mutex);
+       b = dst->buf;
+       memset(b, 0, 10);
+       vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
+       vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
+       vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
+       mutex_unlock(&dst->buf_mutex);
+       /*vp702x_set_pld_mode(d, 0); // filter */
+
+       return 0;
+}
+
+static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       return 0;
+}
+
+/* keys for the enclosed remote control */
+static struct rc_map_table rc_map_vp702x_table[] = {
+       { 0x0001, KEY_1 },
+       { 0x0002, KEY_2 },
+};
+
+/* remote control stuff (does not work with my box) */
+static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 *key;
+       int i;
+
+/* remove the following return to enabled remote querying */
+       return 0;
+
+       key = kmalloc(10, GFP_KERNEL);
+       if (!key)
+               return -ENOMEM;
+
+       vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
+
+       deb_rc("remote query key: %x %d\n",key[1],key[1]);
+
+       if (key[1] == 0x44) {
+               *state = REMOTE_NO_KEY_PRESSED;
+               kfree(key);
+               return 0;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
+               if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
+                       *state = REMOTE_KEY_PRESSED;
+                       *event = rc_map_vp702x_table[i].keycode;
+                       break;
+               }
+       kfree(key);
+       return 0;
+}
+
+
+static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+       u8 i, *buf;
+       struct vp702x_device_state *st = d->priv;
+
+       mutex_lock(&st->buf_mutex);
+       buf = st->buf;
+       for (i = 6; i < 12; i++)
+               vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
+
+       memcpy(mac, buf, 6);
+       mutex_unlock(&st->buf_mutex);
+       return 0;
+}
+
+static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       u8 buf[10] = { 0 };
+
+       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
+
+       if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
+                                  buf, 10, 10))
+               return -EIO;
+
+       buf[9] = '\0';
+       info("system string: %s",&buf[1]);
+
+       vp702x_init_pid_filter(adap);
+
+       adap->fe_adap[0].fe = vp702x_fe_attach(adap->dev);
+       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
+
+       return 0;
+}
+
+static struct dvb_usb_device_properties vp702x_properties;
+
+static int vp702x_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct dvb_usb_device *d;
+       struct vp702x_device_state *st;
+       int ret;
+
+       ret = dvb_usb_device_init(intf, &vp702x_properties,
+                                  THIS_MODULE, &d, adapter_nr);
+       if (ret)
+               goto out;
+
+       st = d->priv;
+       st->buf_len = 16;
+       st->buf = kmalloc(st->buf_len, GFP_KERNEL);
+       if (!st->buf) {
+               ret = -ENOMEM;
+               dvb_usb_device_exit(intf);
+               goto out;
+       }
+       mutex_init(&st->buf_mutex);
+
+out:
+       return ret;
+
+}
+
+static void vp702x_usb_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       struct vp702x_device_state *st = d->priv;
+       mutex_lock(&st->buf_mutex);
+       kfree(st->buf);
+       mutex_unlock(&st->buf_mutex);
+       dvb_usb_device_exit(intf);
+}
+
+static struct usb_device_id vp702x_usb_table [] = {
+           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
+//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
+//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
+           { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
+
+static struct dvb_usb_device_properties vp702x_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware            = "dvb-usb-vp702x-02.fw",
+       .no_reconnect        = 1,
+
+       .size_of_priv     = sizeof(struct vp702x_device_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .caps             = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
+
+                       .streaming_ctrl   = vp702x_streaming_ctrl,
+                       .frontend_attach  = vp702x_frontend_attach,
+
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 10,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+                       .size_of_priv     = sizeof(struct vp702x_adapter_state),
+               }
+       },
+       .read_mac_address = vp702x_read_mac_addr,
+
+       .rc.legacy = {
+               .rc_map_table       = rc_map_vp702x_table,
+               .rc_map_size  = ARRAY_SIZE(rc_map_vp702x_table),
+               .rc_interval      = 400,
+               .rc_query         = vp702x_rc_query,
+       },
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
+                 .cold_ids = { &vp702x_usb_table[0], NULL },
+                 .warm_ids = { NULL },
+               },
+/*             { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
+                 .cold_ids = { &vp702x_usb_table[2], NULL },
+                 .warm_ids = { &vp702x_usb_table[3], NULL },
+               },
+*/             { NULL },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp702x_usb_driver = {
+       .name           = "dvb_usb_vp702x",
+       .probe          = vp702x_usb_probe,
+       .disconnect     = vp702x_usb_disconnect,
+       .id_table       = vp702x_usb_table,
+};
+
+module_usb_driver(vp702x_usb_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp702x.h b/drivers/media/usb/dvb-usb/vp702x.h
new file mode 100644 (file)
index 0000000..20b9005
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef _DVB_USB_VP7021_H_
+#define _DVB_USB_VP7021_H_
+
+#define DVB_USB_LOG_PREFIX "vp702x"
+#include "dvb-usb.h"
+
+extern int dvb_usb_vp702x_debug;
+#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_vp702x_debug,0x04,args)
+#define deb_fe(args...)   dprintk(dvb_usb_vp702x_debug,0x08,args)
+
+/* commands are read and written with USB control messages */
+
+/* consecutive read/write operation */
+#define REQUEST_OUT            0xB2
+#define REQUEST_IN             0xB3
+
+/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
+ * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
+ * the returning buffer looks as follows
+ * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
+
+#define GET_TUNER_STATUS       0x05
+/* additional in buffer:
+ * 0   1   2    3              4   5   6               7       8
+ * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
+
+#define GET_SYSTEM_STRING      0x06
+/* additional in buffer:
+ * 0   1   2   3   4   5   6   7   8
+ * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
+
+#define SET_DISEQC_CMD         0x08
+/* additional out buffer:
+ * 0    1  2  3  4
+ * len  X1 X2 X3 X4
+ * additional in buffer:
+ * 0   1 2
+ * N/A 0 0   b[1] == b[2] == 0 -> success, failure otherwise */
+
+#define SET_LNB_POWER          0x09
+/* additional out buffer:
+ * 0    1    2
+ * 0x00 0xff 1 = on, 0 = off
+ * additional in buffer:
+ * 0   1 2
+ * N/A 0 0   b[1] == b[2] == 0 -> success failure otherwise */
+
+#define GET_MAC_ADDRESS                0x0A
+/* #define GET_MAC_ADDRESS   0x0B */
+/* additional in buffer:
+ * 0   1   2            3    4    5    6    7    8
+ * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
+
+#define SET_PID_FILTER         0x11
+/* additional in buffer:
+ * 0        1        ... 14       15       16
+ * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
+
+/* request: 0xB2; i: 0; v: 0;
+ * b[0] != 0 -> tune and lock a channel
+ * 0     1     2       3      4      5      6    7
+ * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
+ */
+
+/* one direction requests */
+#define READ_REMOTE_REQ                0xB4
+/* IN  i: 0; v: 0; b[0] == request, b[1] == key */
+
+#define READ_PID_NUMBER_REQ    0xB5
+/* IN  i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
+
+#define WRITE_EEPROM_REQ       0xB6
+/* OUT i: offset; v: value to write; no extra buffer */
+
+#define READ_EEPROM_REQ                0xB7
+/* IN  i: bufferlen; v: offset; buffer with bufferlen bytes */
+
+#define READ_STATUS            0xB8
+/* IN  i: 0; v: 0; bufferlen 10 */
+
+#define READ_TUNER_REG_REQ     0xB9
+/* IN  i: 0; v: register; b[0] = value */
+
+#define READ_FX2_REG_REQ       0xBA
+/* IN  i: offset; v: 0; b[0] = value */
+
+#define WRITE_FX2_REG_REQ      0xBB
+/* OUT i: offset; v: value to write; 1 byte extra buffer */
+
+#define SET_TUNER_POWER_REQ    0xBC
+/* IN  i: 0 = power off, 1 = power on */
+
+#define WRITE_TUNER_REG_REQ    0xBD
+/* IN  i: register, v: value to write, no extra buffer */
+
+#define RESET_TUNER            0xBE
+/* IN  i: 0, v: 0, no extra buffer */
+
+struct vp702x_device_state {
+       struct mutex buf_mutex;
+       int buf_len;
+       u8 *buf;
+};
+
+
+extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
+
+extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
+extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
new file mode 100644 (file)
index 0000000..b8825b1
--- /dev/null
@@ -0,0 +1,190 @@
+/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp7045.h"
+
+/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
+ *
+ * Programming is hidden inside the firmware, so set_frontend is very easy.
+ * Even though there is a Firmware command that one can use to access the demod
+ * via its registers. This is used for status information.
+ */
+
+struct vp7045_fe_state {
+       struct dvb_frontend fe;
+       struct dvb_usb_device *d;
+};
+
+static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       u8 s0 = vp7045_read_reg(state->d,0x00),
+          s1 = vp7045_read_reg(state->d,0x01),
+          s3 = vp7045_read_reg(state->d,0x03);
+
+       *status = 0;
+       if (s0 & (1 << 4))
+               *status |= FE_HAS_CARRIER;
+       if (s0 & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if (s0 & (1 << 5))
+               *status |= FE_HAS_LOCK;
+       if (s1 & (1 << 1))
+               *status |= FE_HAS_SYNC;
+       if (s3 & (1 << 6))
+               *status |= FE_HAS_SIGNAL;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+                       (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
+              (vp7045_read_reg(state->d, 0x0E) << 8) |
+               vp7045_read_reg(state->d, 0x0F);
+       return 0;
+}
+
+static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
+                   vp7045_read_reg(state->d, 0x11);
+       return 0;
+}
+
+static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
+               vp7045_read_reg(state->d, 0x15);
+
+       *strength = ~signal;
+       return 0;
+}
+
+static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       u8 _snr = vp7045_read_reg(state->d, 0x09);
+       *snr = (_snr << 8) | _snr;
+       return 0;
+}
+
+static int vp7045_fe_init(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int vp7045_fe_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 800;
+       return 0;
+}
+
+static int vp7045_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       u8 buf[5];
+       u32 freq = fep->frequency / 1000;
+
+       buf[0] = (freq >> 16) & 0xff;
+       buf[1] = (freq >>  8) & 0xff;
+       buf[2] =  freq        & 0xff;
+       buf[3] = 0;
+
+       switch (fep->bandwidth_hz) {
+       case 8000000:
+               buf[4] = 8;
+               break;
+       case 7000000:
+               buf[4] = 7;
+               break;
+       case 6000000:
+               buf[4] = 6;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
+       return 0;
+}
+
+static void vp7045_fe_release(struct dvb_frontend* fe)
+{
+       struct vp7045_fe_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops vp7045_fe_ops;
+
+struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
+{
+       struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
+       if (s == NULL)
+               goto error;
+
+       s->d = d;
+       memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.demodulator_priv = s;
+
+       return &s->fe;
+error:
+       return NULL;
+}
+
+
+static struct dvb_frontend_ops vp7045_fe_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Twinhan VP7045/46 USB DVB-T",
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 1000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                               FE_CAN_TRANSMISSION_MODE_AUTO |
+                               FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_RECOVER |
+                               FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = vp7045_fe_release,
+
+       .init = vp7045_fe_init,
+       .sleep = vp7045_fe_sleep,
+
+       .set_frontend = vp7045_fe_set_frontend,
+       .get_tune_settings = vp7045_fe_get_tune_settings,
+
+       .read_status = vp7045_fe_read_status,
+       .read_ber = vp7045_fe_read_ber,
+       .read_signal_strength = vp7045_fe_read_signal_strength,
+       .read_snr = vp7045_fe_read_snr,
+       .read_ucblocks = vp7045_fe_read_unc_blocks,
+};
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
new file mode 100644 (file)
index 0000000..d750724
--- /dev/null
@@ -0,0 +1,302 @@
+/* DVB USB compliant Linux driver for the
+ *  - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
+ *  - DigitalNow TinyUSB2 DVB-t receiver
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp7045.h"
+
+/* debug */
+static int dvb_usb_vp7045_debug;
+module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_vp7045_debug,0x04,args)
+
+int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
+{
+       int ret = 0;
+       u8 *buf = d->priv;
+
+       buf[0] = cmd;
+
+       if (outlen > 19)
+               outlen = 19;
+
+       if (inlen > 11)
+               inlen = 11;
+
+       ret = mutex_lock_interruptible(&d->usb_mutex);
+       if (ret)
+               return ret;
+
+       if (out != NULL && outlen > 0)
+               memcpy(&buf[1], out, outlen);
+
+       deb_xfer("out buffer: ");
+       debug_dump(buf, outlen+1, deb_xfer);
+
+
+       if (usb_control_msg(d->udev,
+                       usb_sndctrlpipe(d->udev,0),
+                       TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
+                       buf, 20, 2000) != 20) {
+               err("USB control message 'out' went wrong.");
+               ret = -EIO;
+               goto unlock;
+       }
+
+       msleep(msec);
+
+       if (usb_control_msg(d->udev,
+                       usb_rcvctrlpipe(d->udev,0),
+                       TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                       buf, 12, 2000) != 12) {
+               err("USB control message 'in' went wrong.");
+               ret = -EIO;
+               goto unlock;
+       }
+
+       deb_xfer("in buffer: ");
+       debug_dump(buf, 12, deb_xfer);
+
+       if (in != NULL && inlen > 0)
+               memcpy(in, &buf[1], inlen);
+
+unlock:
+       mutex_unlock(&d->usb_mutex);
+
+       return ret;
+}
+
+u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
+{
+       u8 obuf[2] = { 0 },v;
+       obuf[1] = reg;
+
+       vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
+
+       return v;
+}
+
+static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 v = onoff;
+       return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
+}
+
+/* remote control stuff */
+
+/* The keymapping struct. Somehow this should be loaded to the driver, but
+ * currently it is hardcoded. */
+static struct rc_map_table rc_map_vp7045_table[] = {
+       { 0x0016, KEY_POWER },
+       { 0x0010, KEY_MUTE },
+       { 0x0003, KEY_1 },
+       { 0x0001, KEY_2 },
+       { 0x0006, KEY_3 },
+       { 0x0009, KEY_4 },
+       { 0x001d, KEY_5 },
+       { 0x001f, KEY_6 },
+       { 0x000d, KEY_7 },
+       { 0x0019, KEY_8 },
+       { 0x001b, KEY_9 },
+       { 0x0015, KEY_0 },
+       { 0x0005, KEY_CHANNELUP },
+       { 0x0002, KEY_CHANNELDOWN },
+       { 0x001e, KEY_VOLUMEUP },
+       { 0x000a, KEY_VOLUMEDOWN },
+       { 0x0011, KEY_RECORD },
+       { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+       { 0x0014, KEY_PLAY },
+       { 0x001a, KEY_STOP },
+       { 0x0040, KEY_REWIND },
+       { 0x0012, KEY_FASTFORWARD },
+       { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+       { 0x004c, KEY_PAUSE },
+       { 0x004d, KEY_SCREEN }, /* Full screen mode. */
+       { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+       { 0x000c, KEY_CANCEL }, /* Cancel */
+       { 0x001c, KEY_EPG }, /* EPG */
+       { 0x0000, KEY_TAB }, /* Tab */
+       { 0x0048, KEY_INFO }, /* Preview */
+       { 0x0004, KEY_LIST }, /* RecordList */
+       { 0x000f, KEY_TEXT }, /* Teletext */
+       { 0x0041, KEY_PREVIOUSSONG },
+       { 0x0042, KEY_NEXTSONG },
+       { 0x004b, KEY_UP },
+       { 0x0051, KEY_DOWN },
+       { 0x004e, KEY_LEFT },
+       { 0x0052, KEY_RIGHT },
+       { 0x004f, KEY_ENTER },
+       { 0x0013, KEY_CANCEL },
+       { 0x004a, KEY_CLEAR },
+       { 0x0054, KEY_PRINT }, /* Capture */
+       { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
+       { 0x0008, KEY_VIDEO }, /* A/V */
+       { 0x0007, KEY_SLEEP }, /* Hibernate */
+       { 0x0045, KEY_ZOOM }, /* Zoom+ */
+       { 0x0018, KEY_RED},
+       { 0x0053, KEY_GREEN},
+       { 0x005e, KEY_YELLOW},
+       { 0x005f, KEY_BLUE}
+};
+
+static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 key;
+       int i;
+       vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
+
+       deb_rc("remote query key: %x %d\n",key,key);
+
+       if (key == 0x44) {
+               *state = REMOTE_NO_KEY_PRESSED;
+               return 0;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
+               if (rc5_data(&rc_map_vp7045_table[i]) == key) {
+                       *state = REMOTE_KEY_PRESSED;
+                       *event = rc_map_vp7045_table[i].keycode;
+                       break;
+               }
+       return 0;
+}
+
+static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
+{
+       int i = 0;
+       u8 v,br[2];
+       for (i=0; i < len; i++) {
+               v = offset + i;
+               vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
+               buf[i] = br[1];
+       }
+       deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
+       debug_dump(buf,i,deb_info);
+       return 0;
+}
+
+static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+       return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
+}
+
+static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       u8 buf[255] = { 0 };
+
+       vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
+       buf[10] = '\0';
+       deb_info("firmware says: %s ",buf);
+
+       vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
+       buf[10] = '\0';
+       deb_info("%s ",buf);
+
+       vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
+       buf[10] = '\0';
+       deb_info("v%s\n",buf);
+
+/*     Dump the EEPROM */
+/*     vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
+
+       adap->fe_adap[0].fe = vp7045_fe_attach(adap->dev);
+
+       return 0;
+}
+
+static struct dvb_usb_device_properties vp7045_properties;
+
+static int vp7045_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       return dvb_usb_device_init(intf, &vp7045_properties,
+                                  THIS_MODULE, NULL, adapter_nr);
+}
+
+static struct usb_device_id vp7045_usb_table [] = {
+           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
+           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
+           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
+           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
+           { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
+
+static struct dvb_usb_device_properties vp7045_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-vp7045-01.fw",
+       .size_of_priv = 20,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .num_frontends = 1,
+               .fe = {{
+                       .frontend_attach  = vp7045_frontend_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 7,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 4096,
+                                       }
+                               }
+                       },
+               }},
+               }
+       },
+       .power_ctrl       = vp7045_power_ctrl,
+       .read_mac_address = vp7045_read_mac_addr,
+
+       .rc.legacy = {
+               .rc_interval      = 400,
+               .rc_map_table       = rc_map_vp7045_table,
+               .rc_map_size  = ARRAY_SIZE(rc_map_vp7045_table),
+               .rc_query         = vp7045_rc_query,
+       },
+
+       .num_device_descs = 2,
+       .devices = {
+               { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
+                 .cold_ids = { &vp7045_usb_table[0], NULL },
+                 .warm_ids = { &vp7045_usb_table[1], NULL },
+               },
+               { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
+                 .cold_ids = { &vp7045_usb_table[2], NULL },
+                 .warm_ids = { &vp7045_usb_table[3], NULL },
+               },
+               { NULL },
+       }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp7045_usb_driver = {
+       .name           = "dvb_usb_vp7045",
+       .probe          = vp7045_usb_probe,
+       .disconnect     = dvb_usb_device_exit,
+       .id_table       = vp7045_usb_table,
+};
+
+module_usb_driver(vp7045_usb_driver);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp7045.h b/drivers/media/usb/dvb-usb/vp7045.h
new file mode 100644 (file)
index 0000000..cf5ec46
--- /dev/null
@@ -0,0 +1,70 @@
+/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
+ * USB2.0 DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *     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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_VP7045_H_
+#define _DVB_USB_VP7045_H_
+
+#define DVB_USB_LOG_PREFIX "vp7045"
+#include "dvb-usb.h"
+
+/* vp7045 commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN                     0xC0
+#define TH_COMMAND_OUT                    0xC1
+
+/* command bytes */
+#define TUNER_REG_READ                    0x03
+#define TUNER_REG_WRITE                   0x04
+
+#define RC_VAL_READ                       0x05
+ #define RC_NO_KEY                        0x44
+
+#define SET_TUNER_POWER                   0x06
+#define CHECK_TUNER_POWER                 0x12
+ #define Tuner_Power_ON                   1
+ #define Tuner_Power_OFF                  0
+
+#define GET_USB_SPEED                     0x07
+
+#define LOCK_TUNER_COMMAND                0x09
+
+#define TUNER_SIGNAL_READ                 0x0A
+
+/* FX2 eeprom */
+#define SET_EE_VALUE                      0x10
+#define GET_EE_VALUE                      0x11
+ #define FX2_ID_ADDR                      0x00
+ #define VID_MSB_ADDR                     0x02
+ #define VID_LSB_ADDR                     0x01
+ #define PID_MSB_ADDR                     0x04
+ #define PID_LSB_ADDR                     0x03
+ #define MAC_0_ADDR                       0x07
+ #define MAC_1_ADDR                       0x08
+ #define MAC_2_ADDR                       0x09
+ #define MAC_3_ADDR                       0x0a
+ #define MAC_4_ADDR                       0x0b
+ #define MAC_5_ADDR                       0x0c
+
+#define RESET_FX2                         0x13
+
+#define FW_VERSION_READ                   0x0B
+#define VENDOR_STRING_READ                0x0C
+#define PRODUCT_STRING_READ               0x0D
+#define FW_BCD_VERSION_READ               0x14
+
+extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
+extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
+extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
+
+#endif
diff --git a/drivers/media/usb/siano/Kconfig b/drivers/media/usb/siano/Kconfig
new file mode 100644 (file)
index 0000000..bc6456e
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_SIANO_MDTV
+       tristate "Siano SMS1xxx based MDTV receiver"
+       depends on DVB_CORE && RC_CORE && HAS_DMA
+       ---help---
+         Choose Y or M here if you have MDTV receiver with a Siano chipset.
+
+         To compile this driver as a module, choose M here
+         (The module will be called smsmdtv).
+
+         Further documentation on this driver can be found on the WWW
+         at http://www.siano-ms.com/
+
+if SMS_SIANO_MDTV
+menu "Siano module components"
+
+# Hardware interfaces support
+
+config SMS_USB_DRV
+       tristate "USB interface support"
+       depends on DVB_CORE && USB
+       ---help---
+         Choose if you would like to have Siano's support for USB interface
+
+config SMS_SDIO_DRV
+       tristate "SDIO interface support"
+       depends on DVB_CORE && MMC
+       ---help---
+         Choose if you would like to have Siano's support for SDIO interface
+endmenu
+endif # SMS_SIANO_MDTV
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
new file mode 100644 (file)
index 0000000..14756bd
--- /dev/null
@@ -0,0 +1,11 @@
+
+smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
+
+obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
+obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
+obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
+
+ccflags-y += -Idrivers/media/dvb-core
+
+ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/usb/siano/sms-cards.c b/drivers/media/usb/siano/sms-cards.c
new file mode 100644 (file)
index 0000000..680c781
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ *  Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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 "sms-cards.h"
+#include "smsir.h"
+#include <linux/module.h>
+
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
+
+static struct sms_board sms_boards[] = {
+       [SMS_BOARD_UNKNOWN] = {
+               .name   = "Unknown board",
+       },
+       [SMS1XXX_BOARD_SIANO_STELLAR] = {
+               .name   = "Siano Stellar Digital Receiver",
+               .type   = SMS_STELLAR,
+       },
+       [SMS1XXX_BOARD_SIANO_NOVA_A] = {
+               .name   = "Siano Nova A Digital Receiver",
+               .type   = SMS_NOVA_A0,
+       },
+       [SMS1XXX_BOARD_SIANO_NOVA_B] = {
+               .name   = "Siano Nova B Digital Receiver",
+               .type   = SMS_NOVA_B0,
+       },
+       [SMS1XXX_BOARD_SIANO_VEGA] = {
+               .name   = "Siano Vega Digital Receiver",
+               .type   = SMS_VEGA,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
+               .name   = "Hauppauge Catamount",
+               .type   = SMS_STELLAR,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
+               .name   = "Hauppauge Okemo-A",
+               .type   = SMS_NOVA_A0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
+               .name   = "Hauppauge Okemo-B",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
+               .name   = "Hauppauge WinTV MiniStick",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .rc_codes = RC_MAP_HAUPPAUGE,
+               .board_cfg.leds_power = 26,
+               .board_cfg.led0 = 27,
+               .board_cfg.led1 = 28,
+               .board_cfg.ir = 9,
+               .led_power = 26,
+               .led_lo    = 27,
+               .led_hi    = 28,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
+               .name   = "Hauppauge WinTV MiniCard",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .lna_ctrl  = 29,
+               .board_cfg.foreign_lna0_ctrl = 29,
+               .rf_switch = 17,
+               .board_cfg.rf_switch_uhf = 17,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
+               .name   = "Hauppauge WinTV MiniCard",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .lna_ctrl  = -1,
+       },
+       [SMS1XXX_BOARD_SIANO_NICE] = {
+       /* 11 */
+               .name = "Siano Nice Digital Receiver",
+               .type = SMS_NOVA_B0,
+       },
+       [SMS1XXX_BOARD_SIANO_VENICE] = {
+       /* 12 */
+               .name = "Siano Venice Digital Receiver",
+               .type = SMS_VEGA,
+       },
+};
+
+struct sms_board *sms_get_board(unsigned id)
+{
+       BUG_ON(id >= ARRAY_SIZE(sms_boards));
+
+       return &sms_boards[id];
+}
+EXPORT_SYMBOL_GPL(sms_get_board);
+static inline void sms_gpio_assign_11xx_default_led_config(
+               struct smscore_gpio_config *pGpioConfig) {
+       pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
+       pGpioConfig->InputCharacteristics =
+               SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
+       pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
+       pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
+       pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
+}
+
+int sms_board_event(struct smscore_device_t *coredev,
+               enum SMS_BOARD_EVENTS gevent) {
+       struct smscore_gpio_config MyGpioConfig;
+
+       sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
+
+       switch (gevent) {
+       case BOARD_EVENT_POWER_INIT: /* including hotplug */
+               break; /* BOARD_EVENT_BIND */
+
+       case BOARD_EVENT_POWER_SUSPEND:
+               break; /* BOARD_EVENT_POWER_SUSPEND */
+
+       case BOARD_EVENT_POWER_RESUME:
+               break; /* BOARD_EVENT_POWER_RESUME */
+
+       case BOARD_EVENT_BIND:
+               break; /* BOARD_EVENT_BIND */
+
+       case BOARD_EVENT_SCAN_PROG:
+               break; /* BOARD_EVENT_SCAN_PROG */
+       case BOARD_EVENT_SCAN_COMP:
+               break; /* BOARD_EVENT_SCAN_COMP */
+       case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
+               break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
+       case BOARD_EVENT_FE_LOCK:
+               break; /* BOARD_EVENT_FE_LOCK */
+       case BOARD_EVENT_FE_UNLOCK:
+               break; /* BOARD_EVENT_FE_UNLOCK */
+       case BOARD_EVENT_DEMOD_LOCK:
+               break; /* BOARD_EVENT_DEMOD_LOCK */
+       case BOARD_EVENT_DEMOD_UNLOCK:
+               break; /* BOARD_EVENT_DEMOD_UNLOCK */
+       case BOARD_EVENT_RECEPTION_MAX_4:
+               break; /* BOARD_EVENT_RECEPTION_MAX_4 */
+       case BOARD_EVENT_RECEPTION_3:
+               break; /* BOARD_EVENT_RECEPTION_3 */
+       case BOARD_EVENT_RECEPTION_2:
+               break; /* BOARD_EVENT_RECEPTION_2 */
+       case BOARD_EVENT_RECEPTION_1:
+               break; /* BOARD_EVENT_RECEPTION_1 */
+       case BOARD_EVENT_RECEPTION_LOST_0:
+               break; /* BOARD_EVENT_RECEPTION_LOST_0 */
+       case BOARD_EVENT_MULTIPLEX_OK:
+               break; /* BOARD_EVENT_MULTIPLEX_OK */
+       case BOARD_EVENT_MULTIPLEX_ERRORS:
+               break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
+
+       default:
+               sms_err("Unknown SMS board event");
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_event);
+
+static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
+{
+       int lvl, ret;
+       u32 gpio;
+       struct smscore_config_gpio gpioconfig = {
+               .direction            = SMS_GPIO_DIRECTION_OUTPUT,
+               .pullupdown           = SMS_GPIO_PULLUPDOWN_NONE,
+               .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
+               .outputslewrate       = SMS_GPIO_OUTPUTSLEWRATE_FAST,
+               .outputdriving        = SMS_GPIO_OUTPUTDRIVING_4mA,
+       };
+
+       if (pin == 0)
+               return -EINVAL;
+
+       if (pin < 0) {
+               /* inverted gpio */
+               gpio = pin * -1;
+               lvl = enable ? 0 : 1;
+       } else {
+               gpio = pin;
+               lvl = enable ? 1 : 0;
+       }
+
+       ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
+       if (ret < 0)
+               return ret;
+
+       return smscore_set_gpio(coredev, gpio, lvl);
+}
+
+int sms_board_setup(struct smscore_device_t *coredev)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               /* turn off all LEDs */
+               sms_set_gpio(coredev, board->led_power, 0);
+               sms_set_gpio(coredev, board->led_hi, 0);
+               sms_set_gpio(coredev, board->led_lo, 0);
+               break;
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               /* turn off LNA */
+               sms_set_gpio(coredev, board->lna_ctrl, 0);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_setup);
+
+int sms_board_power(struct smscore_device_t *coredev, int onoff)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               /* power LED */
+               sms_set_gpio(coredev,
+                            board->led_power, onoff ? 1 : 0);
+               break;
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               /* LNA */
+               if (!onoff)
+                       sms_set_gpio(coredev, board->lna_ctrl, 0);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_power);
+
+int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       /* dont touch GPIO if LEDs are already set */
+       if (smscore_led_state(coredev, -1) == led)
+               return 0;
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               sms_set_gpio(coredev,
+                            board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
+               sms_set_gpio(coredev,
+                            board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
+
+               smscore_led_state(coredev, led);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               sms_set_gpio(coredev,
+                            board->rf_switch, onoff ? 1 : 0);
+               return sms_set_gpio(coredev,
+                                   board->lna_ctrl, onoff ? 1 : 0);
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+       switch (id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+               request_module("smsdvb");
+               break;
+       default:
+               /* do nothing */
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/usb/siano/sms-cards.h b/drivers/media/usb/siano/sms-cards.h
new file mode 100644 (file)
index 0000000..d8cdf75
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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 __SMS_CARDS_H__
+#define __SMS_CARDS_H__
+
+#include <linux/usb.h>
+#include "smscoreapi.h"
+#include "smsir.h"
+
+#define SMS_BOARD_UNKNOWN 0
+#define SMS1XXX_BOARD_SIANO_STELLAR 1
+#define SMS1XXX_BOARD_SIANO_NOVA_A  2
+#define SMS1XXX_BOARD_SIANO_NOVA_B  3
+#define SMS1XXX_BOARD_SIANO_VEGA    4
+#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
+#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
+#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
+#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
+#define SMS1XXX_BOARD_SIANO_NICE       11
+#define SMS1XXX_BOARD_SIANO_VENICE     12
+
+struct sms_board_gpio_cfg {
+       int lna_vhf_exist;
+       int lna_vhf_ctrl;
+       int lna_uhf_exist;
+       int lna_uhf_ctrl;
+       int lna_uhf_d_ctrl;
+       int lna_sband_exist;
+       int lna_sband_ctrl;
+       int lna_sband_d_ctrl;
+       int foreign_lna0_ctrl;
+       int foreign_lna1_ctrl;
+       int foreign_lna2_ctrl;
+       int rf_switch_vhf;
+       int rf_switch_uhf;
+       int rf_switch_sband;
+       int leds_power;
+       int led0;
+       int led1;
+       int led2;
+       int led3;
+       int led4;
+       int ir;
+       int eeprom_wp;
+       int mrc_sense;
+       int mrc_pdn_resetn;
+       int mrc_gp0; /* mrcs spi int */
+       int mrc_gp1;
+       int mrc_gp2;
+       int mrc_gp3;
+       int mrc_gp4;
+       int host_spi_gsp_ts_int;
+};
+
+struct sms_board {
+       enum sms_device_type_st type;
+       char *name, *fw[DEVICE_MODE_MAX];
+       struct sms_board_gpio_cfg board_cfg;
+       char *rc_codes;                         /* Name of IR codes table */
+
+       /* gpios */
+       int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
+};
+
+struct sms_board *sms_get_board(unsigned id);
+
+extern struct smscore_device_t *coredev;
+
+enum SMS_BOARD_EVENTS {
+       BOARD_EVENT_POWER_INIT,
+       BOARD_EVENT_POWER_SUSPEND,
+       BOARD_EVENT_POWER_RESUME,
+       BOARD_EVENT_BIND,
+       BOARD_EVENT_SCAN_PROG,
+       BOARD_EVENT_SCAN_COMP,
+       BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
+       BOARD_EVENT_FE_LOCK,
+       BOARD_EVENT_FE_UNLOCK,
+       BOARD_EVENT_DEMOD_LOCK,
+       BOARD_EVENT_DEMOD_UNLOCK,
+       BOARD_EVENT_RECEPTION_MAX_4,
+       BOARD_EVENT_RECEPTION_3,
+       BOARD_EVENT_RECEPTION_2,
+       BOARD_EVENT_RECEPTION_1,
+       BOARD_EVENT_RECEPTION_LOST_0,
+       BOARD_EVENT_MULTIPLEX_OK,
+       BOARD_EVENT_MULTIPLEX_ERRORS
+};
+
+int sms_board_event(struct smscore_device_t *coredev,
+               enum SMS_BOARD_EVENTS gevent);
+
+int sms_board_setup(struct smscore_device_t *coredev);
+
+#define SMS_LED_OFF 0
+#define SMS_LED_LO  1
+#define SMS_LED_HI  2
+int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
+int sms_board_power(struct smscore_device_t *coredev, int onoff);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
+
+extern int sms_board_load_modules(int id);
+
+#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/usb/siano/smscoreapi.c b/drivers/media/usb/siano/smscoreapi.c
new file mode 100644 (file)
index 0000000..9cc5554
--- /dev/null
@@ -0,0 +1,1637 @@
+/*
+ *  Siano core API module
+ *
+ *  This file contains implementation for the interface to sms core component
+ *
+ *  author: Uri Shkolnik
+ *
+ *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <linux/firmware.h>
+#include <linux/wait.h>
+#include <asm/byteorder.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+#include "smsir.h"
+#include "smsendian.h"
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+struct smscore_device_notifyee_t {
+       struct list_head entry;
+       hotplug_t hotplug;
+};
+
+struct smscore_idlist_t {
+       struct list_head entry;
+       int             id;
+       int             data_type;
+};
+
+struct smscore_client_t {
+       struct list_head entry;
+       struct smscore_device_t *coredev;
+       void                    *context;
+       struct list_head        idlist;
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+};
+
+void smscore_set_board_id(struct smscore_device_t *core, int id)
+{
+       core->board_id = id;
+}
+
+int smscore_led_state(struct smscore_device_t *core, int led)
+{
+       if (led >= 0)
+               core->led_state = led;
+       return core->led_state;
+}
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
+
+int smscore_get_board_id(struct smscore_device_t *core)
+{
+       return core->board_id;
+}
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
+
+struct smscore_registry_entry_t {
+       struct list_head entry;
+       char                    devpath[32];
+       int                             mode;
+       enum sms_device_type_st type;
+};
+
+static struct list_head g_smscore_notifyees;
+static struct list_head g_smscore_devices;
+static struct mutex g_smscore_deviceslock;
+
+static struct list_head g_smscore_registry;
+static struct mutex g_smscore_registrylock;
+
+static int default_mode = 4;
+
+module_param(default_mode, int, 0644);
+MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
+
+static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+       struct list_head *next;
+
+       kmutex_lock(&g_smscore_registrylock);
+       for (next = g_smscore_registry.next;
+            next != &g_smscore_registry;
+            next = next->next) {
+               entry = (struct smscore_registry_entry_t *) next;
+               if (!strcmp(entry->devpath, devpath)) {
+                       kmutex_unlock(&g_smscore_registrylock);
+                       return entry;
+               }
+       }
+       entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
+       if (entry) {
+               entry->mode = default_mode;
+               strcpy(entry->devpath, devpath);
+               list_add(&entry->entry, &g_smscore_registry);
+       } else
+               sms_err("failed to create smscore_registry.");
+       kmutex_unlock(&g_smscore_registrylock);
+       return entry;
+}
+
+int smscore_registry_getmode(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               return entry->mode;
+       else
+               sms_err("No registry found.");
+
+       return default_mode;
+}
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
+
+static enum sms_device_type_st smscore_registry_gettype(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               return entry->type;
+       else
+               sms_err("No registry found.");
+
+       return -1;
+}
+
+void smscore_registry_setmode(char *devpath, int mode)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               entry->mode = mode;
+       else
+               sms_err("No registry found.");
+}
+
+static void smscore_registry_settype(char *devpath,
+                                    enum sms_device_type_st type)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               entry->type = type;
+       else
+               sms_err("No registry found.");
+}
+
+
+static void list_add_locked(struct list_head *new, struct list_head *head,
+                           spinlock_t *lock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(lock, flags);
+
+       list_add(new, head);
+
+       spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * register a client callback that called when device plugged in/unplugged
+ * NOTE: if devices exist callback is called immediately for each device
+ *
+ * @param hotplug callback
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_hotplug(hotplug_t hotplug)
+{
+       struct smscore_device_notifyee_t *notifyee;
+       struct list_head *next, *first;
+       int rc = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
+                          GFP_KERNEL);
+       if (notifyee) {
+               /* now notify callback about existing devices */
+               first = &g_smscore_devices;
+               for (next = first->next;
+                    next != first && !rc;
+                    next = next->next) {
+                       struct smscore_device_t *coredev =
+                               (struct smscore_device_t *) next;
+                       rc = hotplug(coredev, coredev->device, 1);
+               }
+
+               if (rc >= 0) {
+                       notifyee->hotplug = hotplug;
+                       list_add(&notifyee->entry, &g_smscore_notifyees);
+               } else
+                       kfree(notifyee);
+       } else
+               rc = -ENOMEM;
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
+
+/**
+ * unregister a client callback that called when device plugged in/unplugged
+ *
+ * @param hotplug callback
+ *
+ */
+void smscore_unregister_hotplug(hotplug_t hotplug)
+{
+       struct list_head *next, *first;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       first = &g_smscore_notifyees;
+
+       for (next = first->next; next != first;) {
+               struct smscore_device_notifyee_t *notifyee =
+                       (struct smscore_device_notifyee_t *) next;
+               next = next->next;
+
+               if (notifyee->hotplug == hotplug) {
+                       list_del(&notifyee->entry);
+                       kfree(notifyee);
+               }
+       }
+
+       kmutex_unlock(&g_smscore_deviceslock);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
+
+static void smscore_notify_clients(struct smscore_device_t *coredev)
+{
+       struct smscore_client_t *client;
+
+       /* the client must call smscore_unregister_client from remove handler */
+       while (!list_empty(&coredev->clients)) {
+               client = (struct smscore_client_t *) coredev->clients.next;
+               client->onremove_handler(client->context);
+       }
+}
+
+static int smscore_notify_callbacks(struct smscore_device_t *coredev,
+                                   struct device *device, int arrival)
+{
+       struct smscore_device_notifyee_t *elem;
+       int rc = 0;
+
+       /* note: must be called under g_deviceslock */
+
+       list_for_each_entry(elem, &g_smscore_notifyees, entry) {
+               rc = elem->hotplug(coredev, device, arrival);
+               if (rc < 0)
+                       break;
+       }
+
+       return rc;
+}
+
+static struct
+smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
+                                      dma_addr_t common_buffer_phys)
+{
+       struct smscore_buffer_t *cb =
+               kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+       if (!cb) {
+               sms_info("kmalloc(...) failed");
+               return NULL;
+       }
+
+       cb->p = buffer;
+       cb->offset_in_common = buffer - (u8 *) common_buffer;
+       cb->phys = common_buffer_phys + cb->offset_in_common;
+
+       return cb;
+}
+
+/**
+ * creates coredev object for a device, prepares buffers,
+ * creates buffer mappings, notifies registered hotplugs about new device.
+ *
+ * @param params device pointer to struct with device specific parameters
+ *               and handlers
+ * @param coredev pointer to a value that receives created coredev object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_device(struct smsdevice_params_t *params,
+                           struct smscore_device_t **coredev)
+{
+       struct smscore_device_t *dev;
+       u8 *buffer;
+
+       dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
+       if (!dev) {
+               sms_info("kzalloc(...) failed");
+               return -ENOMEM;
+       }
+
+       /* init list entry so it could be safe in smscore_unregister_device */
+       INIT_LIST_HEAD(&dev->entry);
+
+       /* init queues */
+       INIT_LIST_HEAD(&dev->clients);
+       INIT_LIST_HEAD(&dev->buffers);
+
+       /* init locks */
+       spin_lock_init(&dev->clientslock);
+       spin_lock_init(&dev->bufferslock);
+
+       /* init completion events */
+       init_completion(&dev->version_ex_done);
+       init_completion(&dev->data_download_done);
+       init_completion(&dev->trigger_done);
+       init_completion(&dev->init_device_done);
+       init_completion(&dev->reload_start_done);
+       init_completion(&dev->resume_done);
+       init_completion(&dev->gpio_configuration_done);
+       init_completion(&dev->gpio_set_level_done);
+       init_completion(&dev->gpio_get_level_done);
+       init_completion(&dev->ir_init_done);
+
+       /* Buffer management */
+       init_waitqueue_head(&dev->buffer_mng_waitq);
+
+       /* alloc common buffer */
+       dev->common_buffer_size = params->buffer_size * params->num_buffers;
+       dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
+                                               &dev->common_buffer_phys,
+                                               GFP_KERNEL | GFP_DMA);
+       if (!dev->common_buffer) {
+               smscore_unregister_device(dev);
+               return -ENOMEM;
+       }
+
+       /* prepare dma buffers */
+       for (buffer = dev->common_buffer;
+            dev->num_buffers < params->num_buffers;
+            dev->num_buffers++, buffer += params->buffer_size) {
+               struct smscore_buffer_t *cb =
+                       smscore_createbuffer(buffer, dev->common_buffer,
+                                            dev->common_buffer_phys);
+               if (!cb) {
+                       smscore_unregister_device(dev);
+                       return -ENOMEM;
+               }
+
+               smscore_putbuffer(dev, cb);
+       }
+
+       sms_info("allocated %d buffers", dev->num_buffers);
+
+       dev->mode = DEVICE_MODE_NONE;
+       dev->context = params->context;
+       dev->device = params->device;
+       dev->setmode_handler = params->setmode_handler;
+       dev->detectmode_handler = params->detectmode_handler;
+       dev->sendrequest_handler = params->sendrequest_handler;
+       dev->preload_handler = params->preload_handler;
+       dev->postload_handler = params->postload_handler;
+
+       dev->device_flags = params->flags;
+       strcpy(dev->devpath, params->devpath);
+
+       smscore_registry_settype(dev->devpath, params->device_type);
+
+       /* add device to devices list */
+       kmutex_lock(&g_smscore_deviceslock);
+       list_add(&dev->entry, &g_smscore_devices);
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       *coredev = dev;
+
+       sms_info("device %p created", dev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(smscore_register_device);
+
+
+static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
+               void *buffer, size_t size, struct completion *completion) {
+       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
+       if (rc < 0) {
+               sms_info("sendrequest returned error %d", rc);
+               return rc;
+       }
+
+       return wait_for_completion_timeout(completion,
+                       msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
+                       0 : -ETIME;
+}
+
+/**
+ * Starts & enables IR operations
+ *
+ * @return 0 on success, < 0 on error.
+ */
+static int smscore_init_ir(struct smscore_device_t *coredev)
+{
+       int ir_io;
+       int rc;
+       void *buffer;
+
+       coredev->ir.dev = NULL;
+       ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
+       if (ir_io) {/* only if IR port exist we use IR sub-module */
+               sms_info("IR loading");
+               rc = sms_ir_init(coredev);
+
+               if      (rc != 0)
+                       sms_err("Error initialization DTV IR sub-module");
+               else {
+                       buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
+                                               SMS_DMA_ALIGNMENT,
+                                               GFP_KERNEL | GFP_DMA);
+                       if (buffer) {
+                               struct SmsMsgData_ST2 *msg =
+                               (struct SmsMsgData_ST2 *)
+                               SMS_ALIGN_ADDRESS(buffer);
+
+                               SMS_INIT_MSG(&msg->xMsgHeader,
+                                               MSG_SMS_START_IR_REQ,
+                                               sizeof(struct SmsMsgData_ST2));
+                               msg->msgData[0] = coredev->ir.controller;
+                               msg->msgData[1] = coredev->ir.timeout;
+
+                               smsendian_handle_tx_message(
+                                       (struct SmsMsgHdr_ST2 *)msg);
+                               rc = smscore_sendrequest_and_wait(coredev, msg,
+                                               msg->xMsgHeader. msgLength,
+                                               &coredev->ir_init_done);
+
+                               kfree(buffer);
+                       } else
+                               sms_err
+                               ("Sending IR initialization message failed");
+               }
+       } else
+               sms_info("IR port has not been detected");
+
+       return 0;
+}
+
+/**
+ * sets initial device mode and notifies client hotplugs that device is ready
+ *
+ * @param coredev pointer to a coredev object returned by
+ *               smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_start_device(struct smscore_device_t *coredev)
+{
+       int rc = smscore_set_device_mode(
+                       coredev, smscore_registry_getmode(coredev->devpath));
+       if (rc < 0) {
+               sms_info("set device mode faile , rc %d", rc);
+               return rc;
+       }
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
+       smscore_init_ir(coredev);
+
+       sms_info("device %p started, rc %d", coredev, rc);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(smscore_start_device);
+
+
+static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
+                                        void *buffer, size_t size)
+{
+       struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
+       struct SmsMsgHdr_ST *msg;
+       u32 mem_address;
+       u8 *payload = firmware->Payload;
+       int rc = 0;
+       firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
+       firmware->Length = le32_to_cpu(firmware->Length);
+
+       mem_address = firmware->StartAddress;
+
+       sms_info("loading FW to addr 0x%x size %d",
+                mem_address, firmware->Length);
+       if (coredev->preload_handler) {
+               rc = coredev->preload_handler(coredev->context);
+               if (rc < 0)
+                       return rc;
+       }
+
+       /* PAGE_SIZE buffer shall be enough and dma aligned */
+       msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+       if (!msg)
+               return -ENOMEM;
+
+       if (coredev->mode != DEVICE_MODE_NONE) {
+               sms_debug("sending reload command.");
+               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
+                            sizeof(struct SmsMsgHdr_ST));
+               rc = smscore_sendrequest_and_wait(coredev, msg,
+                                                 msg->msgLength,
+                                                 &coredev->reload_start_done);
+               mem_address = *(u32 *) &payload[20];
+       }
+
+       while (size && rc >= 0) {
+               struct SmsDataDownload_ST *DataMsg =
+                       (struct SmsDataDownload_ST *) msg;
+               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+
+               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
+                            (u16)(sizeof(struct SmsMsgHdr_ST) +
+                                     sizeof(u32) + payload_size));
+
+               DataMsg->MemAddr = mem_address;
+               memcpy(DataMsg->Payload, payload, payload_size);
+
+               if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
+                   (coredev->mode == DEVICE_MODE_NONE))
+                       rc = coredev->sendrequest_handler(
+                               coredev->context, DataMsg,
+                               DataMsg->xMsgHeader.msgLength);
+               else
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, DataMsg,
+                               DataMsg->xMsgHeader.msgLength,
+                               &coredev->data_download_done);
+
+               payload += payload_size;
+               size -= payload_size;
+               mem_address += payload_size;
+       }
+
+       if (rc >= 0) {
+               if (coredev->mode == DEVICE_MODE_NONE) {
+                       struct SmsMsgData_ST *TriggerMsg =
+                               (struct SmsMsgData_ST *) msg;
+
+                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+                                    sizeof(struct SmsMsgHdr_ST) +
+                                    sizeof(u32) * 5);
+
+                       TriggerMsg->msgData[0] = firmware->StartAddress;
+                                               /* Entry point */
+                       TriggerMsg->msgData[1] = 5; /* Priority */
+                       TriggerMsg->msgData[2] = 0x200; /* Stack size */
+                       TriggerMsg->msgData[3] = 0; /* Parameter */
+                       TriggerMsg->msgData[4] = 4; /* Task ID */
+
+                       if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
+                               rc = coredev->sendrequest_handler(
+                                       coredev->context, TriggerMsg,
+                                       TriggerMsg->xMsgHeader.msgLength);
+                               msleep(100);
+                       } else
+                               rc = smscore_sendrequest_and_wait(
+                                       coredev, TriggerMsg,
+                                       TriggerMsg->xMsgHeader.msgLength,
+                                       &coredev->trigger_done);
+               } else {
+                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
+                                    sizeof(struct SmsMsgHdr_ST));
+
+                       rc = coredev->sendrequest_handler(coredev->context,
+                                                         msg, msg->msgLength);
+               }
+               msleep(500);
+       }
+
+       sms_debug("rc=%d, postload=%p ", rc,
+                 coredev->postload_handler);
+
+       kfree(msg);
+
+       return ((rc >= 0) && coredev->postload_handler) ?
+               coredev->postload_handler(coredev->context) :
+               rc;
+}
+
+/**
+ * loads specified firmware into a buffer and calls device loadfirmware_handler
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param filename null-terminated string specifies firmware file name
+ * @param loadfirmware_handler device handler that loads firmware
+ *
+ * @return 0 on success, <0 on error.
+ */
+static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
+                                          char *filename,
+                                          loadfirmware_t loadfirmware_handler)
+{
+       int rc = -ENOENT;
+       const struct firmware *fw;
+       u8 *fw_buffer;
+
+       if (loadfirmware_handler == NULL && !(coredev->device_flags &
+                                             SMS_DEVICE_FAMILY2))
+               return -EINVAL;
+
+       rc = request_firmware(&fw, filename, coredev->device);
+       if (rc < 0) {
+               sms_info("failed to open \"%s\"", filename);
+               return rc;
+       }
+       sms_info("read FW %s, size=%zd", filename, fw->size);
+       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
+                           GFP_KERNEL | GFP_DMA);
+       if (fw_buffer) {
+               memcpy(fw_buffer, fw->data, fw->size);
+
+               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+                     smscore_load_firmware_family2(coredev,
+                                                   fw_buffer,
+                                                   fw->size) :
+                     loadfirmware_handler(coredev->context,
+                                          fw_buffer, fw->size);
+
+               kfree(fw_buffer);
+       } else {
+               sms_info("failed to allocate firmware buffer");
+               rc = -ENOMEM;
+       }
+
+       release_firmware(fw);
+
+       return rc;
+}
+
+/**
+ * notifies all clients registered with the device, notifies hotplugs,
+ * frees all buffers and coredev object
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+void smscore_unregister_device(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb;
+       int num_buffers = 0;
+       int retry = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       /* Release input device (IR) resources */
+       sms_ir_exit(coredev);
+
+       smscore_notify_clients(coredev);
+       smscore_notify_callbacks(coredev, NULL, 0);
+
+       /* at this point all buffers should be back
+        * onresponse must no longer be called */
+
+       while (1) {
+               while (!list_empty(&coredev->buffers)) {
+                       cb = (struct smscore_buffer_t *) coredev->buffers.next;
+                       list_del(&cb->entry);
+                       kfree(cb);
+                       num_buffers++;
+               }
+               if (num_buffers == coredev->num_buffers)
+                       break;
+               if (++retry > 10) {
+                       sms_info("exiting although "
+                                "not all buffers released.");
+                       break;
+               }
+
+               sms_info("waiting for %d buffer(s)",
+                        coredev->num_buffers - num_buffers);
+               msleep(100);
+       }
+
+       sms_info("freed %d buffers", num_buffers);
+
+       if (coredev->common_buffer)
+               dma_free_coherent(NULL, coredev->common_buffer_size,
+                       coredev->common_buffer, coredev->common_buffer_phys);
+
+       if (coredev->fw_buf != NULL)
+               kfree(coredev->fw_buf);
+
+       list_del(&coredev->entry);
+       kfree(coredev);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       sms_info("device %p destroyed", coredev);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
+
+static int smscore_detect_mode(struct smscore_device_t *coredev)
+{
+       void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
+                              GFP_KERNEL | GFP_DMA);
+       struct SmsMsgHdr_ST *msg =
+               (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+       int rc;
+
+       if (!buffer)
+               return -ENOMEM;
+
+       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
+                    sizeof(struct SmsMsgHdr_ST));
+
+       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
+                                         &coredev->version_ex_done);
+       if (rc == -ETIME) {
+               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
+
+               if (wait_for_completion_timeout(&coredev->resume_done,
+                                               msecs_to_jiffies(5000))) {
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, msg, msg->msgLength,
+                               &coredev->version_ex_done);
+                       if (rc < 0)
+                               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
+                                       "second try, rc %d", rc);
+               } else
+                       rc = -ETIME;
+       }
+
+       kfree(buffer);
+
+       return rc;
+}
+
+static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
+       /*Stellar               NOVA A0         Nova B0         VEGA*/
+       /*DVBT*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*DVBH*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*TDMB*/
+       {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
+       /*DABIP*/
+       {"none", "none", "none", "none"},
+       /*BDA*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*ISDBT*/
+       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
+       /*ISDBTBDA*/
+       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
+       /*CMMB*/
+       {"none", "none", "none", "cmmb_vega_12mhz.inp"}
+};
+
+static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
+                                   int mode, enum sms_device_type_st type)
+{
+       char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
+       return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
+}
+
+/**
+ * calls device handler to change mode of operation
+ * NOTE: stellar/usb may disconnect when changing mode
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param mode requested mode of operation
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
+{
+       void *buffer;
+       int rc = 0;
+       enum sms_device_type_st type;
+
+       sms_debug("set device mode to %d", mode);
+       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
+               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
+                       sms_err("invalid mode specified %d", mode);
+                       return -EINVAL;
+               }
+
+               smscore_registry_setmode(coredev->devpath, mode);
+
+               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
+                       rc = smscore_detect_mode(coredev);
+                       if (rc < 0) {
+                               sms_err("mode detect failed %d", rc);
+                               return rc;
+                       }
+               }
+
+               if (coredev->mode == mode) {
+                       sms_info("device mode %d already set", mode);
+                       return 0;
+               }
+
+               if (!(coredev->modes_supported & (1 << mode))) {
+                       char *fw_filename;
+
+                       type = smscore_registry_gettype(coredev->devpath);
+                       fw_filename = sms_get_fw_name(coredev, mode, type);
+
+                       rc = smscore_load_firmware_from_file(coredev,
+                                                            fw_filename, NULL);
+                       if (rc < 0) {
+                               sms_warn("error %d loading firmware: %s, "
+                                        "trying again with default firmware",
+                                        rc, fw_filename);
+
+                               /* try again with the default firmware */
+                               fw_filename = smscore_fw_lkup[mode][type];
+                               rc = smscore_load_firmware_from_file(coredev,
+                                                            fw_filename, NULL);
+
+                               if (rc < 0) {
+                                       sms_warn("error %d loading "
+                                                "firmware: %s", rc,
+                                                fw_filename);
+                                       return rc;
+                               }
+                       }
+                       sms_log("firmware download success: %s", fw_filename);
+               } else
+                       sms_info("mode %d supported by running "
+                                "firmware", mode);
+
+               buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
+                                SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+               if (buffer) {
+                       struct SmsMsgData_ST *msg =
+                               (struct SmsMsgData_ST *)
+                                       SMS_ALIGN_ADDRESS(buffer);
+
+                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
+                                    sizeof(struct SmsMsgData_ST));
+                       msg->msgData[0] = mode;
+
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, msg, msg->xMsgHeader.msgLength,
+                               &coredev->init_device_done);
+
+                       kfree(buffer);
+               } else {
+                       sms_err("Could not allocate buffer for "
+                               "init device message.");
+                       rc = -ENOMEM;
+               }
+       } else {
+               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+                       sms_err("invalid mode specified %d", mode);
+                       return -EINVAL;
+               }
+
+               smscore_registry_setmode(coredev->devpath, mode);
+
+               if (coredev->detectmode_handler)
+                       coredev->detectmode_handler(coredev->context,
+                                                   &coredev->mode);
+
+               if (coredev->mode != mode && coredev->setmode_handler)
+                       rc = coredev->setmode_handler(coredev->context, mode);
+       }
+
+       if (rc >= 0) {
+               coredev->mode = mode;
+               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
+       }
+
+       if (rc < 0)
+               sms_err("return error code %d.", rc);
+       return rc;
+}
+
+/**
+ * calls device handler to get current mode of operation
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return current mode
+ */
+int smscore_get_device_mode(struct smscore_device_t *coredev)
+{
+       return coredev->mode;
+}
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
+
+/**
+ * find client by response id & type within the clients list.
+ * return client handle or NULL.
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param data_type client data type (SMS_DONT_CARE for all types)
+ * @param id client id (SMS_DONT_CARE for all id)
+ *
+ */
+static struct
+smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
+                                     int data_type, int id)
+{
+       struct list_head *first;
+       struct smscore_client_t *client;
+       unsigned long flags;
+       struct list_head *firstid;
+       struct smscore_idlist_t *client_id;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+       first = &coredev->clients;
+       list_for_each_entry(client, first, entry) {
+               firstid = &client->idlist;
+               list_for_each_entry(client_id, firstid, entry) {
+                       if ((client_id->id == id) &&
+                           (client_id->data_type == data_type ||
+                           (client_id->data_type == 0)))
+                               goto found;
+               }
+       }
+       client = NULL;
+found:
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+       return client;
+}
+
+/**
+ * find client by response id/type, call clients onresponse handler
+ * return buffer to pool on error
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param cb pointer to response buffer descriptor
+ *
+ */
+void smscore_onresponse(struct smscore_device_t *coredev,
+               struct smscore_buffer_t *cb) {
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
+                       + cb->offset);
+       struct smscore_client_t *client;
+       int rc = -EBUSY;
+       static unsigned long last_sample_time; /* = 0; */
+       static int data_total; /* = 0; */
+       unsigned long time_now = jiffies_to_msecs(jiffies);
+
+       if (!last_sample_time)
+               last_sample_time = time_now;
+
+       if (time_now - last_sample_time > 10000) {
+               sms_debug("\ndata rate %d bytes/secs",
+                         (int)((data_total * 1000) /
+                               (time_now - last_sample_time)));
+
+               last_sample_time = time_now;
+               data_total = 0;
+       }
+
+       data_total += cb->size;
+       /* Do we need to re-route? */
+       if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
+                       (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
+               if (coredev->mode == DEVICE_MODE_DVBT_BDA)
+                       phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
+       }
+
+
+       client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
+
+       /* If no client registered for type & id,
+        * check for control client where type is not registered */
+       if (client)
+               rc = client->onresponse_handler(client->context, cb);
+
+       if (rc < 0) {
+               switch (phdr->msgType) {
+               case MSG_SMS_GET_VERSION_EX_RES:
+               {
+                       struct SmsVersionRes_ST *ver =
+                               (struct SmsVersionRes_ST *) phdr;
+                       sms_debug("MSG_SMS_GET_VERSION_EX_RES "
+                                 "id %d prots 0x%x ver %d.%d",
+                                 ver->FirmwareId, ver->SupportedProtocols,
+                                 ver->RomVersionMajor, ver->RomVersionMinor);
+
+                       coredev->mode = ver->FirmwareId == 255 ?
+                               DEVICE_MODE_NONE : ver->FirmwareId;
+                       coredev->modes_supported = ver->SupportedProtocols;
+
+                       complete(&coredev->version_ex_done);
+                       break;
+               }
+               case MSG_SMS_INIT_DEVICE_RES:
+                       sms_debug("MSG_SMS_INIT_DEVICE_RES");
+                       complete(&coredev->init_device_done);
+                       break;
+               case MSG_SW_RELOAD_START_RES:
+                       sms_debug("MSG_SW_RELOAD_START_RES");
+                       complete(&coredev->reload_start_done);
+                       break;
+               case MSG_SMS_DATA_DOWNLOAD_RES:
+                       complete(&coredev->data_download_done);
+                       break;
+               case MSG_SW_RELOAD_EXEC_RES:
+                       sms_debug("MSG_SW_RELOAD_EXEC_RES");
+                       break;
+               case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
+                       sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
+                       complete(&coredev->trigger_done);
+                       break;
+               case MSG_SMS_SLEEP_RESUME_COMP_IND:
+                       complete(&coredev->resume_done);
+                       break;
+               case MSG_SMS_GPIO_CONFIG_EX_RES:
+                       sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
+                       complete(&coredev->gpio_configuration_done);
+                       break;
+               case MSG_SMS_GPIO_SET_LEVEL_RES:
+                       sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
+                       complete(&coredev->gpio_set_level_done);
+                       break;
+               case MSG_SMS_GPIO_GET_LEVEL_RES:
+               {
+                       u32 *msgdata = (u32 *) phdr;
+                       coredev->gpio_get_res = msgdata[1];
+                       sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
+                                       coredev->gpio_get_res);
+                       complete(&coredev->gpio_get_level_done);
+                       break;
+               }
+               case MSG_SMS_START_IR_RES:
+                       complete(&coredev->ir_init_done);
+                       break;
+               case MSG_SMS_IR_SAMPLES_IND:
+                       sms_ir_event(coredev,
+                               (const char *)
+                               ((char *)phdr
+                               + sizeof(struct SmsMsgHdr_ST)),
+                               (int)phdr->msgLength
+                               - sizeof(struct SmsMsgHdr_ST));
+                       break;
+
+               default:
+                       break;
+               }
+               smscore_putbuffer(coredev, cb);
+       }
+}
+EXPORT_SYMBOL_GPL(smscore_onresponse);
+
+/**
+ * return pointer to next free buffer descriptor from core pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return pointer to descriptor on success, NULL on error.
+ */
+
+struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->bufferslock, flags);
+       if (!list_empty(&coredev->buffers)) {
+               cb = (struct smscore_buffer_t *) coredev->buffers.next;
+               list_del(&cb->entry);
+       }
+       spin_unlock_irqrestore(&coredev->bufferslock, flags);
+       return cb;
+}
+
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb = NULL;
+
+       wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
+
+       return cb;
+}
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
+
+/**
+ * return buffer descriptor to a pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param cb pointer buffer descriptor
+ *
+ */
+void smscore_putbuffer(struct smscore_device_t *coredev,
+               struct smscore_buffer_t *cb) {
+       wake_up_interruptible(&coredev->buffer_mng_waitq);
+       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
+}
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
+
+static int smscore_validate_client(struct smscore_device_t *coredev,
+                                  struct smscore_client_t *client,
+                                  int data_type, int id)
+{
+       struct smscore_idlist_t *listentry;
+       struct smscore_client_t *registered_client;
+
+       if (!client) {
+               sms_err("bad parameter.");
+               return -EINVAL;
+       }
+       registered_client = smscore_find_client(coredev, data_type, id);
+       if (registered_client == client)
+               return 0;
+
+       if (registered_client) {
+               sms_err("The msg ID already registered to another client.");
+               return -EEXIST;
+       }
+       listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
+       if (!listentry) {
+               sms_err("Can't allocate memory for client id.");
+               return -ENOMEM;
+       }
+       listentry->id = id;
+       listentry->data_type = data_type;
+       list_add_locked(&listentry->entry, &client->idlist,
+                       &coredev->clientslock);
+       return 0;
+}
+
+/**
+ * creates smsclient object, check that id is taken by another client
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ * @param initial_id all messages with this id would be sent to this client
+ * @param data_type all messages of this type would be sent to this client
+ * @param onresponse_handler client handler that is called to
+ *                           process incoming messages
+ * @param onremove_handler client handler that is called when device is removed
+ * @param context client-specific context
+ * @param client pointer to a value that receives created smsclient object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_client(struct smscore_device_t *coredev,
+                           struct smsclient_params_t *params,
+                           struct smscore_client_t **client)
+{
+       struct smscore_client_t *newclient;
+       /* check that no other channel with same parameters exists */
+       if (smscore_find_client(coredev, params->data_type,
+                               params->initial_id)) {
+               sms_err("Client already exist.");
+               return -EEXIST;
+       }
+
+       newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
+       if (!newclient) {
+               sms_err("Failed to allocate memory for client.");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&newclient->idlist);
+       newclient->coredev = coredev;
+       newclient->onresponse_handler = params->onresponse_handler;
+       newclient->onremove_handler = params->onremove_handler;
+       newclient->context = params->context;
+       list_add_locked(&newclient->entry, &coredev->clients,
+                       &coredev->clientslock);
+       smscore_validate_client(coredev, newclient, params->data_type,
+                               params->initial_id);
+       *client = newclient;
+       sms_debug("%p %d %d", params->context, params->data_type,
+                 params->initial_id);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(smscore_register_client);
+
+/**
+ * frees smsclient object and all subclients associated with it
+ *
+ * @param client pointer to smsclient object returned by
+ *               smscore_register_client
+ *
+ */
+void smscore_unregister_client(struct smscore_client_t *client)
+{
+       struct smscore_device_t *coredev = client->coredev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+
+
+       while (!list_empty(&client->idlist)) {
+               struct smscore_idlist_t *identry =
+                       (struct smscore_idlist_t *) client->idlist.next;
+               list_del(&identry->entry);
+               kfree(identry);
+       }
+
+       sms_info("%p", client->context);
+
+       list_del(&client->entry);
+       kfree(client);
+
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
+
+/**
+ * verifies that source id is not taken by another client,
+ * calls device handler to send requests to the device
+ *
+ * @param client pointer to smsclient object returned by
+ *               smscore_register_client
+ * @param buffer pointer to a request buffer
+ * @param size size (in bytes) of request buffer
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smsclient_sendrequest(struct smscore_client_t *client,
+                         void *buffer, size_t size)
+{
+       struct smscore_device_t *coredev;
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
+       int rc;
+
+       if (client == NULL) {
+               sms_err("Got NULL client");
+               return -EINVAL;
+       }
+
+       coredev = client->coredev;
+
+       /* check that no other channel with same id exists */
+       if (coredev == NULL) {
+               sms_err("Got NULL coredev");
+               return -EINVAL;
+       }
+
+       rc = smscore_validate_client(client->coredev, client, 0,
+                                    phdr->msgSrcId);
+       if (rc < 0)
+               return rc;
+
+       return coredev->sendrequest_handler(coredev->context, buffer, size);
+}
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
+
+
+/* old GPIO managements implementation */
+int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
+                          struct smscore_config_gpio *pinconfig)
+{
+       struct {
+               struct SmsMsgHdr_ST hdr;
+               u32 data[6];
+       } msg;
+
+       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
+               msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+               msg.hdr.msgDstId = HIF_TASK;
+               msg.hdr.msgFlags = 0;
+               msg.hdr.msgType  = MSG_SMS_GPIO_CONFIG_EX_REQ;
+               msg.hdr.msgLength = sizeof(msg);
+
+               msg.data[0] = pin;
+               msg.data[1] = pinconfig->pullupdown;
+
+               /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
+               msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
+
+               switch (pinconfig->outputdriving) {
+               case SMS_GPIO_OUTPUTDRIVING_16mA:
+                       msg.data[3] = 7; /* Nova - 16mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_12mA:
+                       msg.data[3] = 5; /* Nova - 11mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_8mA:
+                       msg.data[3] = 3; /* Nova - 7mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_4mA:
+               default:
+                       msg.data[3] = 2; /* Nova - 4mA */
+                       break;
+               }
+
+               msg.data[4] = pinconfig->direction;
+               msg.data[5] = 0;
+       } else /* TODO: SMS_DEVICE_FAMILY1 */
+               return -EINVAL;
+
+       return coredev->sendrequest_handler(coredev->context,
+                                           &msg, sizeof(msg));
+}
+
+int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
+{
+       struct {
+               struct SmsMsgHdr_ST hdr;
+               u32 data[3];
+       } msg;
+
+       if (pin > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       msg.hdr.msgDstId = HIF_TASK;
+       msg.hdr.msgFlags = 0;
+       msg.hdr.msgType  = MSG_SMS_GPIO_SET_LEVEL_REQ;
+       msg.hdr.msgLength = sizeof(msg);
+
+       msg.data[0] = pin;
+       msg.data[1] = level ? 1 : 0;
+       msg.data[2] = 0;
+
+       return coredev->sendrequest_handler(coredev->context,
+                                           &msg, sizeof(msg));
+}
+
+/* new GPIO management implementation */
+static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
+               u32 *pGroupNum, u32 *pGroupCfg) {
+
+       *pGroupCfg = 1;
+
+       if (PinNum <= 1)        {
+               *pTranslatedPinNum = 0;
+               *pGroupNum = 9;
+               *pGroupCfg = 2;
+       } else if (PinNum >= 2 && PinNum <= 6) {
+               *pTranslatedPinNum = 2;
+               *pGroupNum = 0;
+               *pGroupCfg = 2;
+       } else if (PinNum >= 7 && PinNum <= 11) {
+               *pTranslatedPinNum = 7;
+               *pGroupNum = 1;
+       } else if (PinNum >= 12 && PinNum <= 15) {
+               *pTranslatedPinNum = 12;
+               *pGroupNum = 2;
+               *pGroupCfg = 3;
+       } else if (PinNum == 16) {
+               *pTranslatedPinNum = 16;
+               *pGroupNum = 23;
+       } else if (PinNum >= 17 && PinNum <= 24) {
+               *pTranslatedPinNum = 17;
+               *pGroupNum = 3;
+       } else if (PinNum == 25) {
+               *pTranslatedPinNum = 25;
+               *pGroupNum = 6;
+       } else if (PinNum >= 26 && PinNum <= 28) {
+               *pTranslatedPinNum = 26;
+               *pGroupNum = 4;
+       } else if (PinNum == 29) {
+               *pTranslatedPinNum = 29;
+               *pGroupNum = 5;
+               *pGroupCfg = 2;
+       } else if (PinNum == 30) {
+               *pTranslatedPinNum = 30;
+               *pGroupNum = 8;
+       } else if (PinNum == 31) {
+               *pTranslatedPinNum = 31;
+               *pGroupNum = 17;
+       } else
+               return -1;
+
+       *pGroupCfg <<= 24;
+
+       return 0;
+}
+
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+               struct smscore_gpio_config *pGpioConfig) {
+
+       u32 totalLen;
+       u32 TranslatedPinNum = 0;
+       u32 GroupNum = 0;
+       u32 ElectricChar;
+       u32 groupCfg;
+       void *buffer;
+       int rc;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[6];
+       } *pMsg;
+
+
+       if (PinNum > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       if (pGpioConfig == NULL)
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+
+       if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
+               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
+               if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
+                               &groupCfg) != 0) {
+                       rc = -EINVAL;
+                       goto free;
+               }
+
+               pMsg->msgData[1] = TranslatedPinNum;
+               pMsg->msgData[2] = GroupNum;
+               ElectricChar = (pGpioConfig->PullUpDown)
+                               | (pGpioConfig->InputCharacteristics << 2)
+                               | (pGpioConfig->OutputSlewRate << 3)
+                               | (pGpioConfig->OutputDriving << 4);
+               pMsg->msgData[3] = ElectricChar;
+               pMsg->msgData[4] = pGpioConfig->Direction;
+               pMsg->msgData[5] = groupCfg;
+       } else {
+               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
+               pMsg->msgData[1] = pGpioConfig->PullUpDown;
+               pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
+               pMsg->msgData[3] = pGpioConfig->OutputDriving;
+               pMsg->msgData[4] = pGpioConfig->Direction;
+               pMsg->msgData[5] = 0;
+       }
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_configuration_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_configure timeout");
+               else
+                       sms_err("smscore_gpio_configure error");
+       }
+free:
+       kfree(buffer);
+
+       return rc;
+}
+
+int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 NewLevel) {
+
+       u32 totalLen;
+       int rc;
+       void *buffer;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[3]; /* keep it 3 ! */
+       } *pMsg;
+
+       if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) +
+                       (3 * sizeof(u32)); /* keep it 3 ! */
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+       pMsg->msgData[1] = NewLevel;
+
+       /* Send message to SMS */
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_set_level_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_set_level timeout");
+               else
+                       sms_err("smscore_gpio_set_level error");
+       }
+       kfree(buffer);
+
+       return rc;
+}
+
+int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 *level) {
+
+       u32 totalLen;
+       int rc;
+       void *buffer;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[2];
+       } *pMsg;
+
+
+       if (PinNum > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+       pMsg->msgData[1] = 0;
+
+       /* Send message to SMS */
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_get_level_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_get_level timeout");
+               else
+                       sms_err("smscore_gpio_get_level error");
+       }
+       kfree(buffer);
+
+       /* Its a race between other gpio_get_level() and the copy of the single
+        * global 'coredev->gpio_get_res' to  the function's variable 'level'
+        */
+       *level = coredev->gpio_get_res;
+
+       return rc;
+}
+
+static int __init smscore_module_init(void)
+{
+       int rc = 0;
+
+       INIT_LIST_HEAD(&g_smscore_notifyees);
+       INIT_LIST_HEAD(&g_smscore_devices);
+       kmutex_init(&g_smscore_deviceslock);
+
+       INIT_LIST_HEAD(&g_smscore_registry);
+       kmutex_init(&g_smscore_registrylock);
+
+       return rc;
+}
+
+static void __exit smscore_module_exit(void)
+{
+       kmutex_lock(&g_smscore_deviceslock);
+       while (!list_empty(&g_smscore_notifyees)) {
+               struct smscore_device_notifyee_t *notifyee =
+                       (struct smscore_device_notifyee_t *)
+                               g_smscore_notifyees.next;
+
+               list_del(&notifyee->entry);
+               kfree(notifyee);
+       }
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       kmutex_lock(&g_smscore_registrylock);
+       while (!list_empty(&g_smscore_registry)) {
+               struct smscore_registry_entry_t *entry =
+                       (struct smscore_registry_entry_t *)
+                               g_smscore_registry.next;
+
+               list_del(&entry->entry);
+               kfree(entry);
+       }
+       kmutex_unlock(&g_smscore_registrylock);
+
+       sms_debug("");
+}
+
+module_init(smscore_module_init);
+module_exit(smscore_module_exit);
+
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smscoreapi.h b/drivers/media/usb/siano/smscoreapi.h
new file mode 100644 (file)
index 0000000..c592ae0
--- /dev/null
@@ -0,0 +1,775 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
+
+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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_CORE_API_H__
+#define __SMS_CORE_API_H__
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+
+#include <asm/page.h>
+
+#include "smsir.h"
+
+#define kmutex_init(_p_) mutex_init(_p_)
+#define kmutex_lock(_p_) mutex_lock(_p_)
+#define kmutex_trylock(_p_) mutex_trylock(_p_)
+#define kmutex_unlock(_p_) mutex_unlock(_p_)
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS                 (10000)
+#define SMS_ALLOC_ALIGNMENT                            128
+#define SMS_DMA_ALIGNMENT                              16
+#define SMS_ALIGN_ADDRESS(addr) \
+       ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
+
+#define SMS_DEVICE_FAMILY2                             1
+#define SMS_ROM_NO_RESPONSE                            2
+#define SMS_DEVICE_NOT_READY                           0x8000000
+
+enum sms_device_type_st {
+       SMS_STELLAR = 0,
+       SMS_NOVA_A0,
+       SMS_NOVA_B0,
+       SMS_VEGA,
+       SMS_NUM_OF_DEVICE_TYPES
+};
+
+struct smscore_device_t;
+struct smscore_client_t;
+struct smscore_buffer_t;
+
+typedef int (*hotplug_t)(struct smscore_device_t *coredev,
+                        struct device *device, int arrival);
+
+typedef int (*setmode_t)(void *context, int mode);
+typedef void (*detectmode_t)(void *context, int *mode);
+typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
+typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
+typedef int (*preload_t)(void *context);
+typedef int (*postload_t)(void *context);
+
+typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
+typedef void (*onremove_t)(void *context);
+
+struct smscore_buffer_t {
+       /* public members, once passed to clients can be changed freely */
+       struct list_head entry;
+       int size;
+       int offset;
+
+       /* private members, read-only for clients */
+       void *p;
+       dma_addr_t phys;
+       unsigned long offset_in_common;
+};
+
+struct smsdevice_params_t {
+       struct device   *device;
+
+       int                             buffer_size;
+       int                             num_buffers;
+
+       char                    devpath[32];
+       unsigned long   flags;
+
+       setmode_t               setmode_handler;
+       detectmode_t    detectmode_handler;
+       sendrequest_t   sendrequest_handler;
+       preload_t               preload_handler;
+       postload_t              postload_handler;
+
+       void                    *context;
+       enum sms_device_type_st device_type;
+};
+
+struct smsclient_params_t {
+       int                             initial_id;
+       int                             data_type;
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+       void                    *context;
+};
+
+struct smscore_device_t {
+       struct list_head entry;
+
+       struct list_head clients;
+       struct list_head subclients;
+       spinlock_t clientslock;
+
+       struct list_head buffers;
+       spinlock_t bufferslock;
+       int num_buffers;
+
+       void *common_buffer;
+       int common_buffer_size;
+       dma_addr_t common_buffer_phys;
+
+       void *context;
+       struct device *device;
+
+       char devpath[32];
+       unsigned long device_flags;
+
+       setmode_t setmode_handler;
+       detectmode_t detectmode_handler;
+       sendrequest_t sendrequest_handler;
+       preload_t preload_handler;
+       postload_t postload_handler;
+
+       int mode, modes_supported;
+
+       /* host <--> device messages */
+       struct completion version_ex_done, data_download_done, trigger_done;
+       struct completion init_device_done, reload_start_done, resume_done;
+       struct completion gpio_configuration_done, gpio_set_level_done;
+       struct completion gpio_get_level_done, ir_init_done;
+
+       /* Buffer management */
+       wait_queue_head_t buffer_mng_waitq;
+
+       /* GPIO */
+       int gpio_get_res;
+
+       /* Target hardware board */
+       int board_id;
+
+       /* Firmware */
+       u8 *fw_buf;
+       u32 fw_buf_size;
+
+       /* Infrared (IR) */
+       struct ir_t ir;
+
+       int led_state;
+};
+
+/* GPIO definitions for antenna frequency domain control (SMS8021) */
+#define SMS_ANTENNA_GPIO_0                                     1
+#define SMS_ANTENNA_GPIO_1                                     0
+
+#define BW_8_MHZ                                                       0
+#define BW_7_MHZ                                                       1
+#define BW_6_MHZ                                                       2
+#define BW_5_MHZ                                                       3
+#define BW_ISDBT_1SEG                                          4
+#define BW_ISDBT_3SEG                                          5
+
+#define MSG_HDR_FLAG_SPLIT_MSG                         4
+
+#define MAX_GPIO_PIN_NUMBER                                    31
+
+#define HIF_TASK                                                       11
+#define SMS_HOST_LIB                                           150
+#define DVBT_BDA_CONTROL_MSG_ID                                201
+
+#define SMS_MAX_PAYLOAD_SIZE                           240
+#define SMS_TUNE_TIMEOUT                                       500
+
+#define MSG_SMS_GPIO_CONFIG_REQ                                507
+#define MSG_SMS_GPIO_CONFIG_RES                                508
+#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
+#define MSG_SMS_GPIO_SET_LEVEL_RES                     510
+#define MSG_SMS_GPIO_GET_LEVEL_REQ                     511
+#define MSG_SMS_GPIO_GET_LEVEL_RES                     512
+#define MSG_SMS_RF_TUNE_REQ                                    561
+#define MSG_SMS_RF_TUNE_RES                                    562
+#define MSG_SMS_INIT_DEVICE_REQ                                578
+#define MSG_SMS_INIT_DEVICE_RES                                579
+#define MSG_SMS_ADD_PID_FILTER_REQ                     601
+#define MSG_SMS_ADD_PID_FILTER_RES                     602
+#define MSG_SMS_REMOVE_PID_FILTER_REQ                  603
+#define MSG_SMS_REMOVE_PID_FILTER_RES                  604
+#define MSG_SMS_DAB_CHANNEL                            607
+#define MSG_SMS_GET_PID_FILTER_LIST_REQ                        608
+#define MSG_SMS_GET_PID_FILTER_LIST_RES                        609
+#define MSG_SMS_GET_STATISTICS_RES                     616
+#define MSG_SMS_GET_STATISTICS_REQ                     615
+#define MSG_SMS_HO_PER_SLICES_IND                      630
+#define MSG_SMS_SET_ANTENNA_CONFIG_REQ                 651
+#define MSG_SMS_SET_ANTENNA_CONFIG_RES                 652
+#define MSG_SMS_SLEEP_RESUME_COMP_IND                  655
+#define MSG_SMS_DATA_DOWNLOAD_REQ                      660
+#define MSG_SMS_DATA_DOWNLOAD_RES                      661
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ         664
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES         665
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ                666
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES                667
+#define MSG_SMS_GET_VERSION_EX_REQ                     668
+#define MSG_SMS_GET_VERSION_EX_RES                     669
+#define MSG_SMS_SET_CLOCK_OUTPUT_REQ           670
+#define MSG_SMS_I2C_SET_FREQ_REQ                       685
+#define MSG_SMS_GENERIC_I2C_REQ                                687
+#define MSG_SMS_GENERIC_I2C_RES                                688
+#define MSG_SMS_DVBT_BDA_DATA                          693
+#define MSG_SW_RELOAD_REQ                                      697
+#define MSG_SMS_DATA_MSG                                       699
+#define MSG_SW_RELOAD_START_REQ                                702
+#define MSG_SW_RELOAD_START_RES                                703
+#define MSG_SW_RELOAD_EXEC_REQ                         704
+#define MSG_SW_RELOAD_EXEC_RES                         705
+#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
+#define MSG_SMS_GPIO_CONFIG_EX_REQ                     712
+#define MSG_SMS_GPIO_CONFIG_EX_RES                     713
+#define MSG_SMS_ISDBT_TUNE_REQ                         776
+#define MSG_SMS_ISDBT_TUNE_RES                         777
+#define MSG_SMS_TRANSMISSION_IND                       782
+#define MSG_SMS_START_IR_REQ                           800
+#define MSG_SMS_START_IR_RES                           801
+#define MSG_SMS_IR_SAMPLES_IND                         802
+#define MSG_SMS_SIGNAL_DETECTED_IND                    827
+#define MSG_SMS_NO_SIGNAL_IND                          828
+
+#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
+       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
+       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
+} while (0)
+
+#define SMS_INIT_MSG(ptr, type, len) \
+       SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
+
+enum SMS_DVB3_EVENTS {
+       DVB3_EVENT_INIT = 0,
+       DVB3_EVENT_SLEEP,
+       DVB3_EVENT_HOTPLUG,
+       DVB3_EVENT_FE_LOCK,
+       DVB3_EVENT_FE_UNLOCK,
+       DVB3_EVENT_UNC_OK,
+       DVB3_EVENT_UNC_ERR
+};
+
+enum SMS_DEVICE_MODE {
+       DEVICE_MODE_NONE = -1,
+       DEVICE_MODE_DVBT = 0,
+       DEVICE_MODE_DVBH,
+       DEVICE_MODE_DAB_TDMB,
+       DEVICE_MODE_DAB_TDMB_DABIP,
+       DEVICE_MODE_DVBT_BDA,
+       DEVICE_MODE_ISDBT,
+       DEVICE_MODE_ISDBT_BDA,
+       DEVICE_MODE_CMMB,
+       DEVICE_MODE_RAW_TUNER,
+       DEVICE_MODE_MAX,
+};
+
+struct SmsMsgHdr_ST {
+       u16     msgType;
+       u8      msgSrcId;
+       u8      msgDstId;
+       u16     msgLength; /* Length of entire message, including header */
+       u16     msgFlags;
+};
+
+struct SmsMsgData_ST {
+       struct SmsMsgHdr_ST xMsgHeader;
+       u32 msgData[1];
+};
+
+struct SmsMsgData_ST2 {
+       struct SmsMsgHdr_ST xMsgHeader;
+       u32 msgData[2];
+};
+
+struct SmsDataDownload_ST {
+       struct SmsMsgHdr_ST     xMsgHeader;
+       u32                     MemAddr;
+       u8                      Payload[SMS_MAX_PAYLOAD_SIZE];
+};
+
+struct SmsVersionRes_ST {
+       struct SmsMsgHdr_ST     xMsgHeader;
+
+       u16             ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
+       u8              Step; /* 0 - Step A */
+       u8              MetalFix; /* 0 - Metal 0 */
+
+       /* FirmwareId 0xFF if ROM, otherwise the
+        * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
+       u8 FirmwareId;
+       /* SupportedProtocols Bitwise OR combination of
+                                            * supported protocols */
+       u8 SupportedProtocols;
+
+       u8              VersionMajor;
+       u8              VersionMinor;
+       u8              VersionPatch;
+       u8              VersionFieldPatch;
+
+       u8              RomVersionMajor;
+       u8              RomVersionMinor;
+       u8              RomVersionPatch;
+       u8              RomVersionFieldPatch;
+
+       u8              TextLabel[34];
+};
+
+struct SmsFirmware_ST {
+       u32                     CheckSum;
+       u32                     Length;
+       u32                     StartAddress;
+       u8                      Payload[1];
+};
+
+/* Statistics information returned as response for
+ * SmsHostApiGetStatistics_Req */
+struct SMSHOSTLIB_STATISTICS_ST {
+       u32 Reserved;           /* Reserved */
+
+       /* Common parameters */
+       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
+
+       /* Reception quality */
+       s32 SNR;                /* dB */
+       u32 BER;                /* Post Viterbi BER [1E-5] */
+       u32 FIB_CRC;            /* CRC errors percentage, valid only for DAB */
+       u32 TS_PER;             /* Transport stream PER,
+       0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
+       u32 MFER;               /* DVB-H frame error rate in percentage,
+       0xFFFFFFFF indicate N/A, valid only for DVB-H */
+       s32 RSSI;               /* dBm */
+       s32 InBandPwr;          /* In band power in dBM */
+       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
+
+       /* Transmission parameters */
+       u32 Frequency;          /* Frequency in Hz */
+       u32 Bandwidth;          /* Bandwidth in MHz, valid only for DVB-T/H */
+       u32 TransmissionMode;   /* Transmission Mode, for DAB modes 1-4,
+       for DVB-T/H FFT mode carriers in Kilos */
+       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
+       valid only for DVB-T/H */
+       u32 GuardInterval;      /* Guard Interval from
+       SMSHOSTLIB_GUARD_INTERVALS_ET,  valid only for DVB-T/H */
+       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+       valid only for DVB-T/H */
+       u32 LPCodeRate;         /* Low Priority Code Rate from
+       SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
+       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
+       valid only for DVB-T/H */
+       u32 Constellation;      /* Constellation from
+       SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
+
+       /* Burst parameters, valid only for DVB-H */
+       u32 BurstSize;          /* Current burst size in bytes,
+       valid only for DVB-H */
+       u32 BurstDuration;      /* Current burst duration in mSec,
+       valid only for DVB-H */
+       u32 BurstCycleTime;     /* Current burst cycle time in mSec,
+       valid only for DVB-H */
+       u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
+       as calculated by demodulator, valid only for DVB-H */
+       u32 NumOfRows;          /* Number of rows in MPE table,
+       valid only for DVB-H */
+       u32 NumOfPaddCols;      /* Number of padding columns in MPE table,
+       valid only for DVB-H */
+       u32 NumOfPunctCols;     /* Number of puncturing columns in MPE table,
+       valid only for DVB-H */
+       u32 ErrorTSPackets;     /* Number of erroneous
+       transport-stream packets */
+       u32 TotalTSPackets;     /* Total number of transport-stream packets */
+       u32 NumOfValidMpeTlbs;  /* Number of MPE tables which do not include
+       errors after MPE RS decoding */
+       u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
+       after MPE RS decoding */
+       u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
+       corrected by MPE RS decoding */
+       /* Common params */
+       u32 BERErrorCount;      /* Number of errornous SYNC bits. */
+       u32 BERBitCount;        /* Total number of SYNC bits. */
+
+       /* Interface information */
+       u32 SmsToHostTxErrors;  /* Total number of transmission errors. */
+
+       /* DAB/T-DMB */
+       u32 PreBER;             /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
+
+       /* DVB-H TPS parameters */
+       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+        if set to 0xFFFFFFFF cell_id not yet recovered */
+       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
+       Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
+       Time Slicing indicator, bit 0 - MPE-FEC indicator */
+
+       u32 NumMPEReceived;     /* DVB-H, Num MPE section received */
+
+       u32 ReservedFields[10]; /* Reserved */
+};
+
+struct SmsMsgStatisticsInfo_ST {
+       u32 RequestResult;
+
+       struct SMSHOSTLIB_STATISTICS_ST Stat;
+
+       /* Split the calc of the SNR in DAB */
+       u32 Signal; /* dB */
+       u32 Noise; /* dB */
+
+};
+
+struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
+       /* Per-layer information */
+       u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+                      * 255 means layer does not exist */
+       u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
+                           * 255 means layer does not exist */
+       u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 BERErrorCount; /* Post Viterbi Error Bits Count */
+       u32 BERBitCount; /* Post Viterbi Total Bits Count */
+       u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
+       u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
+       u32 TotalTSPackets; /* Total number of transport-stream packets */
+       u32 TILdepthI; /* Time interleaver depth I parameter,
+                       * 255 means layer does not exist */
+       u32 NumberOfSegments; /* Number of segments in layer A,
+                              * 255 means layer does not exist */
+       u32 TMCCErrors; /* TMCC errors */
+};
+
+struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
+       u32 StatisticsType; /* Enumerator identifying the type of the
+                               * structure.  Values are the same as
+                               * SMSHOSTLIB_DEVICE_MODES_E
+                               *
+                               * This field MUST always be first in any
+                               * statistics structure */
+
+       u32 FullSize; /* Total size of the structure returned by the modem.
+                      * If the size requested by the host is smaller than
+                      * FullSize, the struct will be truncated */
+
+       /* Common parameters */
+       u32 IsRfLocked; /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+
+       /* Reception quality */
+       s32  SNR; /* dB */
+       s32  RSSI; /* dBm */
+       s32  InBandPwr; /* In band power in dBM */
+       s32  CarrierOffset; /* Carrier Offset in Hz */
+
+       /* Transmission parameters */
+       u32 Frequency; /* Frequency in Hz */
+       u32 Bandwidth; /* Bandwidth in MHz */
+       u32 TransmissionMode; /* ISDB-T transmission mode */
+       u32 ModemState; /* 0 - Acquisition, 1 - Locked */
+       u32 GuardInterval; /* Guard Interval, 1 divided by value */
+       u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+       u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
+       u32 NumOfLayers; /* Number of ISDB-T layers in the network */
+
+       /* Per-layer information */
+       /* Layers A, B and C */
+       struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST   LayerInfo[3];
+       /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
+
+       /* Interface information */
+       u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+};
+
+struct PID_STATISTICS_DATA_S {
+       struct PID_BURST_S {
+               u32 size;
+               u32 padding_cols;
+               u32 punct_cols;
+               u32 duration;
+               u32 cycle;
+               u32 calc_cycle;
+       } burst;
+
+       u32 tot_tbl_cnt;
+       u32 invalid_tbl_cnt;
+       u32 tot_cor_tbl;
+};
+
+struct PID_DATA_S {
+       u32 pid;
+       u32 num_rows;
+       struct PID_STATISTICS_DATA_S pid_statistics;
+};
+
+#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
+#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
+#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
+       if (_stat.TransmissionMode == 0) \
+               _stat.TransmissionMode = 2; \
+       else if (_stat.TransmissionMode == 1) \
+               _stat.TransmissionMode = 8; \
+               else \
+                       _stat.TransmissionMode = 4;
+
+struct TRANSMISSION_STATISTICS_S {
+       u32 Frequency;          /* Frequency in Hz */
+       u32 Bandwidth;          /* Bandwidth in MHz */
+       u32 TransmissionMode;   /* FFT mode carriers in Kilos */
+       u32 GuardInterval;      /* Guard Interval from
+       SMSHOSTLIB_GUARD_INTERVALS_ET */
+       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
+       u32 LPCodeRate;         /* Low Priority Code Rate from
+       SMSHOSTLIB_CODE_RATE_ET */
+       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
+       u32 Constellation;      /* Constellation from
+       SMSHOSTLIB_CONSTELLATION_ET */
+
+       /* DVB-H TPS parameters */
+       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+        if set to 0xFFFFFFFF cell_id not yet recovered */
+       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
+        Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
+        Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+};
+
+struct RECEPTION_STATISTICS_S {
+       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
+
+       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
+       s32 SNR;                /* dB */
+       u32 BER;                /* Post Viterbi BER [1E-5] */
+       u32 BERErrorCount;      /* Number of erronous SYNC bits. */
+       u32 BERBitCount;        /* Total number of SYNC bits. */
+       u32 TS_PER;             /* Transport stream PER,
+       0xFFFFFFFF indicate N/A */
+       u32 MFER;               /* DVB-H frame error rate in percentage,
+       0xFFFFFFFF indicate N/A, valid only for DVB-H */
+       s32 RSSI;               /* dBm */
+       s32 InBandPwr;          /* In band power in dBM */
+       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
+       u32 ErrorTSPackets;     /* Number of erroneous
+       transport-stream packets */
+       u32 TotalTSPackets;     /* Total number of transport-stream packets */
+
+       s32 MRC_SNR;            /* dB */
+       s32 MRC_RSSI;           /* dBm */
+       s32 MRC_InBandPwr;      /* In band power in dBM */
+};
+
+
+/* Statistics information returned as response for
+ * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
+struct SMSHOSTLIB_STATISTICS_DVB_S {
+       /* Reception */
+       struct RECEPTION_STATISTICS_S ReceptionData;
+
+       /* Transmission parameters */
+       struct TRANSMISSION_STATISTICS_S TransmissionData;
+
+       /* Burst parameters, valid only for DVB-H */
+#define        SRVM_MAX_PID_FILTERS 8
+       struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
+};
+
+struct SRVM_SIGNAL_STATUS_S {
+       u32 result;
+       u32 snr;
+       u32 tsPackets;
+       u32 etsPackets;
+       u32 constellation;
+       u32 hpCode;
+       u32 tpsSrvIndLP;
+       u32 tpsSrvIndHP;
+       u32 cellId;
+       u32 reason;
+
+       s32 inBandPower;
+       u32 requestId;
+};
+
+struct SMSHOSTLIB_I2C_REQ_ST {
+       u32     DeviceAddress; /* I2c device address */
+       u32     WriteCount; /* number of bytes to write */
+       u32     ReadCount; /* number of bytes to read */
+       u8      Data[1];
+};
+
+struct SMSHOSTLIB_I2C_RES_ST {
+       u32     Status; /* non-zero value in case of failure */
+       u32     ReadCount; /* number of bytes read */
+       u8      Data[1];
+};
+
+
+struct smscore_config_gpio {
+#define SMS_GPIO_DIRECTION_INPUT  0
+#define SMS_GPIO_DIRECTION_OUTPUT 1
+       u8 direction;
+
+#define SMS_GPIO_PULLUPDOWN_NONE     0
+#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
+#define SMS_GPIO_PULLUPDOWN_PULLUP   2
+#define SMS_GPIO_PULLUPDOWN_KEEPER   3
+       u8 pullupdown;
+
+#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL  0
+#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
+       u8 inputcharacteristics;
+
+#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
+#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
+       u8 outputslewrate;
+
+#define SMS_GPIO_OUTPUTDRIVING_4mA  0
+#define SMS_GPIO_OUTPUTDRIVING_8mA  1
+#define SMS_GPIO_OUTPUTDRIVING_12mA 2
+#define SMS_GPIO_OUTPUTDRIVING_16mA 3
+       u8 outputdriving;
+};
+
+struct smscore_gpio_config {
+#define SMS_GPIO_DIRECTION_INPUT  0
+#define SMS_GPIO_DIRECTION_OUTPUT 1
+       u8 Direction;
+
+#define SMS_GPIO_PULL_UP_DOWN_NONE     0
+#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
+#define SMS_GPIO_PULL_UP_DOWN_PULLUP   2
+#define SMS_GPIO_PULL_UP_DOWN_KEEPER   3
+       u8 PullUpDown;
+
+#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL  0
+#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
+       u8 InputCharacteristics;
+
+#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW         1 /* 10xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST         0 /* 10xx */
+
+
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS    0 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS     1 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS     2 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS     3 /* 11xx */
+       u8 OutputSlewRate;
+
+#define SMS_GPIO_OUTPUT_DRIVING_S_4mA          0 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_8mA          1 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_12mA         2 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_16mA         3 /* 10xx */
+
+#define SMS_GPIO_OUTPUT_DRIVING_1_5mA          0 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_2_8mA          1 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_4mA            2 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_7mA            3 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_10mA           4 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_11mA           5 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_14mA           6 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_16mA           7 /* 11xx */
+       u8 OutputDriving;
+};
+
+extern void smscore_registry_setmode(char *devpath, int mode);
+extern int smscore_registry_getmode(char *devpath);
+
+extern int smscore_register_hotplug(hotplug_t hotplug);
+extern void smscore_unregister_hotplug(hotplug_t hotplug);
+
+extern int smscore_register_device(struct smsdevice_params_t *params,
+                                  struct smscore_device_t **coredev);
+extern void smscore_unregister_device(struct smscore_device_t *coredev);
+
+extern int smscore_start_device(struct smscore_device_t *coredev);
+extern int smscore_load_firmware(struct smscore_device_t *coredev,
+                                char *filename,
+                                loadfirmware_t loadfirmware_handler);
+
+extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
+extern int smscore_get_device_mode(struct smscore_device_t *coredev);
+
+extern int smscore_register_client(struct smscore_device_t *coredev,
+                                   struct smsclient_params_t *params,
+                                   struct smscore_client_t **client);
+extern void smscore_unregister_client(struct smscore_client_t *client);
+
+extern int smsclient_sendrequest(struct smscore_client_t *client,
+                                void *buffer, size_t size);
+extern void smscore_onresponse(struct smscore_device_t *coredev,
+                              struct smscore_buffer_t *cb);
+
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+                                     struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+                                  int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+                               u8 *ufwbuf, int size);
+
+extern
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
+extern void smscore_putbuffer(struct smscore_device_t *coredev,
+                             struct smscore_buffer_t *cb);
+
+/* old GPIO management */
+int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
+                          struct smscore_config_gpio *pinconfig);
+int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
+
+/* new GPIO management */
+extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+               struct smscore_gpio_config *pGpioConfig);
+extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 NewLevel);
+extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 *level);
+
+void smscore_set_board_id(struct smscore_device_t *core, int id);
+int smscore_get_board_id(struct smscore_device_t *core);
+
+int smscore_led_state(struct smscore_device_t *core, int led);
+
+
+/* ------------------------------------------------------------------------ */
+
+#define DBG_INFO 1
+#define DBG_ADV  2
+
+#define sms_printk(kern, fmt, arg...) \
+       printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define dprintk(kern, lvl, fmt, arg...) do {\
+       if (sms_dbg & lvl) \
+               sms_printk(kern, fmt, ##arg); } while (0)
+
+#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
+#define sms_err(fmt, arg...) \
+       sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
+#define sms_warn(fmt, arg...)  sms_printk(KERN_WARNING, fmt, ##arg)
+#define sms_info(fmt, arg...) \
+       dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
+#define sms_debug(fmt, arg...) \
+       dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
+
+
+#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/usb/siano/smsdvb.c b/drivers/media/usb/siano/smsdvb.c
new file mode 100644 (file)
index 0000000..aa77e54
--- /dev/null
@@ -0,0 +1,1078 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik
+
+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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include "smscoreapi.h"
+#include "smsendian.h"
+#include "sms-cards.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct smsdvb_client_t {
+       struct list_head entry;
+
+       struct smscore_device_t *coredev;
+       struct smscore_client_t *smsclient;
+
+       struct dvb_adapter      adapter;
+       struct dvb_demux        demux;
+       struct dmxdev           dmxdev;
+       struct dvb_frontend     frontend;
+
+       fe_status_t             fe_status;
+
+       struct completion       tune_done;
+
+       struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
+       int event_fe_state;
+       int event_unc_state;
+};
+
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+/* Events that may come from DVB v3 adapter */
+static void sms_board_dvb3_event(struct smsdvb_client_t *client,
+               enum SMS_DVB3_EVENTS event) {
+
+       struct smscore_device_t *coredev = client->coredev;
+       switch (event) {
+       case DVB3_EVENT_INIT:
+               sms_debug("DVB3_EVENT_INIT");
+               sms_board_event(coredev, BOARD_EVENT_BIND);
+               break;
+       case DVB3_EVENT_SLEEP:
+               sms_debug("DVB3_EVENT_SLEEP");
+               sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
+               break;
+       case DVB3_EVENT_HOTPLUG:
+               sms_debug("DVB3_EVENT_HOTPLUG");
+               sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
+               break;
+       case DVB3_EVENT_FE_LOCK:
+               if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
+                       client->event_fe_state = DVB3_EVENT_FE_LOCK;
+                       sms_debug("DVB3_EVENT_FE_LOCK");
+                       sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
+               }
+               break;
+       case DVB3_EVENT_FE_UNLOCK:
+               if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
+                       client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
+                       sms_debug("DVB3_EVENT_FE_UNLOCK");
+                       sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
+               }
+               break;
+       case DVB3_EVENT_UNC_OK:
+               if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
+                       client->event_unc_state = DVB3_EVENT_UNC_OK;
+                       sms_debug("DVB3_EVENT_UNC_OK");
+                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
+               }
+               break;
+       case DVB3_EVENT_UNC_ERR:
+               if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
+                       client->event_unc_state = DVB3_EVENT_UNC_ERR;
+                       sms_debug("DVB3_EVENT_UNC_ERR");
+                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
+               }
+               break;
+
+       default:
+               sms_err("Unknown dvb3 api event");
+               break;
+       }
+}
+
+
+static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                  struct SMSHOSTLIB_STATISTICS_ST *p)
+{
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "Reserved = %d", p->Reserved);
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "BER = %d", p->BER);
+               printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
+               printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
+               printk(KERN_DEBUG "MFER = %d", p->MFER);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
+               printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
+               printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
+               printk(KERN_DEBUG "Constellation = %d", p->Constellation);
+               printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
+               printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
+               printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
+               printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
+               printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
+               printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
+               printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
+               printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
+               printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
+               printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
+               printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
+               printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
+               printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
+               printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+               printk(KERN_DEBUG "PreBER = %d", p->PreBER);
+               printk(KERN_DEBUG "CellId = %d", p->CellId);
+               printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
+               printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
+               printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->BER = p->BER;
+       pReceptionData->BERErrorCount = p->BERErrorCount;
+       pReceptionData->InBandPwr = p->InBandPwr;
+       pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
+};
+
+
+static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                   struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
+{
+       int i;
+
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "SystemType = %d", p->SystemType);
+               printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
+               printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+
+               for (i = 0; i < 3; i++) {
+                       printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
+                       printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
+                       printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
+                       printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
+                       printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
+                       printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
+                       printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
+                       printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
+                       printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
+                       printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
+                       printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
+                       printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
+               }
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->InBandPwr = p->InBandPwr;
+
+       pReceptionData->ErrorTSPackets = 0;
+       pReceptionData->BER = 0;
+       pReceptionData->BERErrorCount = 0;
+       for (i = 0; i < 3; i++) {
+               pReceptionData->BER += p->LayerInfo[i].BER;
+               pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
+               pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
+       }
+}
+
+static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
+{
+       struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
+                       + cb->offset);
+       u32 *pMsgData = (u32 *) phdr + 1;
+       /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
+       bool is_status_update = false;
+
+       smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
+
+       switch (phdr->msgType) {
+       case MSG_SMS_DVBT_BDA_DATA:
+               dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
+                                cb->size - sizeof(struct SmsMsgHdr_ST));
+               break;
+
+       case MSG_SMS_RF_TUNE_RES:
+       case MSG_SMS_ISDBT_TUNE_RES:
+               complete(&client->tune_done);
+               break;
+
+       case MSG_SMS_SIGNAL_DETECTED_IND:
+               sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
+               client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
+               is_status_update = true;
+               break;
+
+       case MSG_SMS_NO_SIGNAL_IND:
+               sms_info("MSG_SMS_NO_SIGNAL_IND");
+               client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
+               is_status_update = true;
+               break;
+
+       case MSG_SMS_TRANSMISSION_IND: {
+               sms_info("MSG_SMS_TRANSMISSION_IND");
+
+               pMsgData++;
+               memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
+                               sizeof(struct TRANSMISSION_STATISTICS_S));
+
+               /* Mo need to correct guard interval
+                * (as opposed to old statistics message).
+                */
+               CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
+               CORRECT_STAT_TRANSMISSON_MODE(
+                               client->sms_stat_dvb.TransmissionData);
+               is_status_update = true;
+               break;
+       }
+       case MSG_SMS_HO_PER_SLICES_IND: {
+               struct RECEPTION_STATISTICS_S *pReceptionData =
+                               &client->sms_stat_dvb.ReceptionData;
+               struct SRVM_SIGNAL_STATUS_S SignalStatusData;
+
+               /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
+               pMsgData++;
+               SignalStatusData.result = pMsgData[0];
+               SignalStatusData.snr = pMsgData[1];
+               SignalStatusData.inBandPower = (s32) pMsgData[2];
+               SignalStatusData.tsPackets = pMsgData[3];
+               SignalStatusData.etsPackets = pMsgData[4];
+               SignalStatusData.constellation = pMsgData[5];
+               SignalStatusData.hpCode = pMsgData[6];
+               SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
+               SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
+               SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
+               SignalStatusData.reason = pMsgData[10];
+               SignalStatusData.requestId = pMsgData[11];
+               pReceptionData->IsRfLocked = pMsgData[16];
+               pReceptionData->IsDemodLocked = pMsgData[17];
+               pReceptionData->ModemState = pMsgData[12];
+               pReceptionData->SNR = pMsgData[1];
+               pReceptionData->BER = pMsgData[13];
+               pReceptionData->RSSI = pMsgData[14];
+               CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
+
+               pReceptionData->InBandPwr = (s32) pMsgData[2];
+               pReceptionData->CarrierOffset = (s32) pMsgData[15];
+               pReceptionData->TotalTSPackets = pMsgData[3];
+               pReceptionData->ErrorTSPackets = pMsgData[4];
+
+               /* TS PER */
+               if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
+                               > 0) {
+                       pReceptionData->TS_PER = (SignalStatusData.etsPackets
+                                       * 100) / (SignalStatusData.tsPackets
+                                       + SignalStatusData.etsPackets);
+               } else {
+                       pReceptionData->TS_PER = 0;
+               }
+
+               pReceptionData->BERBitCount = pMsgData[18];
+               pReceptionData->BERErrorCount = pMsgData[19];
+
+               pReceptionData->MRC_SNR = pMsgData[20];
+               pReceptionData->MRC_InBandPwr = pMsgData[21];
+               pReceptionData->MRC_RSSI = pMsgData[22];
+
+               is_status_update = true;
+               break;
+       }
+       case MSG_SMS_GET_STATISTICS_RES: {
+               union {
+                       struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
+                       struct SmsMsgStatisticsInfo_ST         dvb;
+               } *p = (void *) (phdr + 1);
+               struct RECEPTION_STATISTICS_S *pReceptionData =
+                               &client->sms_stat_dvb.ReceptionData;
+
+               sms_info("MSG_SMS_GET_STATISTICS_RES");
+
+               is_status_update = true;
+
+               switch (smscore_get_device_mode(client->coredev)) {
+               case DEVICE_MODE_ISDBT:
+               case DEVICE_MODE_ISDBT_BDA:
+                       smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
+                       break;
+               default:
+                       smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
+               }
+               if (!pReceptionData->IsDemodLocked) {
+                       pReceptionData->SNR = 0;
+                       pReceptionData->BER = 0;
+                       pReceptionData->BERErrorCount = 0;
+                       pReceptionData->InBandPwr = 0;
+                       pReceptionData->ErrorTSPackets = 0;
+               }
+
+               complete(&client->tune_done);
+               break;
+       }
+       default:
+               sms_info("Unhandled message %d", phdr->msgType);
+
+       }
+       smscore_putbuffer(client->coredev, cb);
+
+       if (is_status_update) {
+               if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
+                       client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
+                               | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+                       sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
+                       if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
+                                       == 0)
+                               sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
+                       else
+                               sms_board_dvb3_event(client,
+                                               DVB3_EVENT_UNC_ERR);
+
+               } else {
+                       if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
+                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+                       else
+                               client->fe_status = 0;
+                       sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
+               }
+       }
+
+       return 0;
+}
+
+static void smsdvb_unregister_client(struct smsdvb_client_t *client)
+{
+       /* must be called under clientslock */
+
+       list_del(&client->entry);
+
+       smscore_unregister_client(client->smsclient);
+       dvb_unregister_frontend(&client->frontend);
+       dvb_dmxdev_release(&client->dmxdev);
+       dvb_dmx_release(&client->demux);
+       dvb_unregister_adapter(&client->adapter);
+       kfree(client);
+}
+
+static void smsdvb_onremove(void *context)
+{
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       smsdvb_unregister_client((struct smsdvb_client_t *) context);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+static int smsdvb_start_feed(struct dvb_demux_feed *feed)
+{
+       struct smsdvb_client_t *client =
+               container_of(feed->demux, struct smsdvb_client_t, demux);
+       struct SmsMsgData_ST PidMsg;
+
+       sms_debug("add pid %d(%x)",
+                 feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
+       return smsclient_sendrequest(client->smsclient,
+                                    &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct smsdvb_client_t *client =
+               container_of(feed->demux, struct smsdvb_client_t, demux);
+       struct SmsMsgData_ST PidMsg;
+
+       sms_debug("remove pid %d(%x)",
+                 feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
+       return smsclient_sendrequest(client->smsclient,
+                                    &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
+                                       void *buffer, size_t size,
+                                       struct completion *completion)
+{
+       int rc;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
+       rc = smsclient_sendrequest(client->smsclient, buffer, size);
+       if (rc < 0)
+               return rc;
+
+       return wait_for_completion_timeout(completion,
+                                          msecs_to_jiffies(2000)) ?
+                                               0 : -ETIME;
+}
+
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+       int rc;
+       struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
+                                   DVBT_BDA_CONTROL_MSG_ID,
+                                   HIF_TASK,
+                                   sizeof(struct SmsMsgHdr_ST), 0 };
+
+       rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                         &client->tune_done);
+
+       return rc;
+}
+
+static inline int led_feedback(struct smsdvb_client_t *client)
+{
+       if (client->fe_status & FE_HAS_LOCK)
+               return sms_board_led_feedback(client->coredev,
+                       (client->sms_stat_dvb.ReceptionData.BER
+                       == 0) ? SMS_LED_HI : SMS_LED_LO);
+       else
+               return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+}
+
+static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *stat = client->fe_status;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *ber = client->sms_stat_dvb.ReceptionData.BER;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       int rc;
+
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
+               *strength = 0;
+               else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
+                       *strength = 100;
+               else
+                       *strength =
+                               (client->sms_stat_dvb.ReceptionData.InBandPwr
+                               + 95) * 3 / 2;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *snr = client->sms_stat_dvb.ReceptionData.SNR;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
+                                   struct dvb_frontend_tune_settings *tune)
+{
+       sms_debug("");
+
+       tune->min_delay_ms = 400;
+       tune->step_size = 250000;
+       tune->max_drift = 0;
+       return 0;
+}
+
+static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       struct {
+               struct SmsMsgHdr_ST     Msg;
+               u32             Data[3];
+       } Msg;
+
+       int ret;
+
+       client->fe_status = FE_HAS_SIGNAL;
+       client->event_fe_state = -1;
+       client->event_unc_state = -1;
+       fe->dtv_property_cache.delivery_system = SYS_DVBT;
+
+       Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId = HIF_TASK;
+       Msg.Msg.msgFlags = 0;
+       Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+       Msg.Data[0] = c->frequency;
+       Msg.Data[2] = 12000000;
+
+       sms_info("%s: freq %d band %d", __func__, c->frequency,
+                c->bandwidth_hz);
+
+       switch (c->bandwidth_hz / 1000000) {
+       case 8:
+               Msg.Data[1] = BW_8_MHZ;
+               break;
+       case 7:
+               Msg.Data[1] = BW_7_MHZ;
+               break;
+       case 6:
+               Msg.Data[1] = BW_6_MHZ;
+               break;
+       case 0:
+               return -EOPNOTSUPP;
+       default:
+               return -EINVAL;
+       }
+       /* Disable LNA, if any. An error is returned if no LNA is present */
+       ret = sms_board_lna_control(client->coredev, 0);
+       if (ret == 0) {
+               fe_status_t status;
+
+               /* tune with LNA off at first */
+               ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                                 &client->tune_done);
+
+               smsdvb_read_status(fe, &status);
+
+               if (status & FE_HAS_LOCK)
+                       return ret;
+
+               /* previous tune didn't lock - enable LNA and tune again */
+               sms_board_lna_control(client->coredev, 1);
+       }
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                          &client->tune_done);
+}
+
+static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       struct {
+               struct SmsMsgHdr_ST     Msg;
+               u32             Data[4];
+       } Msg;
+
+       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
+       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId  = HIF_TASK;
+       Msg.Msg.msgFlags  = 0;
+       Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+
+       if (c->isdbt_sb_segment_idx == -1)
+               c->isdbt_sb_segment_idx = 0;
+
+       switch (c->isdbt_sb_segment_count) {
+       case 3:
+               Msg.Data[1] = BW_ISDBT_3SEG;
+               break;
+       case 1:
+               Msg.Data[1] = BW_ISDBT_1SEG;
+               break;
+       case 0: /* AUTO */
+               switch (c->bandwidth_hz / 1000000) {
+               case 8:
+               case 7:
+                       c->isdbt_sb_segment_count = 3;
+                       Msg.Data[1] = BW_ISDBT_3SEG;
+                       break;
+               case 6:
+                       c->isdbt_sb_segment_count = 1;
+                       Msg.Data[1] = BW_ISDBT_1SEG;
+                       break;
+               default: /* Assumes 6 MHZ bw */
+                       c->isdbt_sb_segment_count = 1;
+                       c->bandwidth_hz = 6000;
+                       Msg.Data[1] = BW_ISDBT_1SEG;
+                       break;
+               }
+               break;
+       default:
+               sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
+               return -EINVAL;
+       }
+
+       Msg.Data[0] = c->frequency;
+       Msg.Data[2] = 12000000;
+       Msg.Data[3] = c->isdbt_sb_segment_idx;
+
+       sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
+                c->frequency, c->isdbt_sb_segment_count,
+                c->isdbt_sb_segment_idx);
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                          &client->tune_done);
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+       struct smscore_device_t *coredev = client->coredev;
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               return smsdvb_dvbt_set_frontend(fe);
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               return smsdvb_isdbt_set_frontend(fe);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int smsdvb_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+       struct smscore_device_t *coredev = client->coredev;
+       struct TRANSMISSION_STATISTICS_S *td =
+               &client->sms_stat_dvb.TransmissionData;
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               fep->frequency = td->Frequency;
+
+               switch (td->Bandwidth) {
+               case 6:
+                       fep->bandwidth_hz = 6000000;
+                       break;
+               case 7:
+                       fep->bandwidth_hz = 7000000;
+                       break;
+               case 8:
+                       fep->bandwidth_hz = 8000000;
+                       break;
+               }
+
+               switch (td->TransmissionMode) {
+               case 2:
+                       fep->transmission_mode = TRANSMISSION_MODE_2K;
+                       break;
+               case 8:
+                       fep->transmission_mode = TRANSMISSION_MODE_8K;
+               }
+
+               switch (td->GuardInterval) {
+               case 0:
+                       fep->guard_interval = GUARD_INTERVAL_1_32;
+                       break;
+               case 1:
+                       fep->guard_interval = GUARD_INTERVAL_1_16;
+                       break;
+               case 2:
+                       fep->guard_interval = GUARD_INTERVAL_1_8;
+                       break;
+               case 3:
+                       fep->guard_interval = GUARD_INTERVAL_1_4;
+                       break;
+               }
+
+               switch (td->CodeRate) {
+               case 0:
+                       fep->code_rate_HP = FEC_1_2;
+                       break;
+               case 1:
+                       fep->code_rate_HP = FEC_2_3;
+                       break;
+               case 2:
+                       fep->code_rate_HP = FEC_3_4;
+                       break;
+               case 3:
+                       fep->code_rate_HP = FEC_5_6;
+                       break;
+               case 4:
+                       fep->code_rate_HP = FEC_7_8;
+                       break;
+               }
+
+               switch (td->LPCodeRate) {
+               case 0:
+                       fep->code_rate_LP = FEC_1_2;
+                       break;
+               case 1:
+                       fep->code_rate_LP = FEC_2_3;
+                       break;
+               case 2:
+                       fep->code_rate_LP = FEC_3_4;
+                       break;
+               case 3:
+                       fep->code_rate_LP = FEC_5_6;
+                       break;
+               case 4:
+                       fep->code_rate_LP = FEC_7_8;
+                       break;
+               }
+
+               switch (td->Constellation) {
+               case 0:
+                       fep->modulation = QPSK;
+                       break;
+               case 1:
+                       fep->modulation = QAM_16;
+                       break;
+               case 2:
+                       fep->modulation = QAM_64;
+                       break;
+               }
+
+               switch (td->Hierarchy) {
+               case 0:
+                       fep->hierarchy = HIERARCHY_NONE;
+                       break;
+               case 1:
+                       fep->hierarchy = HIERARCHY_1;
+                       break;
+               case 2:
+                       fep->hierarchy = HIERARCHY_2;
+                       break;
+               case 3:
+                       fep->hierarchy = HIERARCHY_4;
+                       break;
+               }
+
+               fep->inversion = INVERSION_AUTO;
+               break;
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               fep->frequency = td->Frequency;
+               fep->bandwidth_hz = 6000000;
+               /* todo: retrive the other parameters */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int smsdvb_init(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       sms_board_power(client->coredev, 1);
+
+       sms_board_dvb3_event(client, DVB3_EVENT_INIT);
+       return 0;
+}
+
+static int smsdvb_sleep(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+       sms_board_power(client->coredev, 0);
+
+       sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
+
+       return 0;
+}
+
+static void smsdvb_release(struct dvb_frontend *fe)
+{
+       /* do nothing */
+}
+
+static struct dvb_frontend_ops smsdvb_fe_ops = {
+       .info = {
+               .name                   = "Siano Mobile Digital MDTV Receiver",
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 250000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = smsdvb_release,
+
+       .set_frontend = smsdvb_set_frontend,
+       .get_frontend = smsdvb_get_frontend,
+       .get_tune_settings = smsdvb_get_tune_settings,
+
+       .read_status = smsdvb_read_status,
+       .read_ber = smsdvb_read_ber,
+       .read_signal_strength = smsdvb_read_signal_strength,
+       .read_snr = smsdvb_read_snr,
+       .read_ucblocks = smsdvb_read_ucblocks,
+
+       .init = smsdvb_init,
+       .sleep = smsdvb_sleep,
+};
+
+static int smsdvb_hotplug(struct smscore_device_t *coredev,
+                         struct device *device, int arrival)
+{
+       struct smsclient_params_t params;
+       struct smsdvb_client_t *client;
+       int rc;
+
+       /* device removal handled by onremove callback */
+       if (!arrival)
+               return 0;
+       client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
+       if (!client) {
+               sms_err("kmalloc() failed");
+               return -ENOMEM;
+       }
+
+       /* register dvb adapter */
+       rc = dvb_register_adapter(&client->adapter,
+                                 sms_get_board(
+                                       smscore_get_board_id(coredev))->name,
+                                 THIS_MODULE, device, adapter_nr);
+       if (rc < 0) {
+               sms_err("dvb_register_adapter() failed %d", rc);
+               goto adapter_error;
+       }
+
+       /* init dvb demux */
+       client->demux.dmx.capabilities = DMX_TS_FILTERING;
+       client->demux.filternum = 32; /* todo: nova ??? */
+       client->demux.feednum = 32;
+       client->demux.start_feed = smsdvb_start_feed;
+       client->demux.stop_feed = smsdvb_stop_feed;
+
+       rc = dvb_dmx_init(&client->demux);
+       if (rc < 0) {
+               sms_err("dvb_dmx_init failed %d", rc);
+               goto dvbdmx_error;
+       }
+
+       /* init dmxdev */
+       client->dmxdev.filternum = 32;
+       client->dmxdev.demux = &client->demux.dmx;
+       client->dmxdev.capabilities = 0;
+
+       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
+       if (rc < 0) {
+               sms_err("dvb_dmxdev_init failed %d", rc);
+               goto dmxdev_error;
+       }
+
+       /* init and register frontend */
+       memcpy(&client->frontend.ops, &smsdvb_fe_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               client->frontend.ops.delsys[0] = SYS_DVBT;
+               break;
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               client->frontend.ops.delsys[0] = SYS_ISDBT;
+               break;
+       }
+
+       rc = dvb_register_frontend(&client->adapter, &client->frontend);
+       if (rc < 0) {
+               sms_err("frontend registration failed %d", rc);
+               goto frontend_error;
+       }
+
+       params.initial_id = 1;
+       params.data_type = MSG_SMS_DVBT_BDA_DATA;
+       params.onresponse_handler = smsdvb_onresponse;
+       params.onremove_handler = smsdvb_onremove;
+       params.context = client;
+
+       rc = smscore_register_client(coredev, &params, &client->smsclient);
+       if (rc < 0) {
+               sms_err("smscore_register_client() failed %d", rc);
+               goto client_error;
+       }
+
+       client->coredev = coredev;
+
+       init_completion(&client->tune_done);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       list_add(&client->entry, &g_smsdvb_clients);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+
+       client->event_fe_state = -1;
+       client->event_unc_state = -1;
+       sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
+
+       sms_info("success");
+       sms_board_setup(coredev);
+
+       return 0;
+
+client_error:
+       dvb_unregister_frontend(&client->frontend);
+
+frontend_error:
+       dvb_dmxdev_release(&client->dmxdev);
+
+dmxdev_error:
+       dvb_dmx_release(&client->demux);
+
+dvbdmx_error:
+       dvb_unregister_adapter(&client->adapter);
+
+adapter_error:
+       kfree(client);
+       return rc;
+}
+
+static int __init smsdvb_module_init(void)
+{
+       int rc;
+
+       INIT_LIST_HEAD(&g_smsdvb_clients);
+       kmutex_init(&g_smsdvb_clientslock);
+
+       rc = smscore_register_hotplug(smsdvb_hotplug);
+
+       sms_debug("");
+
+       return rc;
+}
+
+static void __exit smsdvb_module_exit(void)
+{
+       smscore_unregister_hotplug(smsdvb_hotplug);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       while (!list_empty(&g_smsdvb_clients))
+              smsdvb_unregister_client(
+                       (struct smsdvb_client_t *) g_smsdvb_clients.next);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smsendian.c b/drivers/media/usb/siano/smsendian.c
new file mode 100644 (file)
index 0000000..e2657c2
--- /dev/null
@@ -0,0 +1,103 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ 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, see <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+#include <linux/export.h>
+#include <asm/byteorder.h>
+
+#include "smsendian.h"
+#include "smscoreapi.h"
+
+void smsendian_handle_tx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+       int i;
+       int msgWords;
+
+       switch (msg->xMsgHeader.msgType) {
+       case MSG_SMS_DATA_DOWNLOAD_REQ:
+       {
+               msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
+               break;
+       }
+
+       default:
+               msgWords = (msg->xMsgHeader.msgLength -
+                               sizeof(struct SmsMsgHdr_ST))/4;
+
+               for (i = 0; i < msgWords; i++)
+                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+               break;
+       }
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
+
+void smsendian_handle_rx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+       int i;
+       int msgWords;
+
+       switch (msg->xMsgHeader.msgType) {
+       case MSG_SMS_GET_VERSION_EX_RES:
+       {
+               struct SmsVersionRes_ST *ver =
+                       (struct SmsVersionRes_ST *) msg;
+               ver->ChipModel = le16_to_cpu(ver->ChipModel);
+               break;
+       }
+
+       case MSG_SMS_DVBT_BDA_DATA:
+       case MSG_SMS_DAB_CHANNEL:
+       case MSG_SMS_DATA_MSG:
+       {
+               break;
+       }
+
+       default:
+       {
+               msgWords = (msg->xMsgHeader.msgLength -
+                               sizeof(struct SmsMsgHdr_ST))/4;
+
+               for (i = 0; i < msgWords; i++)
+                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+               break;
+       }
+       }
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
+
+void smsendian_handle_message_header(void *msg)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
+
+       phdr->msgType = le16_to_cpu(phdr->msgType);
+       phdr->msgLength = le16_to_cpu(phdr->msgLength);
+       phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/usb/siano/smsendian.h b/drivers/media/usb/siano/smsendian.h
new file mode 100644 (file)
index 0000000..1624d6f
--- /dev/null
@@ -0,0 +1,32 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_ENDIAN_H__
+#define __SMS_ENDIAN_H__
+
+#include <asm/byteorder.h>
+
+extern void smsendian_handle_tx_message(void *buffer);
+extern void smsendian_handle_rx_message(void *buffer);
+extern void smsendian_handle_message_header(void *msg);
+
+#endif /* __SMS_ENDIAN_H__ */
+
diff --git a/drivers/media/usb/siano/smsir.c b/drivers/media/usb/siano/smsir.c
new file mode 100644 (file)
index 0000000..37bc5c4
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ Copyright (c) 2010 - Mauro Carvalho Chehab
+       - Ported the driver to use rc-core
+       - IR raw event decoding is now done at rc-core
+       - Code almost re-written
+
+ 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, see <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#include "smscoreapi.h"
+#include "smsir.h"
+#include "sms-cards.h"
+
+#define MODULE_NAME "smsmdtv"
+
+void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
+{
+       int i;
+       const s32 *samples = (const void *)buf;
+
+       for (i = 0; i < len >> 2; i++) {
+               DEFINE_IR_RAW_EVENT(ev);
+
+               ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
+               ev.pulse = (samples[i] > 0) ? false : true;
+
+               ir_raw_event_store(coredev->ir.dev, &ev);
+       }
+       ir_raw_event_handle(coredev->ir.dev);
+}
+
+int sms_ir_init(struct smscore_device_t *coredev)
+{
+       int err;
+       int board_id = smscore_get_board_id(coredev);
+       struct rc_dev *dev;
+
+       sms_log("Allocating rc device");
+       dev = rc_allocate_device();
+       if (!dev) {
+               sms_err("Not enough memory");
+               return -ENOMEM;
+       }
+
+       coredev->ir.controller = 0;     /* Todo: vega/nova SPI number */
+       coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
+       sms_log("IR port %d, timeout %d ms",
+                       coredev->ir.controller, coredev->ir.timeout);
+
+       snprintf(coredev->ir.name, sizeof(coredev->ir.name),
+                "SMS IR (%s)", sms_get_board(board_id)->name);
+
+       strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
+       strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
+
+       dev->input_name = coredev->ir.name;
+       dev->input_phys = coredev->ir.phys;
+       dev->dev.parent = coredev->device;
+
+#if 0
+       /* TODO: properly initialize the parameters bellow */
+       dev->input_id.bustype = BUS_USB;
+       dev->input_id.version = 1;
+       dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+       dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+#endif
+
+       dev->priv = coredev;
+       dev->driver_type = RC_DRIVER_IR_RAW;
+       dev->allowed_protos = RC_TYPE_ALL;
+       dev->map_name = sms_get_board(board_id)->rc_codes;
+       dev->driver_name = MODULE_NAME;
+
+       sms_log("Input device (IR) %s is set for key events", dev->input_name);
+
+       err = rc_register_device(dev);
+       if (err < 0) {
+               sms_err("Failed to register device");
+               rc_free_device(dev);
+               return err;
+       }
+
+       coredev->ir.dev = dev;
+       return 0;
+}
+
+void sms_ir_exit(struct smscore_device_t *coredev)
+{
+       if (coredev->ir.dev)
+               rc_unregister_device(coredev->ir.dev);
+
+       sms_log("");
+}
diff --git a/drivers/media/usb/siano/smsir.h b/drivers/media/usb/siano/smsir.h
new file mode 100644 (file)
index 0000000..ae92b3a
--- /dev/null
@@ -0,0 +1,55 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+ Copyright (c) 2010 - Mauro Carvalho Chehab
+       - Ported the driver to use rc-core
+       - IR raw event decoding is now done at rc-core
+       - Code almost re-written
+
+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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_IR_H__
+#define __SMS_IR_H__
+
+#include <linux/input.h>
+#include <media/rc-core.h>
+
+#define IR_DEFAULT_TIMEOUT             100
+
+struct smscore_device_t;
+
+struct ir_t {
+       struct rc_dev *dev;
+       char name[40];
+       char phys[32];
+
+       char *rc_codes;
+       u64 protocol;
+
+       u32 timeout;
+       u32 controller;
+};
+
+int sms_ir_init(struct smscore_device_t *coredev);
+void sms_ir_exit(struct smscore_device_t *coredev);
+void sms_ir_event(struct smscore_device_t *coredev,
+                       const char *buf, int len);
+
+#endif /* __SMS_IR_H__ */
+
diff --git a/drivers/media/usb/siano/smssdio.c b/drivers/media/usb/siano/smssdio.c
new file mode 100644 (file)
index 0000000..d6f3f10
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ *  smssdio.c - Siano 1xxx SDIO interface driver
+ *
+ *  Copyright 2008 Pierre Ossman
+ *
+ * Based on code by Siano Mobile Silicon, Inc.,
+ * Copyright (C) 2006-2008, Uri Shkolnik
+ *
+ * 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 hardware is a bit odd in that all transfers should be done
+ * to/from the SMSSDIO_DATA register, yet the "increase address" bit
+ * always needs to be set.
+ *
+ * Also, buffers from the card are always aligned to 128 byte
+ * boundaries.
+ */
+
+/*
+ * General cleanup notes:
+ *
+ * - only typedefs should be name *_t
+ *
+ * - use ERR_PTR and friends for smscore_register_device()
+ *
+ * - smscore_getbuffer should zero fields
+ *
+ * Fix stop command
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+/* Registers */
+
+#define SMSSDIO_DATA           0x00
+#define SMSSDIO_INT            0x04
+#define SMSSDIO_BLOCK_SIZE     128
+
+static const struct sdio_device_id smssdio_ids[] __devinitconst = {
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
+        .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
+        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
+        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
+        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
+        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+       { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, smssdio_ids);
+
+struct smssdio_device {
+       struct sdio_func *func;
+
+       struct smscore_device_t *coredev;
+
+       struct smscore_buffer_t *split_cb;
+};
+
+/*******************************************************************/
+/* Siano core callbacks                                            */
+/*******************************************************************/
+
+static int smssdio_sendrequest(void *context, void *buffer, size_t size)
+{
+       int ret = 0;
+       struct smssdio_device *smsdev;
+
+       smsdev = context;
+
+       sdio_claim_host(smsdev->func);
+
+       while (size >= smsdev->func->cur_blksize) {
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, smsdev->func->cur_blksize);
+               if (ret)
+                       goto out;
+
+               buffer += smsdev->func->cur_blksize;
+               size -= smsdev->func->cur_blksize;
+       }
+
+       if (size) {
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, size);
+       }
+
+out:
+       sdio_release_host(smsdev->func);
+
+       return ret;
+}
+
+/*******************************************************************/
+/* SDIO callbacks                                                  */
+/*******************************************************************/
+
+static void smssdio_interrupt(struct sdio_func *func)
+{
+       int ret;
+
+       struct smssdio_device *smsdev;
+       struct smscore_buffer_t *cb;
+       struct SmsMsgHdr_ST *hdr;
+       size_t size;
+
+       smsdev = sdio_get_drvdata(func);
+
+       /*
+        * The interrupt register has no defined meaning. It is just
+        * a way of turning of the level triggered interrupt.
+        */
+       (void)sdio_readb(func, SMSSDIO_INT, &ret);
+       if (ret) {
+               sms_err("Unable to read interrupt register!\n");
+               return;
+       }
+
+       if (smsdev->split_cb == NULL) {
+               cb = smscore_getbuffer(smsdev->coredev);
+               if (!cb) {
+                       sms_err("Unable to allocate data buffer!\n");
+                       return;
+               }
+
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        cb->p,
+                                        SMSSDIO_DATA,
+                                        SMSSDIO_BLOCK_SIZE);
+               if (ret) {
+                       sms_err("Error %d reading initial block!\n", ret);
+                       return;
+               }
+
+               hdr = cb->p;
+
+               if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
+                       smsdev->split_cb = cb;
+                       return;
+               }
+
+               if (hdr->msgLength > smsdev->func->cur_blksize)
+                       size = hdr->msgLength - smsdev->func->cur_blksize;
+               else
+                       size = 0;
+       } else {
+               cb = smsdev->split_cb;
+               hdr = cb->p;
+
+               size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
+
+               smsdev->split_cb = NULL;
+       }
+
+       if (size) {
+               void *buffer;
+
+               buffer = cb->p + (hdr->msgLength - size);
+               size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
+
+               BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
+
+               /*
+                * First attempt to transfer all of it in one go...
+                */
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        buffer,
+                                        SMSSDIO_DATA,
+                                        size);
+               if (ret && ret != -EINVAL) {
+                       smscore_putbuffer(smsdev->coredev, cb);
+                       sms_err("Error %d reading data from card!\n", ret);
+                       return;
+               }
+
+               /*
+                * ..then fall back to one block at a time if that is
+                * not possible...
+                *
+                * (we have to do this manually because of the
+                * problem with the "increase address" bit)
+                */
+               if (ret == -EINVAL) {
+                       while (size) {
+                               ret = sdio_memcpy_fromio(smsdev->func,
+                                                 buffer, SMSSDIO_DATA,
+                                                 smsdev->func->cur_blksize);
+                               if (ret) {
+                                       smscore_putbuffer(smsdev->coredev, cb);
+                                       sms_err("Error %d reading "
+                                               "data from card!\n", ret);
+                                       return;
+                               }
+
+                               buffer += smsdev->func->cur_blksize;
+                               if (size > smsdev->func->cur_blksize)
+                                       size -= smsdev->func->cur_blksize;
+                               else
+                                       size = 0;
+                       }
+               }
+       }
+
+       cb->size = hdr->msgLength;
+       cb->offset = 0;
+
+       smscore_onresponse(smsdev->coredev, cb);
+}
+
+static int __devinit smssdio_probe(struct sdio_func *func,
+                        const struct sdio_device_id *id)
+{
+       int ret;
+
+       int board_id;
+       struct smssdio_device *smsdev;
+       struct smsdevice_params_t params;
+
+       board_id = id->driver_data;
+
+       smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
+       if (!smsdev)
+               return -ENOMEM;
+
+       smsdev->func = func;
+
+       memset(&params, 0, sizeof(struct smsdevice_params_t));
+
+       params.device = &func->dev;
+       params.buffer_size = 0x5000;    /* ?? */
+       params.num_buffers = 22;        /* ?? */
+       params.context = smsdev;
+
+       snprintf(params.devpath, sizeof(params.devpath),
+                "sdio\\%s", sdio_func_id(func));
+
+       params.sendrequest_handler = smssdio_sendrequest;
+
+       params.device_type = sms_get_board(board_id)->type;
+
+       if (params.device_type != SMS_STELLAR)
+               params.flags |= SMS_DEVICE_FAMILY2;
+       else {
+               /*
+                * FIXME: Stellar needs special handling...
+                */
+               ret = -ENODEV;
+               goto free;
+       }
+
+       ret = smscore_register_device(&params, &smsdev->coredev);
+       if (ret < 0)
+               goto free;
+
+       smscore_set_board_id(smsdev->coredev, board_id);
+
+       sdio_claim_host(func);
+
+       ret = sdio_enable_func(func);
+       if (ret)
+               goto release;
+
+       ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
+       if (ret)
+               goto disable;
+
+       ret = sdio_claim_irq(func, smssdio_interrupt);
+       if (ret)
+               goto disable;
+
+       sdio_set_drvdata(func, smsdev);
+
+       sdio_release_host(func);
+
+       ret = smscore_start_device(smsdev->coredev);
+       if (ret < 0)
+               goto reclaim;
+
+       return 0;
+
+reclaim:
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+disable:
+       sdio_disable_func(func);
+release:
+       sdio_release_host(func);
+       smscore_unregister_device(smsdev->coredev);
+free:
+       kfree(smsdev);
+
+       return ret;
+}
+
+static void smssdio_remove(struct sdio_func *func)
+{
+       struct smssdio_device *smsdev;
+
+       smsdev = sdio_get_drvdata(func);
+
+       /* FIXME: racy! */
+       if (smsdev->split_cb)
+               smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
+
+       smscore_unregister_device(smsdev->coredev);
+
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+       sdio_disable_func(func);
+       sdio_release_host(func);
+
+       kfree(smsdev);
+}
+
+static struct sdio_driver smssdio_driver = {
+       .name = "smssdio",
+       .id_table = smssdio_ids,
+       .probe = smssdio_probe,
+       .remove = smssdio_remove,
+};
+
+/*******************************************************************/
+/* Module functions                                                */
+/*******************************************************************/
+
+static int __init smssdio_module_init(void)
+{
+       int ret = 0;
+
+       printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
+       printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
+
+       ret = sdio_register_driver(&smssdio_driver);
+
+       return ret;
+}
+
+static void __exit smssdio_module_exit(void)
+{
+       sdio_unregister_driver(&smssdio_driver);
+}
+
+module_init(smssdio_module_init);
+module_exit(smssdio_module_exit);
+
+MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
+MODULE_AUTHOR("Pierre Ossman");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
new file mode 100644 (file)
index 0000000..664e460
--- /dev/null
@@ -0,0 +1,568 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat
+
+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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+#include "smsendian.h"
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+#define USB1_BUFFER_SIZE               0x1000
+#define USB2_BUFFER_SIZE               0x4000
+
+#define MAX_BUFFERS            50
+#define MAX_URBS               10
+
+struct smsusb_device_t;
+
+struct smsusb_urb_t {
+       struct smscore_buffer_t *cb;
+       struct smsusb_device_t  *dev;
+
+       struct urb urb;
+};
+
+struct smsusb_device_t {
+       struct usb_device *udev;
+       struct smscore_device_t *coredev;
+
+       struct smsusb_urb_t     surbs[MAX_URBS];
+
+       int             response_alignment;
+       int             buffer_size;
+};
+
+static int smsusb_submit_urb(struct smsusb_device_t *dev,
+                            struct smsusb_urb_t *surb);
+
+static void smsusb_onresponse(struct urb *urb)
+{
+       struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
+       struct smsusb_device_t *dev = surb->dev;
+
+       if (urb->status == -ESHUTDOWN) {
+               sms_err("error, urb status %d (-ESHUTDOWN), %d bytes",
+                       urb->status, urb->actual_length);
+               return;
+       }
+
+       if ((urb->actual_length > 0) && (urb->status == 0)) {
+               struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p;
+
+               smsendian_handle_message_header(phdr);
+               if (urb->actual_length >= phdr->msgLength) {
+                       surb->cb->size = phdr->msgLength;
+
+                       if (dev->response_alignment &&
+                           (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {
+
+                               surb->cb->offset =
+                                       dev->response_alignment +
+                                       ((phdr->msgFlags >> 8) & 3);
+
+                               /* sanity check */
+                               if (((int) phdr->msgLength +
+                                    surb->cb->offset) > urb->actual_length) {
+                                       sms_err("invalid response "
+                                               "msglen %d offset %d "
+                                               "size %d",
+                                               phdr->msgLength,
+                                               surb->cb->offset,
+                                               urb->actual_length);
+                                       goto exit_and_resubmit;
+                               }
+
+                               /* move buffer pointer and
+                                * copy header to its new location */
+                               memcpy((char *) phdr + surb->cb->offset,
+                                      phdr, sizeof(struct SmsMsgHdr_ST));
+                       } else
+                               surb->cb->offset = 0;
+
+                       smscore_onresponse(dev->coredev, surb->cb);
+                       surb->cb = NULL;
+               } else {
+                       sms_err("invalid response "
+                               "msglen %d actual %d",
+                               phdr->msgLength, urb->actual_length);
+               }
+       } else
+               sms_err("error, urb status %d, %d bytes",
+                       urb->status, urb->actual_length);
+
+
+exit_and_resubmit:
+       smsusb_submit_urb(dev, surb);
+}
+
+static int smsusb_submit_urb(struct smsusb_device_t *dev,
+                            struct smsusb_urb_t *surb)
+{
+       if (!surb->cb) {
+               surb->cb = smscore_getbuffer(dev->coredev);
+               if (!surb->cb) {
+                       sms_err("smscore_getbuffer(...) returned NULL");
+                       return -ENOMEM;
+               }
+       }
+
+       usb_fill_bulk_urb(
+               &surb->urb,
+               dev->udev,
+               usb_rcvbulkpipe(dev->udev, 0x81),
+               surb->cb->p,
+               dev->buffer_size,
+               smsusb_onresponse,
+               surb
+       );
+       surb->urb.transfer_dma = surb->cb->phys;
+       surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       return usb_submit_urb(&surb->urb, GFP_ATOMIC);
+}
+
+static void smsusb_stop_streaming(struct smsusb_device_t *dev)
+{
+       int i;
+
+       for (i = 0; i < MAX_URBS; i++) {
+               usb_kill_urb(&dev->surbs[i].urb);
+
+               if (dev->surbs[i].cb) {
+                       smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
+                       dev->surbs[i].cb = NULL;
+               }
+       }
+}
+
+static int smsusb_start_streaming(struct smsusb_device_t *dev)
+{
+       int i, rc;
+
+       for (i = 0; i < MAX_URBS; i++) {
+               rc = smsusb_submit_urb(dev, &dev->surbs[i]);
+               if (rc < 0) {
+                       sms_err("smsusb_submit_urb(...) failed");
+                       smsusb_stop_streaming(dev);
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+static int smsusb_sendrequest(void *context, void *buffer, size_t size)
+{
+       struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
+       int dummy;
+
+       smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
+       return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
+                           buffer, size, &dummy, 1000);
+}
+
+static char *smsusb1_fw_lkup[] = {
+       "dvbt_stellar_usb.inp",
+       "dvbh_stellar_usb.inp",
+       "tdmb_stellar_usb.inp",
+       "none",
+       "dvbt_bda_stellar_usb.inp",
+};
+
+static inline char *sms_get_fw_name(int mode, int board_id)
+{
+       char **fw = sms_get_board(board_id)->fw;
+       return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode];
+}
+
+static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id)
+{
+       const struct firmware *fw;
+       u8 *fw_buffer;
+       int rc, dummy;
+       char *fw_filename;
+
+       if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) {
+               sms_err("invalid firmware id specified %d", id);
+               return -EINVAL;
+       }
+
+       fw_filename = sms_get_fw_name(id, board_id);
+
+       rc = request_firmware(&fw, fw_filename, &udev->dev);
+       if (rc < 0) {
+               sms_warn("failed to open \"%s\" mode %d, "
+                        "trying again with default firmware", fw_filename, id);
+
+               fw_filename = smsusb1_fw_lkup[id];
+               rc = request_firmware(&fw, fw_filename, &udev->dev);
+               if (rc < 0) {
+                       sms_warn("failed to open \"%s\" mode %d",
+                                fw_filename, id);
+
+                       return rc;
+               }
+       }
+
+       fw_buffer = kmalloc(fw->size, GFP_KERNEL);
+       if (fw_buffer) {
+               memcpy(fw_buffer, fw->data, fw->size);
+
+               rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2),
+                                 fw_buffer, fw->size, &dummy, 1000);
+
+               sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc);
+
+               kfree(fw_buffer);
+       } else {
+               sms_err("failed to allocate firmware buffer");
+               rc = -ENOMEM;
+       }
+       sms_info("read FW %s, size=%zd", fw_filename, fw->size);
+
+       release_firmware(fw);
+
+       return rc;
+}
+
+static void smsusb1_detectmode(void *context, int *mode)
+{
+       char *product_string =
+               ((struct smsusb_device_t *) context)->udev->product;
+
+       *mode = DEVICE_MODE_NONE;
+
+       if (!product_string) {
+               product_string = "none";
+               sms_err("product string not found");
+       } else if (strstr(product_string, "DVBH"))
+               *mode = 1;
+       else if (strstr(product_string, "BDA"))
+               *mode = 4;
+       else if (strstr(product_string, "DVBT"))
+               *mode = 0;
+       else if (strstr(product_string, "TDMB"))
+               *mode = 2;
+
+       sms_info("%d \"%s\"", *mode, product_string);
+}
+
+static int smsusb1_setmode(void *context, int mode)
+{
+       struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK,
+                            sizeof(struct SmsMsgHdr_ST), 0 };
+
+       if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+               sms_err("invalid firmware id specified %d", mode);
+               return -EINVAL;
+       }
+
+       return smsusb_sendrequest(context, &Msg, sizeof(Msg));
+}
+
+static void smsusb_term_device(struct usb_interface *intf)
+{
+       struct smsusb_device_t *dev = usb_get_intfdata(intf);
+
+       if (dev) {
+               smsusb_stop_streaming(dev);
+
+               /* unregister from smscore */
+               if (dev->coredev)
+                       smscore_unregister_device(dev->coredev);
+
+               sms_info("device %p destroyed", dev);
+               kfree(dev);
+       }
+
+       usb_set_intfdata(intf, NULL);
+}
+
+static int smsusb_init_device(struct usb_interface *intf, int board_id)
+{
+       struct smsdevice_params_t params;
+       struct smsusb_device_t *dev;
+       int i, rc;
+
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+       if (!dev) {
+               sms_err("kzalloc(sizeof(struct smsusb_device_t) failed");
+               return -ENOMEM;
+       }
+
+       memset(&params, 0, sizeof(params));
+       usb_set_intfdata(intf, dev);
+       dev->udev = interface_to_usbdev(intf);
+
+       params.device_type = sms_get_board(board_id)->type;
+
+       switch (params.device_type) {
+       case SMS_STELLAR:
+               dev->buffer_size = USB1_BUFFER_SIZE;
+
+               params.setmode_handler = smsusb1_setmode;
+               params.detectmode_handler = smsusb1_detectmode;
+               break;
+       default:
+               sms_err("Unspecified sms device type!");
+               /* fall-thru */
+       case SMS_NOVA_A0:
+       case SMS_NOVA_B0:
+       case SMS_VEGA:
+               dev->buffer_size = USB2_BUFFER_SIZE;
+               dev->response_alignment =
+                   le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
+                   sizeof(struct SmsMsgHdr_ST);
+
+               params.flags |= SMS_DEVICE_FAMILY2;
+               break;
+       }
+
+       params.device = &dev->udev->dev;
+       params.buffer_size = dev->buffer_size;
+       params.num_buffers = MAX_BUFFERS;
+       params.sendrequest_handler = smsusb_sendrequest;
+       params.context = dev;
+       usb_make_path(dev->udev, params.devpath, sizeof(params.devpath));
+
+       /* register in smscore */
+       rc = smscore_register_device(&params, &dev->coredev);
+       if (rc < 0) {
+               sms_err("smscore_register_device(...) failed, rc %d", rc);
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       smscore_set_board_id(dev->coredev, board_id);
+
+       /* initialize urbs */
+       for (i = 0; i < MAX_URBS; i++) {
+               dev->surbs[i].dev = dev;
+               usb_init_urb(&dev->surbs[i].urb);
+       }
+
+       sms_info("smsusb_start_streaming(...).");
+       rc = smsusb_start_streaming(dev);
+       if (rc < 0) {
+               sms_err("smsusb_start_streaming(...) failed");
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       rc = smscore_start_device(dev->coredev);
+       if (rc < 0) {
+               sms_err("smscore_start_device(...) failed");
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       sms_info("device %p created", dev);
+
+       return rc;
+}
+
+static int __devinit smsusb_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       char devpath[32];
+       int i, rc;
+
+       rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
+       rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
+
+       if (intf->num_altsetting > 0) {
+               rc = usb_set_interface(
+                       udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
+               if (rc < 0) {
+                       sms_err("usb_set_interface failed, rc %d", rc);
+                       return rc;
+               }
+       }
+
+       sms_info("smsusb_probe %d",
+              intf->cur_altsetting->desc.bInterfaceNumber);
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
+               sms_info("endpoint %d %02x %02x %d", i,
+                      intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
+                      intf->cur_altsetting->endpoint[i].desc.bmAttributes,
+                      intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
+
+       if ((udev->actconfig->desc.bNumInterfaces == 2) &&
+           (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
+               sms_err("rom interface 0 is not used");
+               return -ENODEV;
+       }
+
+       if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+               snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
+                        udev->bus->busnum, udev->devpath);
+               sms_info("stellar device was found.");
+               return smsusb1_load_firmware(
+                               udev, smscore_registry_getmode(devpath),
+                               id->driver_info);
+       }
+
+       rc = smsusb_init_device(intf, id->driver_info);
+       sms_info("rc %d", rc);
+       sms_board_load_modules(id->driver_info);
+       return rc;
+}
+
+static void smsusb_disconnect(struct usb_interface *intf)
+{
+       smsusb_term_device(intf);
+}
+
+static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+       struct smsusb_device_t *dev = usb_get_intfdata(intf);
+       printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
+       smsusb_stop_streaming(dev);
+       return 0;
+}
+
+static int smsusb_resume(struct usb_interface *intf)
+{
+       int rc, i;
+       struct smsusb_device_t *dev = usb_get_intfdata(intf);
+       struct usb_device *udev = interface_to_usbdev(intf);
+
+       printk(KERN_INFO "%s: Entering.\n", __func__);
+       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
+       usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
+
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
+               printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,
+                      intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
+                      intf->cur_altsetting->endpoint[i].desc.bmAttributes,
+                      intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
+
+       if (intf->num_altsetting > 0) {
+               rc = usb_set_interface(udev,
+                                      intf->cur_altsetting->desc.
+                                      bInterfaceNumber, 0);
+               if (rc < 0) {
+                       printk(KERN_INFO "%s usb_set_interface failed, "
+                              "rc %d\n", __func__, rc);
+                       return rc;
+               }
+       }
+
+       smsusb_start_streaming(dev);
+       return 0;
+}
+
+static const struct usb_device_id smsusb_id_table[] __devinitconst = {
+       { USB_DEVICE(0x187f, 0x0010),
+               .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+       { USB_DEVICE(0x187f, 0x0100),
+               .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+       { USB_DEVICE(0x187f, 0x0200),
+               .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
+       { USB_DEVICE(0x187f, 0x0201),
+               .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
+       { USB_DEVICE(0x187f, 0x0300),
+               .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
+       { USB_DEVICE(0x2040, 0x1700),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
+       { USB_DEVICE(0x2040, 0x1800),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
+       { USB_DEVICE(0x2040, 0x1801),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
+       { USB_DEVICE(0x2040, 0x2000),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+       { USB_DEVICE(0x2040, 0x2009),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
+       { USB_DEVICE(0x2040, 0x200a),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+       { USB_DEVICE(0x2040, 0x2010),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+       { USB_DEVICE(0x2040, 0x2011),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+       { USB_DEVICE(0x2040, 0x2019),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+       { USB_DEVICE(0x2040, 0x5500),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5510),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5520),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5530),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5580),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0x5590),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x187f, 0x0202),
+               .driver_info = SMS1XXX_BOARD_SIANO_NICE },
+       { USB_DEVICE(0x187f, 0x0301),
+               .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
+       { USB_DEVICE(0x2040, 0xb900),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xb910),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xb980),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xb990),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc000),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc010),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc080),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc090),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xc0a0),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { USB_DEVICE(0x2040, 0xf5a0),
+               .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+       { } /* Terminating entry */
+       };
+
+MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+
+static struct usb_driver smsusb_driver = {
+       .name                   = "smsusb",
+       .probe                  = smsusb_probe,
+       .disconnect             = smsusb_disconnect,
+       .id_table               = smsusb_id_table,
+
+       .suspend                = smsusb_suspend,
+       .resume                 = smsusb_resume,
+};
+
+module_usb_driver(smsusb_driver);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/ttusb-budget/Kconfig b/drivers/media/usb/ttusb-budget/Kconfig
new file mode 100644 (file)
index 0000000..2663ae3
--- /dev/null
@@ -0,0 +1,18 @@
+config DVB_TTUSB_BUDGET
+       tristate "Technotrend/Hauppauge Nova-USB devices"
+       depends on DVB_CORE && USB && I2C && PCI
+       select DVB_CX22700 if !DVB_FE_CUSTOMISE
+       select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+       select DVB_VES1820 if !DVB_FE_CUSTOMISE
+       select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+       select DVB_STV0299 if !DVB_FE_CUSTOMISE
+       select DVB_STV0297 if !DVB_FE_CUSTOMISE
+       select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       help
+         Support for external USB adapters designed by Technotrend and
+         produced by Hauppauge, shipped under the brand name 'Nova-USB'.
+
+         These devices don't have a MPEG decoder built in, so you need
+         an external software decoder to watch TV.
+
+         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
new file mode 100644 (file)
index 0000000..f47bbf6
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
new file mode 100644 (file)
index 0000000..5b682cc
--- /dev/null
@@ -0,0 +1,1816 @@
+/*
+ * TTUSB DVB driver
+ *
+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
+ * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.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.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/errno.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "ves1820.h"
+#include "cx22700.h"
+#include "tda1004x.h"
+#include "stv0299.h"
+#include "tda8083.h"
+#include "stv0297.h"
+#include "lnbp21.h"
+
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/dmx.h>
+#include <linux/pci.h>
+
+/*
+  TTUSB_HWSECTIONS:
+    the DSP supports filtering in hardware, however, since the "muxstream"
+    is a bit braindead (no matching channel masks or no matching filter mask),
+    we won't support this - yet. it doesn't event support negative filters,
+    so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
+    parse TS data. USB bandwidth will be a problem when having large
+    datastreams, especially for dvb-net, but hey, that's not my problem.
+
+  TTUSB_DISEQC, TTUSB_TONE:
+    let the STC do the diseqc/tone stuff. this isn't supported at least with
+    my TTUSB, so let it undef'd unless you want to implement another
+    frontend. never tested.
+
+  debug:
+    define it to > 3 for really hardcore debugging. you probably don't want
+    this unless the device doesn't load at all. > 2 for bandwidth statistics.
+*/
+
+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(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
+
+#define ISO_BUF_COUNT      4
+#define FRAMES_PER_ISO_BUF 4
+#define ISO_FRAME_SIZE     912
+#define TTUSB_MAXCHANNEL   32
+#ifdef TTUSB_HWSECTIONS
+#define TTUSB_MAXFILTER    16  /* ??? */
+#endif
+
+#define TTUSB_REV_2_2  0x22
+#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
+
+/**
+ *  since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
+ *  the dvb_demux field must be the first in struct!!
+ */
+struct ttusb {
+       struct dvb_demux dvb_demux;
+       struct dmxdev dmxdev;
+       struct dvb_net dvbnet;
+
+       /* and one for USB access. */
+       struct mutex semi2c;
+       struct mutex semusb;
+
+       struct dvb_adapter adapter;
+       struct usb_device *dev;
+
+       struct i2c_adapter i2c_adap;
+
+       int disconnecting;
+       int iso_streaming;
+
+       unsigned int bulk_out_pipe;
+       unsigned int bulk_in_pipe;
+       unsigned int isoc_in_pipe;
+
+       void *iso_buffer;
+       dma_addr_t iso_dma_handle;
+
+       struct urb *iso_urb[ISO_BUF_COUNT];
+
+       int running_feed_count;
+       int last_channel;
+       int last_filter;
+
+       u8 c;                   /* transaction counter, wraps around...  */
+       fe_sec_tone_mode_t tone;
+       fe_sec_voltage_t voltage;
+
+       int mux_state;          // 0..2 - MuxSyncWord, 3 - nMuxPacks,    4 - muxpack
+       u8 mux_npacks;
+       u8 muxpack[256 + 8];
+       int muxpack_ptr, muxpack_len;
+
+       int insync;
+
+       int cc;                 /* MuxCounter - will increment on EVERY MUX PACKET */
+       /* (including stuffing. yes. really.) */
+
+       u8 last_result[32];
+
+       int revision;
+
+       struct dvb_frontend* fe;
+};
+
+/* ugly workaround ... don't know why it's necessary to read */
+/* all result codes. */
+
+static int ttusb_cmd(struct ttusb *ttusb,
+             const u8 * data, int len, int needresult)
+{
+       int actual_len;
+       int err;
+       int i;
+
+       if (debug >= 3) {
+               printk(KERN_DEBUG ">");
+               for (i = 0; i < len; ++i)
+                       printk(KERN_CONT " %02x", data[i]);
+               printk(KERN_CONT "\n");
+       }
+
+       if (mutex_lock_interruptible(&ttusb->semusb) < 0)
+               return -EAGAIN;
+
+       err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
+                          (u8 *) data, len, &actual_len, 1000);
+       if (err != 0) {
+               dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
+                       __func__, err);
+               mutex_unlock(&ttusb->semusb);
+               return err;
+       }
+       if (actual_len != len) {
+               dprintk("%s: only wrote %d of %d bytes\n", __func__,
+                       actual_len, len);
+               mutex_unlock(&ttusb->semusb);
+               return -1;
+       }
+
+       err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
+                          ttusb->last_result, 32, &actual_len, 1000);
+
+       if (err != 0) {
+               printk("%s: failed, receive error %d\n", __func__,
+                      err);
+               mutex_unlock(&ttusb->semusb);
+               return err;
+       }
+
+       if (debug >= 3) {
+               actual_len = ttusb->last_result[3] + 4;
+               printk(KERN_DEBUG "<");
+               for (i = 0; i < actual_len; ++i)
+                       printk(KERN_CONT " %02x", ttusb->last_result[i]);
+               printk(KERN_CONT "\n");
+       }
+
+       if (!needresult)
+               mutex_unlock(&ttusb->semusb);
+       return 0;
+}
+
+static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
+{
+       memcpy(data, ttusb->last_result, len);
+       mutex_unlock(&ttusb->semusb);
+       return 0;
+}
+
+static int ttusb_i2c_msg(struct ttusb *ttusb,
+                 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
+                 u8 rcv_len)
+{
+       u8 b[0x28];
+       u8 id = ++ttusb->c;
+       int i, err;
+
+       if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
+               return -EINVAL;
+
+       b[0] = 0xaa;
+       b[1] = id;
+       b[2] = 0x31;
+       b[3] = snd_len + 3;
+       b[4] = addr << 1;
+       b[5] = snd_len;
+       b[6] = rcv_len;
+
+       for (i = 0; i < snd_len; i++)
+               b[7 + i] = snd_buf[i];
+
+       err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
+
+       if (err)
+               return -EREMOTEIO;
+
+       err = ttusb_result(ttusb, b, 0x20);
+
+       /* check if the i2c transaction was successful */
+       if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
+
+       if (rcv_len > 0) {
+
+               if (err || b[0] != 0x55 || b[1] != id) {
+                       dprintk
+                           ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
+                            __func__, err, id);
+                       return -EREMOTEIO;
+               }
+
+               for (i = 0; i < rcv_len; i++)
+                       rcv_buf[i] = b[7 + i];
+       }
+
+       return rcv_len;
+}
+
+static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
+{
+       struct ttusb *ttusb = i2c_get_adapdata(adapter);
+       int i = 0;
+       int inc;
+
+       if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
+               int err;
+
+               if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
+                       addr = msg[i].addr;
+                       snd_buf = msg[i].buf;
+                       snd_len = msg[i].len;
+                       rcv_buf = msg[i + 1].buf;
+                       rcv_len = msg[i + 1].len;
+                       inc = 2;
+               } else {
+                       addr = msg[i].addr;
+                       snd_buf = msg[i].buf;
+                       snd_len = msg[i].len;
+                       rcv_buf = NULL;
+                       rcv_len = 0;
+                       inc = 1;
+               }
+
+               err = ttusb_i2c_msg(ttusb, addr,
+                                   snd_buf, snd_len, rcv_buf, rcv_len);
+
+               if (err < rcv_len) {
+                       dprintk("%s: i == %i\n", __func__, i);
+                       break;
+               }
+
+               i += inc;
+       }
+
+       mutex_unlock(&ttusb->semi2c);
+       return i;
+}
+
+static int ttusb_boot_dsp(struct ttusb *ttusb)
+{
+       const struct firmware *fw;
+       int i, err;
+       u8 b[40];
+
+       err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
+                              &ttusb->dev->dev);
+       if (err) {
+               printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
+               return err;
+       }
+
+       /* BootBlock */
+       b[0] = 0xaa;
+       b[2] = 0x13;
+       b[3] = 28;
+
+       /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
+       /* 32 is max packet size, no messages should be splitted. */
+       for (i = 0; i < fw->size; i += 28) {
+               memcpy(&b[4], &fw->data[i], 28);
+
+               b[1] = ++ttusb->c;
+
+               err = ttusb_cmd(ttusb, b, 32, 0);
+               if (err)
+                       goto done;
+       }
+
+       /* last block ... */
+       b[1] = ++ttusb->c;
+       b[2] = 0x13;
+       b[3] = 0;
+
+       err = ttusb_cmd(ttusb, b, 4, 0);
+       if (err)
+               goto done;
+
+       /* BootEnd */
+       b[1] = ++ttusb->c;
+       b[2] = 0x14;
+       b[3] = 0;
+
+       err = ttusb_cmd(ttusb, b, 4, 0);
+
+      done:
+       release_firmware(fw);
+       if (err) {
+               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
+                       __func__, err);
+       }
+
+       return err;
+}
+
+static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
+                     int pid)
+{
+       int err;
+       /* SetChannel */
+       u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
+               (pid >> 8) & 0xff, pid & 0xff
+       };
+
+       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
+       return err;
+}
+
+static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
+{
+       int err;
+       /* DelChannel */
+       u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
+
+       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
+       return err;
+}
+
+#ifdef TTUSB_HWSECTIONS
+static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
+                    int associated_chan, u8 filter[8], u8 mask[8])
+{
+       int err;
+       /* SetFilter */
+       u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
+               filter[0], filter[1], filter[2], filter[3],
+               filter[4], filter[5], filter[6], filter[7],
+               filter[8], filter[9], filter[10], filter[11],
+               mask[0], mask[1], mask[2], mask[3],
+               mask[4], mask[5], mask[6], mask[7],
+               mask[8], mask[9], mask[10], mask[11]
+       };
+
+       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
+       return err;
+}
+
+static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
+{
+       int err;
+       /* DelFilter */
+       u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
+
+       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
+       return err;
+}
+#endif
+
+static int ttusb_init_controller(struct ttusb *ttusb)
+{
+       u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
+       u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
+       u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
+       /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
+       u8 b3[] =
+           { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
+       u8 b4[] =
+           { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
+
+       u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
+       u8 get_dsp_version[0x20] =
+           { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
+       int err;
+
+       /* reset board */
+       if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
+               return err;
+
+       /* reset board (again?) */
+       if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
+               return err;
+
+       ttusb_boot_dsp(ttusb);
+
+       /* set i2c bit rate */
+       if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
+               return err;
+
+       if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
+               return err;
+
+       err = ttusb_result(ttusb, b4, sizeof(b4));
+
+       if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
+               return err;
+
+       if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
+               return err;
+
+       dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
+               get_version[4], get_version[5], get_version[6],
+               get_version[7], get_version[8]);
+
+       if (memcmp(get_version + 4, "V 0.0", 5) &&
+           memcmp(get_version + 4, "V 1.1", 5) &&
+           memcmp(get_version + 4, "V 2.1", 5) &&
+           memcmp(get_version + 4, "V 2.2", 5)) {
+               printk
+                   ("%s: unknown STC version %c%c%c%c%c, please report!\n",
+                    __func__, get_version[4], get_version[5],
+                    get_version[6], get_version[7], get_version[8]);
+       }
+
+       ttusb->revision = ((get_version[6] - '0') << 4) |
+                          (get_version[8] - '0');
+
+       err =
+           ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
+       if (err)
+               return err;
+
+       err =
+           ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
+       if (err)
+               return err;
+       printk("%s: dsp-version: %c%c%c\n", __func__,
+              get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
+       return 0;
+}
+
+#ifdef TTUSB_DISEQC
+static int ttusb_send_diseqc(struct dvb_frontend* fe,
+                            const struct dvb_diseqc_master_cmd *cmd)
+{
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+       u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
+
+       int err;
+
+       b[3] = 4 + 2 + cmd->msg_len;
+       b[4] = 0xFF;            /* send diseqc master, not burst */
+       b[5] = cmd->msg_len;
+
+       memcpy(b + 5, cmd->msg, cmd->msg_len);
+
+       /* Diseqc */
+       if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
+               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
+                       __func__, err);
+       }
+
+       return err;
+}
+#endif
+
+static int ttusb_update_lnb(struct ttusb *ttusb)
+{
+       u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
+               ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
+               ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
+       };
+       int err;
+
+       /* SetLNB */
+       if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
+               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
+                       __func__, err);
+       }
+
+       return err;
+}
+
+static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+
+       ttusb->voltage = voltage;
+       return ttusb_update_lnb(ttusb);
+}
+
+#ifdef TTUSB_TONE
+static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+
+       ttusb->tone = tone;
+       return ttusb_update_lnb(ttusb);
+}
+#endif
+
+
+#if 0
+static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
+{
+       u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
+       int err, actual_len;
+
+       err = ttusb_cmd(ttusb, b, sizeof(b), 0);
+       if (err) {
+               dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
+                       __func__, err);
+       }
+}
+#endif
+
+/*****************************************************************************/
+
+#ifdef TTUSB_HWSECTIONS
+static void ttusb_handle_ts_data(struct ttusb_channel *channel,
+                                const u8 * data, int len);
+static void ttusb_handle_sec_data(struct ttusb_channel *channel,
+                                 const u8 * data, int len);
+#endif
+
+static int numpkt, numts, numstuff, numsec, numinvalid;
+static unsigned long lastj;
+
+static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
+                          int len)
+{
+       u16 csum = 0, cc;
+       int i;
+       for (i = 0; i < len; i += 2)
+               csum ^= le16_to_cpup((__le16 *) (muxpack + i));
+       if (csum) {
+               printk("%s: muxpack with incorrect checksum, ignoring\n",
+                      __func__);
+               numinvalid++;
+               return;
+       }
+
+       cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
+       cc &= 0x7FFF;
+       if ((cc != ttusb->cc) && (ttusb->cc != -1))
+               printk("%s: cc discontinuity (%d frames missing)\n",
+                      __func__, (cc - ttusb->cc) & 0x7FFF);
+       ttusb->cc = (cc + 1) & 0x7FFF;
+       if (muxpack[0] & 0x80) {
+#ifdef TTUSB_HWSECTIONS
+               /* section data */
+               int pusi = muxpack[0] & 0x40;
+               int channel = muxpack[0] & 0x1F;
+               int payload = muxpack[1];
+               const u8 *data = muxpack + 2;
+               /* check offset flag */
+               if (muxpack[0] & 0x20)
+                       data++;
+
+               ttusb_handle_sec_data(ttusb->channel + channel, data,
+                                     payload);
+               data += payload;
+
+               if ((!!(ttusb->muxpack[0] & 0x20)) ^
+                   !!(ttusb->muxpack[1] & 1))
+                       data++;
+#warning TODO: pusi
+               printk("cc: %04x\n", (data[0] << 8) | data[1]);
+#endif
+               numsec++;
+       } else if (muxpack[0] == 0x47) {
+#ifdef TTUSB_HWSECTIONS
+               /* we have TS data here! */
+               int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
+               int channel;
+               for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
+                       if (ttusb->channel[channel].active
+                           && (pid == ttusb->channel[channel].pid))
+                               ttusb_handle_ts_data(ttusb->channel +
+                                                    channel, muxpack,
+                                                    188);
+#endif
+               numts++;
+               dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
+       } else if (muxpack[0] != 0) {
+               numinvalid++;
+               printk("illegal muxpack type %02x\n", muxpack[0]);
+       } else
+               numstuff++;
+}
+
+static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
+{
+       int maxwork = 1024;
+       while (len) {
+               if (!(maxwork--)) {
+                       printk("%s: too much work\n", __func__);
+                       break;
+               }
+
+               switch (ttusb->mux_state) {
+               case 0:
+               case 1:
+               case 2:
+                       len--;
+                       if (*data++ == 0xAA)
+                               ++ttusb->mux_state;
+                       else {
+                               ttusb->mux_state = 0;
+                               if (ttusb->insync) {
+                                       dprintk("%s: %02x\n",
+                                               __func__, data[-1]);
+                                       printk(KERN_INFO "%s: lost sync.\n",
+                                              __func__);
+                                       ttusb->insync = 0;
+                               }
+                       }
+                       break;
+               case 3:
+                       ttusb->insync = 1;
+                       len--;
+                       ttusb->mux_npacks = *data++;
+                       ++ttusb->mux_state;
+                       ttusb->muxpack_ptr = 0;
+                       /* maximum bytes, until we know the length */
+                       ttusb->muxpack_len = 2;
+                       break;
+               case 4:
+                       {
+                               int avail;
+                               avail = len;
+                               if (avail >
+                                   (ttusb->muxpack_len -
+                                    ttusb->muxpack_ptr))
+                                       avail =
+                                           ttusb->muxpack_len -
+                                           ttusb->muxpack_ptr;
+                               memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
+                                      data, avail);
+                               ttusb->muxpack_ptr += avail;
+                               BUG_ON(ttusb->muxpack_ptr > 264);
+                               data += avail;
+                               len -= avail;
+                               /* determine length */
+                               if (ttusb->muxpack_ptr == 2) {
+                                       if (ttusb->muxpack[0] & 0x80) {
+                                               ttusb->muxpack_len =
+                                                   ttusb->muxpack[1] + 2;
+                                               if (ttusb->
+                                                   muxpack[0] & 0x20)
+                                                       ttusb->
+                                                           muxpack_len++;
+                                               if ((!!
+                                                    (ttusb->
+                                                     muxpack[0] & 0x20)) ^
+                                                   !!(ttusb->
+                                                      muxpack[1] & 1))
+                                                       ttusb->
+                                                           muxpack_len++;
+                                               ttusb->muxpack_len += 4;
+                                       } else if (ttusb->muxpack[0] ==
+                                                  0x47)
+                                               ttusb->muxpack_len =
+                                                   188 + 4;
+                                       else if (ttusb->muxpack[0] == 0x00)
+                                               ttusb->muxpack_len =
+                                                   ttusb->muxpack[1] + 2 +
+                                                   4;
+                                       else {
+                                               dprintk
+                                                   ("%s: invalid state: first byte is %x\n",
+                                                    __func__,
+                                                    ttusb->muxpack[0]);
+                                               ttusb->mux_state = 0;
+                                       }
+                               }
+
+                       /**
+                        * if length is valid and we reached the end:
+                        * goto next muxpack
+                        */
+                               if ((ttusb->muxpack_ptr >= 2) &&
+                                   (ttusb->muxpack_ptr ==
+                                    ttusb->muxpack_len)) {
+                                       ttusb_process_muxpack(ttusb,
+                                                             ttusb->
+                                                             muxpack,
+                                                             ttusb->
+                                                             muxpack_ptr);
+                                       ttusb->muxpack_ptr = 0;
+                                       /* maximum bytes, until we know the length */
+                                       ttusb->muxpack_len = 2;
+
+                               /**
+                                * no muxpacks left?
+                                * return to search-sync state
+                                */
+                                       if (!ttusb->mux_npacks--) {
+                                               ttusb->mux_state = 0;
+                                               break;
+                                       }
+                               }
+                               break;
+                       }
+               default:
+                       BUG();
+                       break;
+               }
+       }
+}
+
+static void ttusb_iso_irq(struct urb *urb)
+{
+       struct ttusb *ttusb = urb->context;
+       struct usb_iso_packet_descriptor *d;
+       u8 *data;
+       int len, i;
+
+       if (!ttusb->iso_streaming)
+               return;
+
+#if 0
+       printk("%s: status %d, errcount == %d, length == %i\n",
+              __func__,
+              urb->status, urb->error_count, urb->actual_length);
+#endif
+
+       if (!urb->status) {
+               for (i = 0; i < urb->number_of_packets; ++i) {
+                       numpkt++;
+                       if (time_after_eq(jiffies, lastj + HZ)) {
+                               dprintk("frames/s: %lu (ts: %d, stuff %d, "
+                                       "sec: %d, invalid: %d, all: %d)\n",
+                                       numpkt * HZ / (jiffies - lastj),
+                                       numts, numstuff, numsec, numinvalid,
+                                       numts + numstuff + numsec + numinvalid);
+                               numts = numstuff = numsec = numinvalid = 0;
+                               lastj = jiffies;
+                               numpkt = 0;
+                       }
+                       d = &urb->iso_frame_desc[i];
+                       data = urb->transfer_buffer + d->offset;
+                       len = d->actual_length;
+                       d->actual_length = 0;
+                       d->status = 0;
+                       ttusb_process_frame(ttusb, data, len);
+               }
+       }
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void ttusb_free_iso_urbs(struct ttusb *ttusb)
+{
+       int i;
+
+       for (i = 0; i < ISO_BUF_COUNT; i++)
+               if (ttusb->iso_urb[i])
+                       usb_free_urb(ttusb->iso_urb[i]);
+
+       pci_free_consistent(NULL,
+                           ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
+                           ISO_BUF_COUNT, ttusb->iso_buffer,
+                           ttusb->iso_dma_handle);
+}
+
+static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
+{
+       int i;
+
+       ttusb->iso_buffer = pci_alloc_consistent(NULL,
+                                                ISO_FRAME_SIZE *
+                                                FRAMES_PER_ISO_BUF *
+                                                ISO_BUF_COUNT,
+                                                &ttusb->iso_dma_handle);
+
+       if (!ttusb->iso_buffer) {
+               dprintk("%s: pci_alloc_consistent - not enough memory\n",
+                       __func__);
+               return -ENOMEM;
+       }
+
+       memset(ttusb->iso_buffer, 0,
+              ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
+
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               struct urb *urb;
+
+               if (!
+                   (urb =
+                    usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
+                       ttusb_free_iso_urbs(ttusb);
+                       return -ENOMEM;
+               }
+
+               ttusb->iso_urb[i] = urb;
+       }
+
+       return 0;
+}
+
+static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
+{
+       int i;
+
+       for (i = 0; i < ISO_BUF_COUNT; i++)
+               usb_kill_urb(ttusb->iso_urb[i]);
+
+       ttusb->iso_streaming = 0;
+}
+
+static int ttusb_start_iso_xfer(struct ttusb *ttusb)
+{
+       int i, j, err, buffer_offset = 0;
+
+       if (ttusb->iso_streaming) {
+               printk("%s: iso xfer already running!\n", __func__);
+               return 0;
+       }
+
+       ttusb->cc = -1;
+       ttusb->insync = 0;
+       ttusb->mux_state = 0;
+
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               int frame_offset = 0;
+               struct urb *urb = ttusb->iso_urb[i];
+
+               urb->dev = ttusb->dev;
+               urb->context = ttusb;
+               urb->complete = ttusb_iso_irq;
+               urb->pipe = ttusb->isoc_in_pipe;
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->interval = 1;
+               urb->number_of_packets = FRAMES_PER_ISO_BUF;
+               urb->transfer_buffer_length =
+                   ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
+               urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
+               buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
+
+               for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
+                       frame_offset += ISO_FRAME_SIZE;
+               }
+       }
+
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
+                       ttusb_stop_iso_xfer(ttusb);
+                       printk
+                           ("%s: failed urb submission (%i: err = %i)!\n",
+                            __func__, i, err);
+                       return err;
+               }
+       }
+
+       ttusb->iso_streaming = 1;
+
+       return 0;
+}
+
+#ifdef TTUSB_HWSECTIONS
+static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
+                         int len)
+{
+       dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
+}
+
+static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
+                          int len)
+{
+//      struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
+#error TODO: handle ugly stuff
+//      dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
+}
+#endif
+
+static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
+       int feed_type = 1;
+
+       dprintk("ttusb_start_feed\n");
+
+       switch (dvbdmxfeed->type) {
+       case DMX_TYPE_TS:
+               break;
+       case DMX_TYPE_SEC:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (dvbdmxfeed->type == DMX_TYPE_TS) {
+               switch (dvbdmxfeed->pes_type) {
+               case DMX_TS_PES_VIDEO:
+               case DMX_TS_PES_AUDIO:
+               case DMX_TS_PES_TELETEXT:
+               case DMX_TS_PES_PCR:
+               case DMX_TS_PES_OTHER:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+#ifdef TTUSB_HWSECTIONS
+#error TODO: allocate filters
+       if (dvbdmxfeed->type == DMX_TYPE_TS) {
+               feed_type = 1;
+       } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
+               feed_type = 2;
+       }
+#endif
+
+       ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
+
+       if (0 == ttusb->running_feed_count++)
+               ttusb_start_iso_xfer(ttusb);
+
+       return 0;
+}
+
+static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
+
+       ttusb_del_channel(ttusb, dvbdmxfeed->index);
+
+       if (--ttusb->running_feed_count == 0)
+               ttusb_stop_iso_xfer(ttusb);
+
+       return 0;
+}
+
+static int ttusb_setup_interfaces(struct ttusb *ttusb)
+{
+       usb_set_interface(ttusb->dev, 1, 1);
+
+       ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
+       ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
+       ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
+
+       return 0;
+}
+
+#if 0
+static u8 stc_firmware[8192];
+
+static int stc_open(struct inode *inode, struct file *file)
+{
+       struct ttusb *ttusb = file->private_data;
+       int addr;
+
+       for (addr = 0; addr < 8192; addr += 16) {
+               u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
+               ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
+                             16);
+       }
+
+       return 0;
+}
+
+static ssize_t stc_read(struct file *file, char *buf, size_t count,
+                loff_t *offset)
+{
+       return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
+}
+
+static int stc_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static const struct file_operations stc_fops = {
+       .owner = THIS_MODULE,
+       .read = stc_read,
+       .open = stc_open,
+       .release = stc_release,
+};
+#endif
+
+static u32 functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+
+
+static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+       u8 data[4];
+       struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
+       u32 div;
+
+       div = (p->frequency + 36166667) / 166667;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = ((div >> 10) & 0x60) | 0x85;
+       data[3] = p->frequency < 592000000 ? 0x40 : 0x80;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
+       return 0;
+}
+
+static struct cx22700_config alps_tdmb7_config = {
+       .demod_address = 0x43,
+};
+
+
+
+
+
+static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
+{
+       struct ttusb* ttusb = (struct ttusb*) 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=0x60, .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(&ttusb->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(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
+               i2c_transfer(&ttusb->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 ttusb* ttusb = (struct ttusb*) 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 = 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
+       switch (p->bandwidth_hz) {
+       case 6000000:
+               tda1004x_writereg(fe, 0x0C, 0);
+               filter = 0;
+               break;
+
+       case 7000000:
+               tda1004x_writereg(fe, 0x0C, 0);
+               filter = 0;
+               break;
+
+       case 8000000:
+               tda1004x_writereg(fe, 0x0C, 0xFF);
+               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(&ttusb->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 ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+
+       return request_firmware(fw, name, &ttusb->dev->dev);
+}
+
+static struct tda1004x_config philips_tdm1316l_config = {
+
+       .demod_address = 0x8,
+       .invert = 1,
+       .invert_oclk = 0,
+       .request_firmware = philips_tdm1316l_request_firmware,
+};
+
+static u8 alps_bsbe1_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, LNB power on OP2/LOCK pin on */
+       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 u8 alps_bsru6_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, LNB power on OP2/LOCK pin on */
+       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, 0x52,
+       0xff, 0xff
+};
+
+static int alps_stv0299_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 int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
+
+       if ((p->frequency < 950000) || (p->frequency > 2150000))
+               return -EINVAL;
+
+       div = (p->frequency + (125 - 1)) / 125; /* round correctly */
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       buf[3] = 0xC4;
+
+       if (p->frequency > 1530000)
+               buf[3] = 0xC0;
+
+       /* BSBE1 wants XCE bit set */
+       if (ttusb->revision == TTUSB_REV_2_2)
+               buf[3] |= 0x20;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static struct stv0299_config alps_stv0299_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsru6_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 = alps_stv0299_set_symbol_rate,
+};
+
+static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
+
+       div = p->frequency / 125;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x8e;
+       buf[3] = 0x00;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
+
+       .demod_address = 0x68,
+};
+
+static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusb* ttusb = 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 (&ttusb->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 u8 read_pwm(struct ttusb* ttusb)
+{
+       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(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+               pwm = 0x48;
+
+       return pwm;
+}
+
+
+static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
+       u8 tuner_buf[5];
+       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 = p->frequency;
+       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
+       // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
+       tuner_frequency = ((p->frequency + 36125000) / 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(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
+               printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
+               return -EIO;
+       }
+
+       msleep(50);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
+               printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
+               return -EIO;
+       }
+
+       msleep(1);
+
+       return 0;
+}
+
+static u8 dvbc_philips_tdm1316l_inittab[] = {
+       0x80, 0x21,
+       0x80, 0x20,
+       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, 0xff,
+       0x4b, 0x7f,
+       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, 0x00,
+       0x89, 0x00,
+       0x90, 0x01,
+       0x91, 0x01,
+       0xa0, 0x00,
+       0xa1, 0x00,
+       0xa2, 0x00,
+       0xb0, 0x91,
+       0xb1, 0x0b,
+       0xc0, 0x4b,
+       0xc1, 0x00,
+       0xc2, 0x00,
+       0xd0, 0x00,
+       0xd1, 0x00,
+       0xd2, 0x00,
+       0xd3, 0x00,
+       0xd4, 0x00,
+       0xd5, 0x00,
+       0xde, 0x00,
+       0xdf, 0x00,
+       0x61, 0x38,
+       0x62, 0x0a,
+       0x53, 0x13,
+       0x59, 0x08,
+       0x55, 0x00,
+       0x56, 0x40,
+       0x57, 0x08,
+       0x58, 0x3d,
+       0x88, 0x10,
+       0xa0, 0x00,
+       0xa0, 0x00,
+       0xa0, 0x00,
+       0xa0, 0x04,
+       0xff, 0xff,
+};
+
+static struct stv0297_config dvbc_philips_tdm1316l_config = {
+       .demod_address = 0x1c,
+       .inittab = dvbc_philips_tdm1316l_inittab,
+       .invert = 0,
+};
+
+static void frontend_init(struct ttusb* ttusb)
+{
+       switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
+       case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
+               // try the stv0299 based first
+               ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
+
+                       if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
+                               alps_stv0299_config.inittab = alps_bsbe1_inittab;
+                               dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
+                       } else { // ALPS BSRU6
+                               ttusb->fe->ops.set_voltage = ttusb_set_voltage;
+                       }
+                       break;
+               }
+
+               // Grundig 29504-491
+               ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
+                       ttusb->fe->ops.set_voltage = ttusb_set_voltage;
+                       break;
+               }
+               break;
+
+       case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
+               ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
+                       break;
+               }
+
+               ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
+                       break;
+               }
+               break;
+
+       case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
+               // try the ALPS TDMB7 first
+               ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
+                       break;
+               }
+
+               // Philips td1316
+               ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
+               if (ttusb->fe != NULL) {
+                       ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
+                       ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
+                       break;
+               }
+               break;
+       }
+
+       if (ttusb->fe == NULL) {
+               printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
+                      le16_to_cpu(ttusb->dev->descriptor.idVendor),
+                      le16_to_cpu(ttusb->dev->descriptor.idProduct));
+       } else {
+               if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
+                       printk("dvb-ttusb-budget: Frontend registration failed!\n");
+                       dvb_frontend_detach(ttusb->fe);
+                       ttusb->fe = NULL;
+               }
+       }
+}
+
+
+
+static struct i2c_algorithm ttusb_dec_algo = {
+       .master_xfer    = master_xfer,
+       .functionality  = functionality,
+};
+
+static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       struct usb_device *udev;
+       struct ttusb *ttusb;
+       int result;
+
+       dprintk("%s: TTUSB DVB connected\n", __func__);
+
+       udev = interface_to_usbdev(intf);
+
+       if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
+
+       if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
+               return -ENOMEM;
+
+       ttusb->dev = udev;
+       ttusb->c = 0;
+       ttusb->mux_state = 0;
+       mutex_init(&ttusb->semi2c);
+
+       mutex_lock(&ttusb->semi2c);
+
+       mutex_init(&ttusb->semusb);
+
+       ttusb_setup_interfaces(ttusb);
+
+       result = ttusb_alloc_iso_urbs(ttusb);
+       if (result < 0) {
+               dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
+               mutex_unlock(&ttusb->semi2c);
+               kfree(ttusb);
+               return result;
+       }
+
+       if (ttusb_init_controller(ttusb))
+               printk("ttusb_init_controller: error\n");
+
+       mutex_unlock(&ttusb->semi2c);
+
+       result = dvb_register_adapter(&ttusb->adapter,
+                                     "Technotrend/Hauppauge Nova-USB",
+                                     THIS_MODULE, &udev->dev, adapter_nr);
+       if (result < 0) {
+               ttusb_free_iso_urbs(ttusb);
+               kfree(ttusb);
+               return result;
+       }
+       ttusb->adapter.priv = ttusb;
+
+       /* i2c */
+       memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
+       strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
+
+       i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
+
+       ttusb->i2c_adap.algo              = &ttusb_dec_algo;
+       ttusb->i2c_adap.algo_data         = NULL;
+       ttusb->i2c_adap.dev.parent        = &udev->dev;
+
+       result = i2c_add_adapter(&ttusb->i2c_adap);
+       if (result)
+               goto err_unregister_adapter;
+
+       memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
+
+       ttusb->dvb_demux.dmx.capabilities =
+           DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       ttusb->dvb_demux.priv = NULL;
+#ifdef TTUSB_HWSECTIONS
+       ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
+#else
+       ttusb->dvb_demux.filternum = 32;
+#endif
+       ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
+       ttusb->dvb_demux.start_feed = ttusb_start_feed;
+       ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
+       ttusb->dvb_demux.write_to_decoder = NULL;
+
+       result = dvb_dmx_init(&ttusb->dvb_demux);
+       if (result < 0) {
+               printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
+               result = -ENODEV;
+               goto err_i2c_del_adapter;
+       }
+//FIXME dmxdev (nur WAS?)
+       ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
+       ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
+       ttusb->dmxdev.capabilities = 0;
+
+       result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter);
+       if (result < 0) {
+               printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
+                      result);
+               result = -ENODEV;
+               goto err_release_dmx;
+       }
+
+       if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
+               printk("ttusb_dvb: dvb_net_init failed!\n");
+               result = -ENODEV;
+               goto err_release_dmxdev;
+       }
+
+       usb_set_intfdata(intf, (void *) ttusb);
+
+       frontend_init(ttusb);
+
+       return 0;
+
+err_release_dmxdev:
+       dvb_dmxdev_release(&ttusb->dmxdev);
+err_release_dmx:
+       dvb_dmx_release(&ttusb->dvb_demux);
+err_i2c_del_adapter:
+       i2c_del_adapter(&ttusb->i2c_adap);
+err_unregister_adapter:
+       dvb_unregister_adapter (&ttusb->adapter);
+       return result;
+}
+
+static void ttusb_disconnect(struct usb_interface *intf)
+{
+       struct ttusb *ttusb = usb_get_intfdata(intf);
+
+       usb_set_intfdata(intf, NULL);
+
+       ttusb->disconnecting = 1;
+
+       ttusb_stop_iso_xfer(ttusb);
+
+       ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
+       dvb_net_release(&ttusb->dvbnet);
+       dvb_dmxdev_release(&ttusb->dmxdev);
+       dvb_dmx_release(&ttusb->dvb_demux);
+       if (ttusb->fe != NULL) {
+               dvb_unregister_frontend(ttusb->fe);
+               dvb_frontend_detach(ttusb->fe);
+       }
+       i2c_del_adapter(&ttusb->i2c_adap);
+       dvb_unregister_adapter(&ttusb->adapter);
+
+       ttusb_free_iso_urbs(ttusb);
+
+       kfree(ttusb);
+
+       dprintk("%s: TTUSB DVB disconnected\n", __func__);
+}
+
+static struct usb_device_id ttusb_table[] = {
+       {USB_DEVICE(0xb48, 0x1003)},
+       {USB_DEVICE(0xb48, 0x1004)},
+       {USB_DEVICE(0xb48, 0x1005)},
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, ttusb_table);
+
+static struct usb_driver ttusb_driver = {
+      .name            = "ttusb",
+      .probe           = ttusb_probe,
+      .disconnect      = ttusb_disconnect,
+      .id_table                = ttusb_table,
+};
+
+module_usb_driver(ttusb_driver);
+
+MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
+MODULE_DESCRIPTION("TTUSB DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");
diff --git a/drivers/media/usb/ttusb-dec/Kconfig b/drivers/media/usb/ttusb-dec/Kconfig
new file mode 100644 (file)
index 0000000..290254a
--- /dev/null
@@ -0,0 +1,21 @@
+config DVB_TTUSB_DEC
+       tristate "Technotrend/Hauppauge USB DEC devices"
+       depends on DVB_CORE && USB && INPUT && PCI
+       select CRC32
+       help
+         Support for external USB adapters designed by Technotrend and
+         produced by Hauppauge, shipped under the brand name 'DEC2000-t'
+         and 'DEC3000-s'.
+
+         Even if these devices have a MPEG decoder built in, they transmit
+         only compressed MPEG data over the USB bus, so you need
+         an external software decoder to watch TV on your computer.
+
+         This driver needs external firmware. Please use the commands
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
+         download/extract them, and then copy them to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+         Say Y if you own such a device and want to use it.
diff --git a/drivers/media/usb/ttusb-dec/Makefile b/drivers/media/usb/ttusb-dec/Makefile
new file mode 100644 (file)
index 0000000..5352740
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
+
+ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
new file mode 100644 (file)
index 0000000..504c812
--- /dev/null
@@ -0,0 +1,1764 @@
+/*
+ * TTUSB DEC Driver
+ *
+ * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
+ * IR support by Peter Beutner <p.beutner@gmx.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+#include <linux/input.h>
+
+#include <linux/mutex.h>
+
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_filter.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include "ttusbdecfe.h"
+
+static int debug;
+static int output_pva;
+static int enable_rc;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+module_param(output_pva, int, 0444);
+MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
+module_param(enable_rc, int, 0644);
+MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define dprintk        if (debug) printk
+
+#define DRIVER_NAME            "TechnoTrend/Hauppauge DEC USB"
+
+#define COMMAND_PIPE           0x03
+#define RESULT_PIPE            0x04
+#define IN_PIPE                        0x08
+#define OUT_PIPE               0x07
+#define IRQ_PIPE               0x0A
+
+#define COMMAND_PACKET_SIZE    0x3c
+#define ARM_PACKET_SIZE                0x1000
+#define IRQ_PACKET_SIZE                0x8
+
+#define ISO_BUF_COUNT          0x04
+#define FRAMES_PER_ISO_BUF     0x04
+#define ISO_FRAME_SIZE         0x0380
+
+#define        MAX_PVA_LENGTH          6144
+
+enum ttusb_dec_model {
+       TTUSB_DEC2000T,
+       TTUSB_DEC2540T,
+       TTUSB_DEC3000S
+};
+
+enum ttusb_dec_packet_type {
+       TTUSB_DEC_PACKET_PVA,
+       TTUSB_DEC_PACKET_SECTION,
+       TTUSB_DEC_PACKET_EMPTY
+};
+
+enum ttusb_dec_interface {
+       TTUSB_DEC_INTERFACE_INITIAL,
+       TTUSB_DEC_INTERFACE_IN,
+       TTUSB_DEC_INTERFACE_OUT
+};
+
+struct ttusb_dec {
+       enum ttusb_dec_model            model;
+       char                            *model_name;
+       char                            *firmware_name;
+       int                             can_playback;
+
+       /* DVB bits */
+       struct dvb_adapter              adapter;
+       struct dmxdev                   dmxdev;
+       struct dvb_demux                demux;
+       struct dmx_frontend             frontend;
+       struct dvb_net                  dvb_net;
+       struct dvb_frontend*            fe;
+
+       u16                     pid[DMX_PES_OTHER];
+
+       /* USB bits */
+       struct usb_device               *udev;
+       u8                              trans_count;
+       unsigned int                    command_pipe;
+       unsigned int                    result_pipe;
+       unsigned int                    in_pipe;
+       unsigned int                    out_pipe;
+       unsigned int                    irq_pipe;
+       enum ttusb_dec_interface        interface;
+       struct mutex                    usb_mutex;
+
+       void                    *irq_buffer;
+       struct urb              *irq_urb;
+       dma_addr_t              irq_dma_handle;
+       void                    *iso_buffer;
+       dma_addr_t              iso_dma_handle;
+       struct urb              *iso_urb[ISO_BUF_COUNT];
+       int                     iso_stream_count;
+       struct mutex            iso_mutex;
+
+       u8                              packet[MAX_PVA_LENGTH + 4];
+       enum ttusb_dec_packet_type      packet_type;
+       int                             packet_state;
+       int                             packet_length;
+       int                             packet_payload_length;
+       u16                             next_packet_id;
+
+       int                             pva_stream_count;
+       int                             filter_stream_count;
+
+       struct dvb_filter_pes2ts        a_pes2ts;
+       struct dvb_filter_pes2ts        v_pes2ts;
+
+       u8                      v_pes[16 + MAX_PVA_LENGTH];
+       int                     v_pes_length;
+       int                     v_pes_postbytes;
+
+       struct list_head        urb_frame_list;
+       struct tasklet_struct   urb_tasklet;
+       spinlock_t              urb_frame_list_lock;
+
+       struct dvb_demux_filter *audio_filter;
+       struct dvb_demux_filter *video_filter;
+       struct list_head        filter_info_list;
+       spinlock_t              filter_info_list_lock;
+
+       struct input_dev        *rc_input_dev;
+       char                    rc_phys[64];
+
+       int                     active; /* Loaded successfully */
+};
+
+struct urb_frame {
+       u8                      data[ISO_FRAME_SIZE];
+       int                     length;
+       struct list_head        urb_frame_list;
+};
+
+struct filter_info {
+       u8                      stream_id;
+       struct dvb_demux_filter *filter;
+       struct list_head        filter_info_list;
+};
+
+static u16 rc_keys[] = {
+       KEY_POWER,
+       KEY_MUTE,
+       KEY_1,
+       KEY_2,
+       KEY_3,
+       KEY_4,
+       KEY_5,
+       KEY_6,
+       KEY_7,
+       KEY_8,
+       KEY_9,
+       KEY_0,
+       KEY_CHANNELUP,
+       KEY_VOLUMEDOWN,
+       KEY_OK,
+       KEY_VOLUMEUP,
+       KEY_CHANNELDOWN,
+       KEY_PREVIOUS,
+       KEY_ESC,
+       KEY_RED,
+       KEY_GREEN,
+       KEY_YELLOW,
+       KEY_BLUE,
+       KEY_OPTION,
+       KEY_M,
+       KEY_RADIO
+};
+
+static void ttusb_dec_set_model(struct ttusb_dec *dec,
+                               enum ttusb_dec_model model);
+
+static void ttusb_dec_handle_irq( struct urb *urb)
+{
+       struct ttusb_dec * dec = urb->context;
+       char *buffer = dec->irq_buffer;
+       int retval;
+
+       switch(urb->status) {
+               case 0: /*success*/
+                       break;
+               case -ECONNRESET:
+               case -ENOENT:
+               case -ESHUTDOWN:
+               case -ETIME:
+                       /* this urb is dead, cleanup */
+                       dprintk("%s:urb shutting down with status: %d\n",
+                                       __func__, urb->status);
+                       return;
+               default:
+                       dprintk("%s:nonzero status received: %d\n",
+                                       __func__,urb->status);
+                       goto exit;
+       }
+
+       if( (buffer[0] == 0x1) && (buffer[2] == 0x15) )  {
+               /* IR - Event */
+               /* this is an fact a bit too simple implementation;
+                * the box also reports a keyrepeat signal
+                * (with buffer[3] == 0x40) in an intervall of ~100ms.
+                * But to handle this correctly we had to imlemenent some
+                * kind of timer which signals a 'key up' event if no
+                * keyrepeat signal is received for lets say 200ms.
+                * this should/could be added later ...
+                * for now lets report each signal as a key down and up*/
+               dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
+               input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+               input_sync(dec->rc_input_dev);
+               input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
+               input_sync(dec->rc_input_dev);
+       }
+
+exit:  retval = usb_submit_urb(urb, GFP_ATOMIC);
+       if(retval)
+               printk("%s - usb_commit_urb failed with result: %d\n",
+                       __func__, retval);
+}
+
+static u16 crc16(u16 crc, const u8 *buf, size_t len)
+{
+       u16 tmp;
+
+       while (len--) {
+               crc ^= *buf++;
+               crc ^= (u8)crc >> 4;
+               tmp = (u8)crc;
+               crc ^= (tmp ^ (tmp << 1)) << 4;
+       }
+       return crc;
+}
+
+static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
+                                 int param_length, const u8 params[],
+                                 int *result_length, u8 cmd_result[])
+{
+       int result, actual_len, i;
+       u8 *b;
+
+       dprintk("%s\n", __func__);
+
+       b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
+               kfree(b);
+               printk("%s: Failed to lock usb mutex.\n", __func__);
+               return result;
+       }
+
+       b[0] = 0xaa;
+       b[1] = ++dec->trans_count;
+       b[2] = command;
+       b[3] = param_length;
+
+       if (params)
+               memcpy(&b[4], params, param_length);
+
+       if (debug) {
+               printk("%s: command: ", __func__);
+               for (i = 0; i < param_length + 4; i++)
+                       printk("0x%02X ", b[i]);
+               printk("\n");
+       }
+
+       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
+                             COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
+
+       if (result) {
+               printk("%s: command bulk message failed: error %d\n",
+                      __func__, result);
+               mutex_unlock(&dec->usb_mutex);
+               kfree(b);
+               return result;
+       }
+
+       result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
+                             COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
+
+       if (result) {
+               printk("%s: result bulk message failed: error %d\n",
+                      __func__, result);
+               mutex_unlock(&dec->usb_mutex);
+               kfree(b);
+               return result;
+       } else {
+               if (debug) {
+                       printk("%s: result: ", __func__);
+                       for (i = 0; i < actual_len; i++)
+                               printk("0x%02X ", b[i]);
+                       printk("\n");
+               }
+
+               if (result_length)
+                       *result_length = b[3];
+               if (cmd_result && b[3] > 0)
+                       memcpy(cmd_result, &b[4], b[3]);
+
+               mutex_unlock(&dec->usb_mutex);
+
+               kfree(b);
+               return 0;
+       }
+}
+
+static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
+                                   unsigned int *model, unsigned int *version)
+{
+       u8 c[COMMAND_PACKET_SIZE];
+       int c_length;
+       int result;
+       __be32 tmp;
+
+       dprintk("%s\n", __func__);
+
+       result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
+       if (result)
+               return result;
+
+       if (c_length >= 0x0c) {
+               if (mode != NULL) {
+                       memcpy(&tmp, c, 4);
+                       *mode = ntohl(tmp);
+               }
+               if (model != NULL) {
+                       memcpy(&tmp, &c[4], 4);
+                       *model = ntohl(tmp);
+               }
+               if (version != NULL) {
+                       memcpy(&tmp, &c[8], 4);
+                       *version = ntohl(tmp);
+               }
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
+{
+       struct ttusb_dec *dec = priv;
+
+       dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
+                                      &dec->audio_filter->feed->feed.ts,
+                                      DMX_OK);
+
+       return 0;
+}
+
+static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
+{
+       struct ttusb_dec *dec = priv;
+
+       dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
+                                      &dec->video_filter->feed->feed.ts,
+                                      DMX_OK);
+
+       return 0;
+}
+
+static void ttusb_dec_set_pids(struct ttusb_dec *dec)
+{
+       u8 b[] = { 0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0xff, 0xff,
+                  0xff, 0xff, 0xff, 0xff };
+
+       __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
+       __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
+       __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
+
+       dprintk("%s\n", __func__);
+
+       memcpy(&b[0], &pcr, 2);
+       memcpy(&b[2], &audio, 2);
+       memcpy(&b[4], &video, 2);
+
+       ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
+
+       dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
+                              ttusb_dec_audio_pes2ts_cb, dec);
+       dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
+                              ttusb_dec_video_pes2ts_cb, dec);
+       dec->v_pes_length = 0;
+       dec->v_pes_postbytes = 0;
+}
+
+static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
+{
+       if (length < 8) {
+               printk("%s: packet too short - discarding\n", __func__);
+               return;
+       }
+
+       if (length > 8 + MAX_PVA_LENGTH) {
+               printk("%s: packet too long - discarding\n", __func__);
+               return;
+       }
+
+       switch (pva[2]) {
+
+       case 0x01: {            /* VideoStream */
+               int prebytes = pva[5] & 0x03;
+               int postbytes = (pva[5] & 0x0c) >> 2;
+               __be16 v_pes_payload_length;
+
+               if (output_pva) {
+                       dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
+                               &dec->video_filter->feed->feed.ts, DMX_OK);
+                       return;
+               }
+
+               if (dec->v_pes_postbytes > 0 &&
+                   dec->v_pes_postbytes == prebytes) {
+                       memcpy(&dec->v_pes[dec->v_pes_length],
+                              &pva[12], prebytes);
+
+                       dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
+                                         dec->v_pes_length + prebytes, 1);
+               }
+
+               if (pva[5] & 0x10) {
+                       dec->v_pes[7] = 0x80;
+                       dec->v_pes[8] = 0x05;
+
+                       dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
+                       dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
+                                        ((pva[9] & 0xc0) >> 6);
+                       dec->v_pes[11] = 0x01 |
+                                        ((pva[9] & 0x3f) << 2) |
+                                        ((pva[10] & 0x80) >> 6);
+                       dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
+                                        ((pva[11] & 0xc0) >> 7);
+                       dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
+
+                       memcpy(&dec->v_pes[14], &pva[12 + prebytes],
+                              length - 12 - prebytes);
+                       dec->v_pes_length = 14 + length - 12 - prebytes;
+               } else {
+                       dec->v_pes[7] = 0x00;
+                       dec->v_pes[8] = 0x00;
+
+                       memcpy(&dec->v_pes[9], &pva[8], length - 8);
+                       dec->v_pes_length = 9 + length - 8;
+               }
+
+               dec->v_pes_postbytes = postbytes;
+
+               if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
+                   dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
+                   dec->v_pes[11 + dec->v_pes[8]] == 0x01)
+                       dec->v_pes[6] = 0x84;
+               else
+                       dec->v_pes[6] = 0x80;
+
+               v_pes_payload_length = htons(dec->v_pes_length - 6 +
+                                            postbytes);
+               memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
+
+               if (postbytes == 0)
+                       dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
+                                         dec->v_pes_length, 1);
+
+               break;
+       }
+
+       case 0x02:              /* MainAudioStream */
+               if (output_pva) {
+                       dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
+                               &dec->audio_filter->feed->feed.ts, DMX_OK);
+                       return;
+               }
+
+               dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
+                                 pva[5] & 0x10);
+               break;
+
+       default:
+               printk("%s: unknown PVA type: %02x.\n", __func__,
+                      pva[2]);
+               break;
+       }
+}
+
+static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
+                                    int length)
+{
+       struct list_head *item;
+       struct filter_info *finfo;
+       struct dvb_demux_filter *filter = NULL;
+       unsigned long flags;
+       u8 sid;
+
+       sid = packet[1];
+       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
+       for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
+            item = item->next) {
+               finfo = list_entry(item, struct filter_info, filter_info_list);
+               if (finfo->stream_id == sid) {
+                       filter = finfo->filter;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
+
+       if (filter)
+               filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
+                                    &filter->filter, DMX_OK);
+}
+
+static void ttusb_dec_process_packet(struct ttusb_dec *dec)
+{
+       int i;
+       u16 csum = 0;
+       u16 packet_id;
+
+       if (dec->packet_length % 2) {
+               printk("%s: odd sized packet - discarding\n", __func__);
+               return;
+       }
+
+       for (i = 0; i < dec->packet_length; i += 2)
+               csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
+
+       if (csum) {
+               printk("%s: checksum failed - discarding\n", __func__);
+               return;
+       }
+
+       packet_id = dec->packet[dec->packet_length - 4] << 8;
+       packet_id += dec->packet[dec->packet_length - 3];
+
+       if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
+               printk("%s: warning: lost packets between %u and %u\n",
+                      __func__, dec->next_packet_id - 1, packet_id);
+       }
+
+       if (packet_id == 0xffff)
+               dec->next_packet_id = 0x8000;
+       else
+               dec->next_packet_id = packet_id + 1;
+
+       switch (dec->packet_type) {
+       case TTUSB_DEC_PACKET_PVA:
+               if (dec->pva_stream_count)
+                       ttusb_dec_process_pva(dec, dec->packet,
+                                             dec->packet_payload_length);
+               break;
+
+       case TTUSB_DEC_PACKET_SECTION:
+               if (dec->filter_stream_count)
+                       ttusb_dec_process_filter(dec, dec->packet,
+                                                dec->packet_payload_length);
+               break;
+
+       case TTUSB_DEC_PACKET_EMPTY:
+               break;
+       }
+}
+
+static void swap_bytes(u8 *b, int length)
+{
+       u8 c;
+
+       length -= length % 2;
+       for (; length; b += 2, length -= 2) {
+               c = *b;
+               *b = *(b + 1);
+               *(b + 1) = c;
+       }
+}
+
+static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
+                                       int length)
+{
+       swap_bytes(b, length);
+
+       while (length) {
+               switch (dec->packet_state) {
+
+               case 0:
+               case 1:
+               case 2:
+                       if (*b++ == 0xaa)
+                               dec->packet_state++;
+                       else
+                               dec->packet_state = 0;
+
+                       length--;
+                       break;
+
+               case 3:
+                       if (*b == 0x00) {
+                               dec->packet_state++;
+                               dec->packet_length = 0;
+                       } else if (*b != 0xaa) {
+                               dec->packet_state = 0;
+                       }
+
+                       b++;
+                       length--;
+                       break;
+
+               case 4:
+                       dec->packet[dec->packet_length++] = *b++;
+
+                       if (dec->packet_length == 2) {
+                               if (dec->packet[0] == 'A' &&
+                                   dec->packet[1] == 'V') {
+                                       dec->packet_type =
+                                               TTUSB_DEC_PACKET_PVA;
+                                       dec->packet_state++;
+                               } else if (dec->packet[0] == 'S') {
+                                       dec->packet_type =
+                                               TTUSB_DEC_PACKET_SECTION;
+                                       dec->packet_state++;
+                               } else if (dec->packet[0] == 0x00) {
+                                       dec->packet_type =
+                                               TTUSB_DEC_PACKET_EMPTY;
+                                       dec->packet_payload_length = 2;
+                                       dec->packet_state = 7;
+                               } else {
+                                       printk("%s: unknown packet type: "
+                                              "%02x%02x\n", __func__,
+                                              dec->packet[0], dec->packet[1]);
+                                       dec->packet_state = 0;
+                               }
+                       }
+
+                       length--;
+                       break;
+
+               case 5:
+                       dec->packet[dec->packet_length++] = *b++;
+
+                       if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
+                           dec->packet_length == 8) {
+                               dec->packet_state++;
+                               dec->packet_payload_length = 8 +
+                                       (dec->packet[6] << 8) +
+                                       dec->packet[7];
+                       } else if (dec->packet_type ==
+                                       TTUSB_DEC_PACKET_SECTION &&
+                                  dec->packet_length == 5) {
+                               dec->packet_state++;
+                               dec->packet_payload_length = 5 +
+                                       ((dec->packet[3] & 0x0f) << 8) +
+                                       dec->packet[4];
+                       }
+
+                       length--;
+                       break;
+
+               case 6: {
+                       int remainder = dec->packet_payload_length -
+                                       dec->packet_length;
+
+                       if (length >= remainder) {
+                               memcpy(dec->packet + dec->packet_length,
+                                      b, remainder);
+                               dec->packet_length += remainder;
+                               b += remainder;
+                               length -= remainder;
+                               dec->packet_state++;
+                       } else {
+                               memcpy(&dec->packet[dec->packet_length],
+                                      b, length);
+                               dec->packet_length += length;
+                               length = 0;
+                       }
+
+                       break;
+               }
+
+               case 7: {
+                       int tail = 4;
+
+                       dec->packet[dec->packet_length++] = *b++;
+
+                       if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
+                           dec->packet_payload_length % 2)
+                               tail++;
+
+                       if (dec->packet_length ==
+                           dec->packet_payload_length + tail) {
+                               ttusb_dec_process_packet(dec);
+                               dec->packet_state = 0;
+                       }
+
+                       length--;
+                       break;
+               }
+
+               default:
+                       printk("%s: illegal packet state encountered.\n",
+                              __func__);
+                       dec->packet_state = 0;
+               }
+       }
+}
+
+static void ttusb_dec_process_urb_frame_list(unsigned long data)
+{
+       struct ttusb_dec *dec = (struct ttusb_dec *)data;
+       struct list_head *item;
+       struct urb_frame *frame;
+       unsigned long flags;
+
+       while (1) {
+               spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
+               if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
+                       frame = list_entry(item, struct urb_frame,
+                                          urb_frame_list);
+                       list_del(&frame->urb_frame_list);
+               } else {
+                       spin_unlock_irqrestore(&dec->urb_frame_list_lock,
+                                              flags);
+                       return;
+               }
+               spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
+
+               ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
+               kfree(frame);
+       }
+}
+
+static void ttusb_dec_process_urb(struct urb *urb)
+{
+       struct ttusb_dec *dec = urb->context;
+
+       if (!urb->status) {
+               int i;
+
+               for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
+                       struct usb_iso_packet_descriptor *d;
+                       u8 *b;
+                       int length;
+                       struct urb_frame *frame;
+
+                       d = &urb->iso_frame_desc[i];
+                       b = urb->transfer_buffer + d->offset;
+                       length = d->actual_length;
+
+                       if ((frame = kmalloc(sizeof(struct urb_frame),
+                                            GFP_ATOMIC))) {
+                               unsigned long flags;
+
+                               memcpy(frame->data, b, length);
+                               frame->length = length;
+
+                               spin_lock_irqsave(&dec->urb_frame_list_lock,
+                                                    flags);
+                               list_add_tail(&frame->urb_frame_list,
+                                             &dec->urb_frame_list);
+                               spin_unlock_irqrestore(&dec->urb_frame_list_lock,
+                                                      flags);
+
+                               tasklet_schedule(&dec->urb_tasklet);
+                       }
+               }
+       } else {
+                /* -ENOENT is expected when unlinking urbs */
+               if (urb->status != -ENOENT)
+                       dprintk("%s: urb error: %d\n", __func__,
+                               urb->status);
+       }
+
+       if (dec->iso_stream_count)
+               usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
+{
+       int i, j, buffer_offset = 0;
+
+       dprintk("%s\n", __func__);
+
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               int frame_offset = 0;
+               struct urb *urb = dec->iso_urb[i];
+
+               urb->dev = dec->udev;
+               urb->context = dec;
+               urb->complete = ttusb_dec_process_urb;
+               urb->pipe = dec->in_pipe;
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->interval = 1;
+               urb->number_of_packets = FRAMES_PER_ISO_BUF;
+               urb->transfer_buffer_length = ISO_FRAME_SIZE *
+                                             FRAMES_PER_ISO_BUF;
+               urb->transfer_buffer = dec->iso_buffer + buffer_offset;
+               buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
+
+               for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
+                       frame_offset += ISO_FRAME_SIZE;
+               }
+       }
+}
+
+static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
+{
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       if (mutex_lock_interruptible(&dec->iso_mutex))
+               return;
+
+       dec->iso_stream_count--;
+
+       if (!dec->iso_stream_count) {
+               for (i = 0; i < ISO_BUF_COUNT; i++)
+                       usb_kill_urb(dec->iso_urb[i]);
+       }
+
+       mutex_unlock(&dec->iso_mutex);
+}
+
+/* Setting the interface of the DEC tends to take down the USB communications
+ * for a short period, so it's important not to call this function just before
+ * trying to talk to it.
+ */
+static int ttusb_dec_set_interface(struct ttusb_dec *dec,
+                                  enum ttusb_dec_interface interface)
+{
+       int result = 0;
+       u8 b[] = { 0x05 };
+
+       if (interface != dec->interface) {
+               switch (interface) {
+               case TTUSB_DEC_INTERFACE_INITIAL:
+                       result = usb_set_interface(dec->udev, 0, 0);
+                       break;
+               case TTUSB_DEC_INTERFACE_IN:
+                       result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
+                                                       b, NULL, NULL);
+                       if (result)
+                               return result;
+                       result = usb_set_interface(dec->udev, 0, 8);
+                       break;
+               case TTUSB_DEC_INTERFACE_OUT:
+                       result = usb_set_interface(dec->udev, 0, 1);
+                       break;
+               }
+
+               if (result)
+                       return result;
+
+               dec->interface = interface;
+       }
+
+       return 0;
+}
+
+static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
+{
+       int i, result;
+
+       dprintk("%s\n", __func__);
+
+       if (mutex_lock_interruptible(&dec->iso_mutex))
+               return -EAGAIN;
+
+       if (!dec->iso_stream_count) {
+               ttusb_dec_setup_urbs(dec);
+
+               dec->packet_state = 0;
+               dec->v_pes_postbytes = 0;
+               dec->next_packet_id = 0;
+
+               for (i = 0; i < ISO_BUF_COUNT; i++) {
+                       if ((result = usb_submit_urb(dec->iso_urb[i],
+                                                    GFP_ATOMIC))) {
+                               printk("%s: failed urb submission %d: "
+                                      "error %d\n", __func__, i, result);
+
+                               while (i) {
+                                       usb_kill_urb(dec->iso_urb[i - 1]);
+                                       i--;
+                               }
+
+                               mutex_unlock(&dec->iso_mutex);
+                               return result;
+                       }
+               }
+       }
+
+       dec->iso_stream_count++;
+
+       mutex_unlock(&dec->iso_mutex);
+
+       return 0;
+}
+
+static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+       struct ttusb_dec *dec = dvbdmx->priv;
+       u8 b0[] = { 0x05 };
+       int result = 0;
+
+       dprintk("%s\n", __func__);
+
+       dprintk("  ts_type:");
+
+       if (dvbdmxfeed->ts_type & TS_DECODER)
+               dprintk(" TS_DECODER");
+
+       if (dvbdmxfeed->ts_type & TS_PACKET)
+               dprintk(" TS_PACKET");
+
+       if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
+               dprintk(" TS_PAYLOAD_ONLY");
+
+       dprintk("\n");
+
+       switch (dvbdmxfeed->pes_type) {
+
+       case DMX_TS_PES_VIDEO:
+               dprintk("  pes_type: DMX_TS_PES_VIDEO\n");
+               dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
+               dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
+               dec->video_filter = dvbdmxfeed->filter;
+               ttusb_dec_set_pids(dec);
+               break;
+
+       case DMX_TS_PES_AUDIO:
+               dprintk("  pes_type: DMX_TS_PES_AUDIO\n");
+               dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
+               dec->audio_filter = dvbdmxfeed->filter;
+               ttusb_dec_set_pids(dec);
+               break;
+
+       case DMX_TS_PES_TELETEXT:
+               dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
+               dprintk("  pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
+               return -ENOSYS;
+
+       case DMX_TS_PES_PCR:
+               dprintk("  pes_type: DMX_TS_PES_PCR\n");
+               dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
+               ttusb_dec_set_pids(dec);
+               break;
+
+       case DMX_TS_PES_OTHER:
+               dprintk("  pes_type: DMX_TS_PES_OTHER(not supported)\n");
+               return -ENOSYS;
+
+       default:
+               dprintk("  pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
+               return -EINVAL;
+
+       }
+
+       result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
+       if (result)
+               return result;
+
+       dec->pva_stream_count++;
+       return ttusb_dec_start_iso_xfer(dec);
+}
+
+static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
+       u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x00, 0xff, 0x00, 0x00,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x00 };
+       __be16 pid;
+       u8 c[COMMAND_PACKET_SIZE];
+       int c_length;
+       int result;
+       struct filter_info *finfo;
+       unsigned long flags;
+       u8 x = 1;
+
+       dprintk("%s\n", __func__);
+
+       pid = htons(dvbdmxfeed->pid);
+       memcpy(&b0[0], &pid, 2);
+       memcpy(&b0[4], &x, 1);
+       memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
+
+       result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
+                                       &c_length, c);
+
+       if (!result) {
+               if (c_length == 2) {
+                       if (!(finfo = kmalloc(sizeof(struct filter_info),
+                                             GFP_ATOMIC)))
+                               return -ENOMEM;
+
+                       finfo->stream_id = c[1];
+                       finfo->filter = dvbdmxfeed->filter;
+
+                       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
+                       list_add_tail(&finfo->filter_info_list,
+                                     &dec->filter_info_list);
+                       spin_unlock_irqrestore(&dec->filter_info_list_lock,
+                                              flags);
+
+                       dvbdmxfeed->priv = finfo;
+
+                       dec->filter_stream_count++;
+                       return ttusb_dec_start_iso_xfer(dec);
+               }
+
+               return -EAGAIN;
+       } else
+               return result;
+}
+
+static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+
+       dprintk("%s\n", __func__);
+
+       if (!dvbdmx->dmx.frontend)
+               return -EINVAL;
+
+       dprintk("  pid: 0x%04X\n", dvbdmxfeed->pid);
+
+       switch (dvbdmxfeed->type) {
+
+       case DMX_TYPE_TS:
+               return ttusb_dec_start_ts_feed(dvbdmxfeed);
+               break;
+
+       case DMX_TYPE_SEC:
+               return ttusb_dec_start_sec_feed(dvbdmxfeed);
+               break;
+
+       default:
+               dprintk("  type: unknown (%d)\n", dvbdmxfeed->type);
+               return -EINVAL;
+
+       }
+}
+
+static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
+       u8 b0[] = { 0x00 };
+
+       ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
+
+       dec->pva_stream_count--;
+
+       ttusb_dec_stop_iso_xfer(dec);
+
+       return 0;
+}
+
+static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
+       u8 b0[] = { 0x00, 0x00 };
+       struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
+       unsigned long flags;
+
+       b0[1] = finfo->stream_id;
+       spin_lock_irqsave(&dec->filter_info_list_lock, flags);
+       list_del(&finfo->filter_info_list);
+       spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
+       kfree(finfo);
+       ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
+
+       dec->filter_stream_count--;
+
+       ttusb_dec_stop_iso_xfer(dec);
+
+       return 0;
+}
+
+static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       dprintk("%s\n", __func__);
+
+       switch (dvbdmxfeed->type) {
+       case DMX_TYPE_TS:
+               return ttusb_dec_stop_ts_feed(dvbdmxfeed);
+               break;
+
+       case DMX_TYPE_SEC:
+               return ttusb_dec_stop_sec_feed(dvbdmxfeed);
+               break;
+       }
+
+       return 0;
+}
+
+static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
+{
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       for (i = 0; i < ISO_BUF_COUNT; i++)
+               usb_free_urb(dec->iso_urb[i]);
+
+       pci_free_consistent(NULL,
+                           ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
+                                             ISO_BUF_COUNT),
+                           dec->iso_buffer, dec->iso_dma_handle);
+}
+
+static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
+{
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       dec->iso_buffer = pci_alloc_consistent(NULL,
+                                              ISO_FRAME_SIZE *
+                                              (FRAMES_PER_ISO_BUF *
+                                               ISO_BUF_COUNT),
+                                              &dec->iso_dma_handle);
+
+       if (!dec->iso_buffer) {
+               dprintk("%s: pci_alloc_consistent - not enough memory\n",
+                       __func__);
+               return -ENOMEM;
+       }
+
+       memset(dec->iso_buffer, 0,
+              ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
+
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               struct urb *urb;
+
+               if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
+                       ttusb_dec_free_iso_urbs(dec);
+                       return -ENOMEM;
+               }
+
+               dec->iso_urb[i] = urb;
+       }
+
+       ttusb_dec_setup_urbs(dec);
+
+       return 0;
+}
+
+static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
+{
+       spin_lock_init(&dec->urb_frame_list_lock);
+       INIT_LIST_HEAD(&dec->urb_frame_list);
+       tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
+                    (unsigned long)dec);
+}
+
+static int ttusb_init_rc( struct ttusb_dec *dec)
+{
+       struct input_dev *input_dev;
+       u8 b[] = { 0x00, 0x01 };
+       int i;
+       int err;
+
+       usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
+       strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
+
+       input_dev = input_allocate_device();
+       if (!input_dev)
+               return -ENOMEM;
+
+       input_dev->name = "ttusb_dec remote control";
+       input_dev->phys = dec->rc_phys;
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       input_dev->keycodesize = sizeof(u16);
+       input_dev->keycodemax = 0x1a;
+       input_dev->keycode = rc_keys;
+
+       for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+                 set_bit(rc_keys[i], input_dev->keybit);
+
+       err = input_register_device(input_dev);
+       if (err) {
+               input_free_device(input_dev);
+               return err;
+       }
+
+       dec->rc_input_dev = input_dev;
+       if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
+               printk("%s: usb_submit_urb failed\n",__func__);
+       /* enable irq pipe */
+       ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
+
+       return 0;
+}
+
+static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
+{
+       dprintk("%s\n", __func__);
+
+       dec->v_pes[0] = 0x00;
+       dec->v_pes[1] = 0x00;
+       dec->v_pes[2] = 0x01;
+       dec->v_pes[3] = 0xe0;
+}
+
+static int ttusb_dec_init_usb(struct ttusb_dec *dec)
+{
+       dprintk("%s\n", __func__);
+
+       mutex_init(&dec->usb_mutex);
+       mutex_init(&dec->iso_mutex);
+
+       dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
+       dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
+       dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
+       dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
+       dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
+
+       if(enable_rc) {
+               dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+               if(!dec->irq_urb) {
+                       return -ENOMEM;
+               }
+               dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
+                                       GFP_ATOMIC, &dec->irq_dma_handle);
+               if(!dec->irq_buffer) {
+                       usb_free_urb(dec->irq_urb);
+                       return -ENOMEM;
+               }
+               usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
+                                dec->irq_buffer, IRQ_PACKET_SIZE,
+                                ttusb_dec_handle_irq, dec, 1);
+               dec->irq_urb->transfer_dma = dec->irq_dma_handle;
+               dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       }
+
+       return ttusb_dec_alloc_iso_urbs(dec);
+}
+
+static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
+{
+       int i, j, actual_len, result, size, trans_count;
+       u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
+                   0x00, 0x00, 0x00, 0x00,
+                   0x61, 0x00 };
+       u8 b1[] = { 0x61 };
+       u8 *b;
+       char idstring[21];
+       const u8 *firmware = NULL;
+       size_t firmware_size = 0;
+       u16 firmware_csum = 0;
+       __be16 firmware_csum_ns;
+       __be32 firmware_size_nl;
+       u32 crc32_csum, crc32_check;
+       __be32 tmp;
+       const struct firmware *fw_entry = NULL;
+
+       dprintk("%s\n", __func__);
+
+       if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
+               printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
+                      __func__, dec->firmware_name);
+               return 1;
+       }
+
+       firmware = fw_entry->data;
+       firmware_size = fw_entry->size;
+
+       if (firmware_size < 60) {
+               printk("%s: firmware size too small for DSP code (%zu < 60).\n",
+                       __func__, firmware_size);
+               release_firmware(fw_entry);
+               return -1;
+       }
+
+       /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
+          at offset 56 of file, so use it to check if the firmware file is
+          valid. */
+       crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
+       memcpy(&tmp, &firmware[56], 4);
+       crc32_check = ntohl(tmp);
+       if (crc32_csum != crc32_check) {
+               printk("%s: crc32 check of DSP code failed (calculated "
+                      "0x%08x != 0x%08x in file), file invalid.\n",
+                       __func__, crc32_csum, crc32_check);
+               release_firmware(fw_entry);
+               return -1;
+       }
+       memcpy(idstring, &firmware[36], 20);
+       idstring[20] = '\0';
+       printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
+
+       firmware_size_nl = htonl(firmware_size);
+       memcpy(b0, &firmware_size_nl, 4);
+       firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
+       firmware_csum_ns = htons(firmware_csum);
+       memcpy(&b0[6], &firmware_csum_ns, 2);
+
+       result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
+
+       if (result) {
+               release_firmware(fw_entry);
+               return result;
+       }
+
+       trans_count = 0;
+       j = 0;
+
+       b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
+       if (b == NULL) {
+               release_firmware(fw_entry);
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
+               size = firmware_size - i;
+               if (size > COMMAND_PACKET_SIZE)
+                       size = COMMAND_PACKET_SIZE;
+
+               b[j + 0] = 0xaa;
+               b[j + 1] = trans_count++;
+               b[j + 2] = 0xf0;
+               b[j + 3] = size;
+               memcpy(&b[j + 4], &firmware[i], size);
+
+               j += COMMAND_PACKET_SIZE + 4;
+
+               if (j >= ARM_PACKET_SIZE) {
+                       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
+                                             ARM_PACKET_SIZE, &actual_len,
+                                             100);
+                       j = 0;
+               } else if (size < COMMAND_PACKET_SIZE) {
+                       result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
+                                             j - COMMAND_PACKET_SIZE + size,
+                                             &actual_len, 100);
+               }
+       }
+
+       result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
+
+       release_firmware(fw_entry);
+       kfree(b);
+
+       return result;
+}
+
+static int ttusb_dec_init_stb(struct ttusb_dec *dec)
+{
+       int result;
+       unsigned int mode = 0, model = 0, version = 0;
+
+       dprintk("%s\n", __func__);
+
+       result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
+
+       if (!result) {
+               if (!mode) {
+                       if (version == 0xABCDEFAB)
+                               printk(KERN_INFO "ttusb_dec: no version "
+                                      "info in Firmware\n");
+                       else
+                               printk(KERN_INFO "ttusb_dec: Firmware "
+                                      "%x.%02x%c%c\n",
+                                      version >> 24, (version >> 16) & 0xff,
+                                      (version >> 8) & 0xff, version & 0xff);
+
+                       result = ttusb_dec_boot_dsp(dec);
+                       if (result)
+                               return result;
+                       else
+                               return 1;
+               } else {
+                       /* We can't trust the USB IDs that some firmwares
+                          give the box */
+                       switch (model) {
+                       case 0x00070001:
+                       case 0x00070008:
+                       case 0x0007000c:
+                               ttusb_dec_set_model(dec, TTUSB_DEC3000S);
+                               break;
+                       case 0x00070009:
+                       case 0x00070013:
+                               ttusb_dec_set_model(dec, TTUSB_DEC2000T);
+                               break;
+                       case 0x00070011:
+                               ttusb_dec_set_model(dec, TTUSB_DEC2540T);
+                               break;
+                       default:
+                               printk(KERN_ERR "%s: unknown model returned "
+                                      "by firmware (%08x) - please report\n",
+                                      __func__, model);
+                               return -1;
+                               break;
+                       }
+
+                       if (version >= 0x01770000)
+                               dec->can_playback = 1;
+
+                       return 0;
+               }
+       }
+       else
+               return result;
+}
+
+static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
+{
+       int result;
+
+       dprintk("%s\n", __func__);
+
+       if ((result = dvb_register_adapter(&dec->adapter,
+                                          dec->model_name, THIS_MODULE,
+                                          &dec->udev->dev,
+                                          adapter_nr)) < 0) {
+               printk("%s: dvb_register_adapter failed: error %d\n",
+                      __func__, result);
+
+               return result;
+       }
+
+       dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+
+       dec->demux.priv = (void *)dec;
+       dec->demux.filternum = 31;
+       dec->demux.feednum = 31;
+       dec->demux.start_feed = ttusb_dec_start_feed;
+       dec->demux.stop_feed = ttusb_dec_stop_feed;
+       dec->demux.write_to_decoder = NULL;
+
+       if ((result = dvb_dmx_init(&dec->demux)) < 0) {
+               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
+                      result);
+
+               dvb_unregister_adapter(&dec->adapter);
+
+               return result;
+       }
+
+       dec->dmxdev.filternum = 32;
+       dec->dmxdev.demux = &dec->demux.dmx;
+       dec->dmxdev.capabilities = 0;
+
+       if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
+               printk("%s: dvb_dmxdev_init failed: error %d\n",
+                      __func__, result);
+
+               dvb_dmx_release(&dec->demux);
+               dvb_unregister_adapter(&dec->adapter);
+
+               return result;
+       }
+
+       dec->frontend.source = DMX_FRONTEND_0;
+
+       if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
+                                                 &dec->frontend)) < 0) {
+               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
+                      result);
+
+               dvb_dmxdev_release(&dec->dmxdev);
+               dvb_dmx_release(&dec->demux);
+               dvb_unregister_adapter(&dec->adapter);
+
+               return result;
+       }
+
+       if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
+                                                     &dec->frontend)) < 0) {
+               printk("%s: dvb_dmx_init failed: error %d\n", __func__,
+                      result);
+
+               dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
+               dvb_dmxdev_release(&dec->dmxdev);
+               dvb_dmx_release(&dec->demux);
+               dvb_unregister_adapter(&dec->adapter);
+
+               return result;
+       }
+
+       dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
+
+       return 0;
+}
+
+static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
+{
+       dprintk("%s\n", __func__);
+
+       dvb_net_release(&dec->dvb_net);
+       dec->demux.dmx.close(&dec->demux.dmx);
+       dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
+       dvb_dmxdev_release(&dec->dmxdev);
+       dvb_dmx_release(&dec->demux);
+       if (dec->fe) {
+               dvb_unregister_frontend(dec->fe);
+               if (dec->fe->ops.release)
+                       dec->fe->ops.release(dec->fe);
+       }
+       dvb_unregister_adapter(&dec->adapter);
+}
+
+static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
+{
+
+       dprintk("%s\n", __func__);
+       /* we have to check whether the irq URB is already submitted.
+         * As the irq is submitted after the interface is changed,
+         * this is the best method i figured out.
+         * Any others?*/
+       if (dec->interface == TTUSB_DEC_INTERFACE_IN)
+               usb_kill_urb(dec->irq_urb);
+
+       usb_free_urb(dec->irq_urb);
+
+       usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,
+                         dec->irq_buffer, dec->irq_dma_handle);
+
+       if (dec->rc_input_dev) {
+               input_unregister_device(dec->rc_input_dev);
+               dec->rc_input_dev = NULL;
+       }
+}
+
+
+static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
+{
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       dec->iso_stream_count = 0;
+
+       for (i = 0; i < ISO_BUF_COUNT; i++)
+               usb_kill_urb(dec->iso_urb[i]);
+
+       ttusb_dec_free_iso_urbs(dec);
+}
+
+static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
+{
+       struct list_head *item;
+       struct urb_frame *frame;
+
+       tasklet_kill(&dec->urb_tasklet);
+
+       while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
+               frame = list_entry(item, struct urb_frame, urb_frame_list);
+               list_del(&frame->urb_frame_list);
+               kfree(frame);
+       }
+}
+
+static void ttusb_dec_init_filters(struct ttusb_dec *dec)
+{
+       INIT_LIST_HEAD(&dec->filter_info_list);
+       spin_lock_init(&dec->filter_info_list_lock);
+}
+
+static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
+{
+       struct list_head *item;
+       struct filter_info *finfo;
+
+       while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
+               finfo = list_entry(item, struct filter_info, filter_info_list);
+               list_del(&finfo->filter_info_list);
+               kfree(finfo);
+       }
+}
+
+static int fe_send_command(struct dvb_frontend* fe, const u8 command,
+                          int param_length, const u8 params[],
+                          int *result_length, u8 cmd_result[])
+{
+       struct ttusb_dec* dec = fe->dvb->priv;
+       return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
+}
+
+static struct ttusbdecfe_config fe_config = {
+       .send_command = fe_send_command
+};
+
+static int ttusb_dec_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+{
+       struct usb_device *udev;
+       struct ttusb_dec *dec;
+
+       dprintk("%s\n", __func__);
+
+       udev = interface_to_usbdev(intf);
+
+       if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
+               printk("%s: couldn't allocate memory.\n", __func__);
+               return -ENOMEM;
+       }
+
+       usb_set_intfdata(intf, (void *)dec);
+
+       switch (id->idProduct) {
+       case 0x1006:
+               ttusb_dec_set_model(dec, TTUSB_DEC3000S);
+               break;
+
+       case 0x1008:
+               ttusb_dec_set_model(dec, TTUSB_DEC2000T);
+               break;
+
+       case 0x1009:
+               ttusb_dec_set_model(dec, TTUSB_DEC2540T);
+               break;
+       }
+
+       dec->udev = udev;
+
+       if (ttusb_dec_init_usb(dec))
+               return 0;
+       if (ttusb_dec_init_stb(dec)) {
+               ttusb_dec_exit_usb(dec);
+               return 0;
+       }
+       ttusb_dec_init_dvb(dec);
+
+       dec->adapter.priv = dec;
+       switch (id->idProduct) {
+       case 0x1006:
+               dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
+               break;
+
+       case 0x1008:
+       case 0x1009:
+               dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
+               break;
+       }
+
+       if (dec->fe == NULL) {
+               printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
+                      le16_to_cpu(dec->udev->descriptor.idVendor),
+                      le16_to_cpu(dec->udev->descriptor.idProduct));
+       } else {
+               if (dvb_register_frontend(&dec->adapter, dec->fe)) {
+                       printk("budget-ci: Frontend registration failed!\n");
+                       if (dec->fe->ops.release)
+                               dec->fe->ops.release(dec->fe);
+                       dec->fe = NULL;
+               }
+       }
+
+       ttusb_dec_init_v_pes(dec);
+       ttusb_dec_init_filters(dec);
+       ttusb_dec_init_tasklet(dec);
+
+       dec->active = 1;
+
+       ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
+
+       if (enable_rc)
+               ttusb_init_rc(dec);
+
+       return 0;
+}
+
+static void ttusb_dec_disconnect(struct usb_interface *intf)
+{
+       struct ttusb_dec *dec = usb_get_intfdata(intf);
+
+       usb_set_intfdata(intf, NULL);
+
+       dprintk("%s\n", __func__);
+
+       if (dec->active) {
+               ttusb_dec_exit_tasklet(dec);
+               ttusb_dec_exit_filters(dec);
+               if(enable_rc)
+                       ttusb_dec_exit_rc(dec);
+               ttusb_dec_exit_usb(dec);
+               ttusb_dec_exit_dvb(dec);
+       }
+
+       kfree(dec);
+}
+
+static void ttusb_dec_set_model(struct ttusb_dec *dec,
+                               enum ttusb_dec_model model)
+{
+       dec->model = model;
+
+       switch (model) {
+       case TTUSB_DEC2000T:
+               dec->model_name = "DEC2000-t";
+               dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
+               break;
+
+       case TTUSB_DEC2540T:
+               dec->model_name = "DEC2540-t";
+               dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
+               break;
+
+       case TTUSB_DEC3000S:
+               dec->model_name = "DEC3000-s";
+               dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
+               break;
+       }
+}
+
+static struct usb_device_id ttusb_dec_table[] = {
+       {USB_DEVICE(0x0b48, 0x1006)},   /* DEC3000-s */
+       /*{USB_DEVICE(0x0b48, 0x1007)},    Unconfirmed */
+       {USB_DEVICE(0x0b48, 0x1008)},   /* DEC2000-t */
+       {USB_DEVICE(0x0b48, 0x1009)},   /* DEC2540-t */
+       {}
+};
+
+static struct usb_driver ttusb_dec_driver = {
+       .name           = "ttusb-dec",
+       .probe          = ttusb_dec_probe,
+       .disconnect     = ttusb_dec_disconnect,
+       .id_table       = ttusb_dec_table,
+};
+
+module_usb_driver(ttusb_dec_driver);
+
+MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
+MODULE_DESCRIPTION(DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
new file mode 100644 (file)
index 0000000..5c45c9d
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * TTUSB DEC Frontend Driver
+ *
+ * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.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.
+ *
+ */
+
+#include "dvb_frontend.h"
+#include "ttusbdecfe.h"
+
+
+#define LOF_HI                 10600000
+#define LOF_LO                 9750000
+
+struct ttusbdecfe_state {
+
+       /* configuration settings */
+       const struct ttusbdecfe_config* config;
+
+       struct dvb_frontend frontend;
+
+       u8 hi_band;
+       u8 voltage;
+};
+
+
+static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
+       fe_status_t *status)
+{
+       *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
+               FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
+       return 0;
+}
+
+
+static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
+       fe_status_t *status)
+{
+       struct ttusbdecfe_state* state = fe->demodulator_priv;
+       u8 b[] = { 0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00 };
+       u8 result[4];
+       int len, ret;
+
+       *status=0;
+
+       ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
+       if(ret)
+               return ret;
+
+       if(len != 4) {
+               printk(KERN_ERR "%s: unexpected reply\n", __func__);
+               return -EIO;
+       }
+
+       switch(result[3]) {
+               case 1:  /* not tuned yet */
+               case 2:  /* no signal/no lock*/
+                       break;
+               case 3:  /* signal found and locked*/
+                       *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
+                       FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
+                       break;
+               case 4:
+                       *status = FE_TIMEDOUT;
+                       break;
+               default:
+                       pr_info("%s: returned unknown value: %d\n",
+                               __func__, result[3]);
+                       return -EIO;
+       }
+
+       return 0;
+}
+
+static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+       u8 b[] = { 0x00, 0x00, 0x00, 0x03,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x01,
+                  0x00, 0x00, 0x00, 0xff,
+                  0x00, 0x00, 0x00, 0xff };
+
+       __be32 freq = htonl(p->frequency / 1000);
+       memcpy(&b[4], &freq, sizeof (u32));
+       state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
+
+       return 0;
+}
+
+static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
+                                       struct dvb_frontend_tune_settings* fesettings)
+{
+               fesettings->min_delay_ms = 1500;
+               /* Drift compensation makes no sense for DVB-T */
+               fesettings->step_size = 0;
+               fesettings->max_drift = 0;
+               return 0;
+}
+
+static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+
+       u8 b[] = { 0x00, 0x00, 0x00, 0x01,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x01,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00 };
+       __be32 freq;
+       __be32 sym_rate;
+       __be32 band;
+       __be32 lnb_voltage;
+
+       freq = htonl(p->frequency +
+              (state->hi_band ? LOF_HI : LOF_LO));
+       memcpy(&b[4], &freq, sizeof(u32));
+       sym_rate = htonl(p->symbol_rate);
+       memcpy(&b[12], &sym_rate, sizeof(u32));
+       band = htonl(state->hi_band ? LOF_HI : LOF_LO);
+       memcpy(&b[24], &band, sizeof(u32));
+       lnb_voltage = htonl(state->voltage);
+       memcpy(&b[28], &lnb_voltage, sizeof(u32));
+
+       state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
+
+       return 0;
+}
+
+static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
+{
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+       u8 b[] = { 0x00, 0xff, 0x00, 0x00,
+                  0x00, 0x00, 0x00, 0x00,
+                  0x00, 0x00 };
+
+       memcpy(&b[4], cmd->msg, cmd->msg_len);
+
+       state->config->send_command(fe, 0x72,
+                                   sizeof(b) - (6 - cmd->msg_len), b,
+                                   NULL, NULL);
+
+       return 0;
+}
+
+
+static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+
+       state->hi_band = (SEC_TONE_ON == tone);
+
+       return 0;
+}
+
+
+static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               state->voltage = 13;
+               break;
+       case SEC_VOLTAGE_18:
+               state->voltage = 18;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void ttusbdecfe_release(struct dvb_frontend* fe)
+{
+       struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
+
+struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
+{
+       struct ttusbdecfe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       /* setup the state */
+       state->config = config;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
+
+struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
+{
+       struct ttusbdecfe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       /* setup the state */
+       state->config = config;
+       state->voltage = 0;
+       state->hi_band = 0;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
+               .frequency_min          = 51000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = ttusbdecfe_release,
+
+       .set_frontend = ttusbdecfe_dvbt_set_frontend,
+
+       .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
+
+       .read_status = ttusbdecfe_dvbt_read_status,
+};
+
+static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 125,
+               .symbol_rate_min        = 1000000,  /* guessed */
+               .symbol_rate_max        = 45000000, /* guessed */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK
+       },
+
+       .release = ttusbdecfe_release,
+
+       .set_frontend = ttusbdecfe_dvbs_set_frontend,
+
+       .read_status = ttusbdecfe_dvbs_read_status,
+
+       .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
+       .set_voltage = ttusbdecfe_dvbs_set_voltage,
+       .set_tone = ttusbdecfe_dvbs_set_tone,
+};
+
+MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
+MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
+EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.h b/drivers/media/usb/ttusb-dec/ttusbdecfe.h
new file mode 100644 (file)
index 0000000..15ccc3d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * TTUSB DEC Driver
+ *
+ * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.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.
+ *
+ */
+
+#ifndef TTUSBDECFE_H
+#define TTUSBDECFE_H
+
+#include <linux/dvb/frontend.h>
+
+struct ttusbdecfe_config
+{
+       int (*send_command)(struct dvb_frontend* fe, const u8 command,
+                           int param_length, const u8 params[],
+                           int *result_length, u8 cmd_result[]);
+};
+
+extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config);
+
+extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config);
+
+#endif // TTUSBDECFE_H
index 3ba13f9aaf7c17684cbab4290b46d9a1454b468f..9f2d4a9df3f2943cde77a8946b21c0ed9460356e 100644 (file)
@@ -12,4 +12,4 @@ ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/dvb/dvb-usb
+ccflags-y += -Idrivers/media/usb/dvb-usb
index f654ddcb2c6e39030610de915727997813ff5748..3fdbef5306a0a9bea05d30822fb6287b2c378117 100644 (file)
@@ -24,7 +24,7 @@ s2250-y := s2250-board.o
 #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
 
 # S2250 needs cypress ezusb loader from dvb-usb
-ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/dvb/dvb-usb
+ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
 
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/dvb-core